Skip to content

Commit 3692a1d

Browse files
committed
feat: Add controller and retry when the parameter initilization fails
1 parent 9835526 commit 3692a1d

File tree

2 files changed

+102
-22
lines changed

2 files changed

+102
-22
lines changed

include/dynamixel_hardware_interface/dynamixel_hardware_interface.hpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ class DynamixelHardware : public
235235
std::vector<uint8_t> sensor_id_;
236236
std::map<uint8_t /*id*/, std::string /*interface_name*/> sensor_item_;
237237

238+
std::vector<uint8_t> controller_id_;
239+
std::map<uint8_t /*id*/, std::string /*interface_name*/> controller_item_;
240+
238241
///// handler variable
239242
std::vector<HandlerVarType> hdl_trans_states_;
240243
std::vector<HandlerVarType> hdl_trans_commands_;
@@ -254,11 +257,33 @@ class DynamixelHardware : public
254257
double ** joint_to_transmission_matrix_;
255258

256259
/**
257-
* @brief Initializes the Dynamixel items.
260+
* @brief Helper function to initialize items for a specific type.
261+
* @param type_filter The type of items to initialize ("controller" or "dxl" or "sensor").
262+
* @return True if initialization was successful, false otherwise.
263+
*/
264+
bool initItems(const std::string& type_filter);
265+
266+
/**
267+
* @brief Helper function to retry writing an item to a Dynamixel device.
268+
* @param id The ID of the Dynamixel device.
269+
* @param item_name The name of the item to write.
270+
* @param value The value to write.
271+
* @return True if write was successful, false if timeout occurred.
272+
*/
273+
bool retryWriteItem(uint8_t id, const std::string& item_name, uint32_t value);
274+
275+
/**
276+
* @brief Initializes Dynamixel items.
258277
* @return True if initialization was successful, false otherwise.
259278
*/
260279
bool InitDxlItems();
261280

281+
/**
282+
* @brief Initializes the controller items.
283+
* @return True if initialization was successful, false otherwise.
284+
*/
285+
bool InitControllerItems();
286+
262287
/**
263288
* @brief Initializes the read items for Dynamixel.
264289
* @return True if initialization was successful, false otherwise.

src/dynamixel_hardware_interface.cpp

Lines changed: 76 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ hardware_interface::CallbackReturn DynamixelHardware::on_init(
105105
dxl_id_.push_back(static_cast<uint8_t>(stoi(gpio.parameters.at("ID"))));
106106
} else if (gpio.parameters.at("type") == "sensor") {
107107
sensor_id_.push_back(static_cast<uint8_t>(stoi(gpio.parameters.at("ID"))));
108+
} else if (gpio.parameters.at("type") == "controller") {
109+
controller_id_.push_back(static_cast<uint8_t>(stoi(gpio.parameters.at("ID"))));
108110
} else {
109111
RCLCPP_ERROR_STREAM(logger_, "Invalid DXL / Sensor type");
110112
exit(-1);
@@ -115,6 +117,35 @@ hardware_interface::CallbackReturn DynamixelHardware::on_init(
115117
int trying_cnt = 60;
116118
int cnt = 0;
117119

120+
if(controller_id_.size() > 0 ) {
121+
while (trying_connect) {
122+
std::vector<uint8_t> id_arr;
123+
for (auto controller : controller_id_) {
124+
id_arr.push_back(controller);
125+
}
126+
if (dxl_comm_->InitDxlComm(id_arr, port_name_, baud_rate_) == DxlError::OK) {
127+
RCLCPP_INFO_STREAM(logger_, "Trying to connect to the communication port...");
128+
trying_connect = false;
129+
} else {
130+
sleep(1);
131+
cnt++;
132+
if (cnt > trying_cnt) {
133+
RCLCPP_ERROR_STREAM(logger_, "Cannot connect communication port! :(");
134+
cnt = 0;
135+
}
136+
}
137+
}
138+
}
139+
140+
if (!InitControllerItems()) {
141+
RCLCPP_ERROR_STREAM(logger_, "Error: InitControllerItems");
142+
return hardware_interface::CallbackReturn::ERROR;
143+
}
144+
145+
trying_connect = true;
146+
trying_cnt = 60;
147+
cnt = 0;
148+
118149
while (trying_connect) {
119150
std::vector<uint8_t> id_arr;
120151
for (auto dxl : dxl_id_) {
@@ -566,6 +597,7 @@ bool DynamixelHardware::CommReset()
566597
usleep(200 * 1000);
567598
}
568599
if (!result) {continue;}
600+
if (!InitControllerItems()) {continue;}
569601
if (!InitDxlItems()) {continue;}
570602
if (!InitDxlReadItems()) {continue;}
571603
if (!InitDxlWriteItems()) {continue;}
@@ -582,48 +614,71 @@ bool DynamixelHardware::CommReset()
582614
return false;
583615
}
584616

585-
bool DynamixelHardware::InitDxlItems()
586-
{
587-
RCLCPP_INFO_STREAM(logger_, "$$$$$ Init Dxl Items");
617+
bool DynamixelHardware::retryWriteItem(uint8_t id, const std::string& item_name, uint32_t value) {
618+
rclcpp::Time start_time = this->now();
619+
rclcpp::Duration error_duration(0, 0);
620+
621+
while (true) {
622+
if (dxl_comm_->WriteItem(id, item_name, value) == DxlError::OK) {
623+
RCLCPP_INFO_STREAM(
624+
logger_,
625+
"[ID:" << std::to_string(id) << "] item_name:" << item_name.c_str() << "\tdata:" << value);
626+
return true;
627+
}
628+
629+
error_duration = this->now() - start_time;
630+
if (error_duration.seconds() * 1000 >= err_timeout_ms_) {
631+
RCLCPP_ERROR_STREAM(
632+
logger_,
633+
"[ID:" << std::to_string(id) << "] Write Item error (Timeout: " <<
634+
error_duration.seconds() * 1000 << "ms/" << err_timeout_ms_ << "ms)");
635+
return false;
636+
}
637+
RCLCPP_WARN_STREAM(
638+
logger_,
639+
"[ID:" << std::to_string(id) << "] Write Item retry...");
640+
}
641+
}
642+
643+
bool DynamixelHardware::initItems(const std::string& type_filter) {
644+
RCLCPP_INFO_STREAM(logger_, "$$$$$ Init Items for type: " << type_filter);
588645
for (const hardware_interface::ComponentInfo & gpio : info_.gpios) {
646+
if (gpio.parameters.at("type") != type_filter) {
647+
continue;
648+
}
589649
uint8_t id = static_cast<uint8_t>(stoi(gpio.parameters.at("ID")));
650+
590651
// First write items containing "Limit"
591652
for (auto it : gpio.parameters) {
592653
if (it.first != "ID" && it.first != "type" && it.first.find("Limit") != std::string::npos) {
593-
if (dxl_comm_->WriteItem(
594-
id, it.first,
595-
static_cast<uint32_t>(stoi(it.second))) != DxlError::OK)
596-
{
597-
RCLCPP_ERROR_STREAM(logger_, "[ID:" << std::to_string(id) << "] Write Item error");
654+
if (!retryWriteItem(id, it.first, static_cast<uint32_t>(stoi(it.second)))) {
598655
return false;
599656
}
600-
RCLCPP_INFO_STREAM(
601-
logger_,
602-
"[ID:" << std::to_string(id) << "] item_name:" << it.first.c_str() << "\tdata:" <<
603-
stoi(it.second));
604657
}
605658
}
606659

607660
// Then write the remaining items
608661
for (auto it : gpio.parameters) {
609662
if (it.first != "ID" && it.first != "type" && it.first.find("Limit") == std::string::npos) {
610-
if (dxl_comm_->WriteItem(
611-
id, it.first,
612-
static_cast<uint32_t>(stoi(it.second))) != DxlError::OK)
613-
{
614-
RCLCPP_ERROR_STREAM(logger_, "[ID:" << std::to_string(id) << "] Write Item error");
663+
if (!retryWriteItem(id, it.first, static_cast<uint32_t>(stoi(it.second)))) {
615664
return false;
616665
}
617-
RCLCPP_INFO_STREAM(
618-
logger_,
619-
"[ID:" << std::to_string(id) << "] item_name:" << it.first.c_str() << "\tdata:" <<
620-
stoi(it.second));
621666
}
622667
}
623668
}
624669
return true;
625670
}
626671

672+
bool DynamixelHardware::InitControllerItems()
673+
{
674+
return initItems("controller");
675+
}
676+
677+
bool DynamixelHardware::InitDxlItems()
678+
{
679+
return initItems("dxl") && initItems("sensor");
680+
}
681+
627682
bool DynamixelHardware::InitDxlReadItems()
628683
{
629684
RCLCPP_INFO_STREAM(logger_, "$$$$$ Init Dxl Read Items");

0 commit comments

Comments
 (0)