Skip to content

Commit 806e06a

Browse files
committed
Enhance Dynamixel hardware interface by adding unordered maps for command name conversions and refactoring state synchronization logic. Removed redundant definitions and improved handling of joint commands and states. Updated model files to reflect changes in command interfaces.
1 parent 389c3c2 commit 806e06a

File tree

4 files changed

+120
-111
lines changed

4 files changed

+120
-111
lines changed

include/dynamixel_hardware_interface/dynamixel_hardware_interface.hpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <string>
2222
#include <vector>
2323
#include <map>
24+
#include <unordered_map>
2425

2526
#include "rclcpp/rclcpp.hpp"
2627
#include "ament_index_cpp/get_package_share_directory.hpp"
@@ -47,10 +48,6 @@
4748
#define PRESENT_VELOCITY_INDEX 1
4849
#define PRESENT_EFFORT_INDEX 2
4950

50-
#define GOAL_POSITION_INDEX 0
51-
// #define GOAL_VELOCITY_INDEX 1 // TODO: to be implemented
52-
#define GOAL_CURRENT_INDEX 1
53-
5451
namespace dynamixel_hardware_interface
5552
{
5653

@@ -361,6 +358,18 @@ class DynamixelHardware : public
361358
double prismaticToRevolute(double prismatic_value);
362359
};
363360

361+
// Conversion maps between ROS2 and Dynamixel interface names
362+
inline const std::unordered_map<std::string, std::string> ros2_to_dxl_cmd_map = {
363+
{hardware_interface::HW_IF_POSITION, "Goal Position"},
364+
{hardware_interface::HW_IF_VELOCITY, "Goal Velocity"},
365+
{hardware_interface::HW_IF_EFFORT, "Goal Current"}
366+
};
367+
inline const std::unordered_map<std::string, std::string> dxl_to_ros2_cmd_map = {
368+
{"Goal Position", hardware_interface::HW_IF_POSITION},
369+
{"Goal Velocity", hardware_interface::HW_IF_VELOCITY},
370+
{"Goal Current", hardware_interface::HW_IF_EFFORT}
371+
};
372+
364373
} // namespace dynamixel_hardware_interface
365374

366375
#endif // DYNAMIXEL_HARDWARE_INTERFACE__DYNAMIXEL_HARDWARE_INTERFACE_HPP_

param/dxl_model/xl430_w250.model

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ Address Size Data Name
4343
98 1 Bus Watchdog
4444
100 2 Goal PWM
4545
104 4 Goal Velocity
46-
104 2 Goal Current
4746
108 4 Profile Acceleration
4847
112 4 Profile Velocity
4948
116 4 Goal Position
@@ -53,7 +52,6 @@ Address Size Data Name
5352
124 2 Present PWM
5453
126 2 Present Load
5554
128 4 Present Velocity
56-
128 2 Present Current
5755
132 4 Present Position
5856
136 4 Velocity Trajectory
5957
140 4 Position Trajectory

src/dynamixel/dynamixel.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,12 @@ DxlError Dynamixel::SetMultiDxlWrite()
269269
}
270270
fprintf(stderr, "\n");
271271
fprintf(stderr, "Write items : ");
272-
273-
for (auto it_name : write_data_list_.at(0).item_name) {
274-
fprintf(stderr, "\t%s", it_name.c_str());
272+
if (!write_data_list_.empty()) {
273+
for (auto it_name : write_data_list_.at(0).item_name) {
274+
fprintf(stderr, "\t%s", it_name.c_str());
275+
}
276+
} else {
277+
fprintf(stderr, "(none)");
275278
}
276279
fprintf(stderr, "\n");
277280
} else {
@@ -1179,16 +1182,16 @@ DxlError Dynamixel::SetDxlValueToSyncWrite()
11791182
param_write_value[added_byte + 1] = DXL_HIBYTE(DXL_LOWORD(goal_position));
11801183
param_write_value[added_byte + 2] = DXL_LOBYTE(DXL_HIWORD(goal_position));
11811184
param_write_value[added_byte + 3] = DXL_HIBYTE(DXL_HIWORD(goal_position));
1182-
} else if (indirect_info_write_[ID].item_name.at(item_index) == "Goal Current") {
1183-
int16_t goal_current = dxl_info_.ConvertEffortToCurrent(ID, data);
1184-
param_write_value[added_byte + 0] = DXL_LOBYTE(goal_current);
1185-
param_write_value[added_byte + 1] = DXL_HIBYTE(goal_current);
11861185
} else if (indirect_info_write_[ID].item_name.at(item_index) == "Goal Velocity") {
11871186
int16_t goal_velocity = dxl_info_.ConvertVelocityRPSToValueRPM(data);
11881187
param_write_value[added_byte + 0] = DXL_LOBYTE(DXL_LOWORD(goal_velocity));
11891188
param_write_value[added_byte + 1] = DXL_HIBYTE(DXL_LOWORD(goal_velocity));
11901189
param_write_value[added_byte + 2] = DXL_LOBYTE(DXL_HIWORD(goal_velocity));
11911190
param_write_value[added_byte + 3] = DXL_HIBYTE(DXL_HIWORD(goal_velocity));
1191+
} else if (indirect_info_write_[ID].item_name.at(item_index) == "Goal Current") {
1192+
int16_t goal_current = dxl_info_.ConvertEffortToCurrent(ID, data);
1193+
param_write_value[added_byte + 0] = DXL_LOBYTE(goal_current);
1194+
param_write_value[added_byte + 1] = DXL_HIBYTE(goal_current);
11921195
}
11931196
added_byte += indirect_info_write_[ID].item_size.at(item_index);
11941197
}
@@ -1294,16 +1297,16 @@ DxlError Dynamixel::SetDxlValueToBulkWrite()
12941297
param_write_value[added_byte + 1] = DXL_HIBYTE(DXL_LOWORD(goal_position));
12951298
param_write_value[added_byte + 2] = DXL_LOBYTE(DXL_HIWORD(goal_position));
12961299
param_write_value[added_byte + 3] = DXL_HIBYTE(DXL_HIWORD(goal_position));
1297-
} else if (indirect_info_write_[ID].item_name.at(item_index) == "Goal Current") {
1298-
int16_t goal_current = dxl_info_.ConvertEffortToCurrent(ID, data);
1299-
param_write_value[added_byte + 0] = DXL_LOBYTE(goal_current);
1300-
param_write_value[added_byte + 1] = DXL_HIBYTE(goal_current);
13011300
} else if (indirect_info_write_[ID].item_name.at(item_index) == "Goal Velocity") {
13021301
int32_t goal_velocity = dxl_info_.ConvertVelocityRPSToValueRPM(data);
13031302
param_write_value[added_byte + 0] = DXL_LOBYTE(DXL_LOWORD(goal_velocity));
13041303
param_write_value[added_byte + 1] = DXL_HIBYTE(DXL_LOWORD(goal_velocity));
13051304
param_write_value[added_byte + 2] = DXL_LOBYTE(DXL_HIWORD(goal_velocity));
13061305
param_write_value[added_byte + 3] = DXL_HIBYTE(DXL_HIWORD(goal_velocity));
1306+
} else if (indirect_info_write_[ID].item_name.at(item_index) == "Goal Current") {
1307+
int16_t goal_current = dxl_info_.ConvertEffortToCurrent(ID, data);
1308+
param_write_value[added_byte + 0] = DXL_LOBYTE(goal_current);
1309+
param_write_value[added_byte + 1] = DXL_HIBYTE(goal_current);
13071310
}
13081311
added_byte += indirect_info_write_[ID].item_size.at(item_index);
13091312
}

src/dynamixel_hardware_interface.cpp

Lines changed: 93 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <vector>
2424
#include <string>
2525
#include <map>
26+
#include <unordered_map>
2627

2728
#include "hardware_interface/types/hardware_interface_type_values.hpp"
2829
#include "rclcpp/rclcpp.hpp"
@@ -435,23 +436,7 @@ hardware_interface::CallbackReturn DynamixelHardware::start()
435436
CalcTransmissionToJoint();
436437

437438
// sync commands = states joint
438-
for (auto it_states : hdl_joint_states_) {
439-
for (auto it_commands : hdl_joint_commands_) {
440-
if (it_states.name == it_commands.name) {
441-
for (size_t i = 0; i < it_states.interface_name_vec.size(); i++) {
442-
if (it_commands.interface_name_vec.at(0) == it_states.interface_name_vec.at(i)) {
443-
*it_commands.value_ptr_vec.at(0) = *it_states.value_ptr_vec.at(i);
444-
RCLCPP_INFO_STREAM(
445-
logger_, "Sync joint state to command (" <<
446-
it_commands.interface_name_vec.at(0).c_str() << ", " <<
447-
*it_commands.value_ptr_vec.at(0) * 180.0 / 3.141592 << " <- " <<
448-
it_states.interface_name_vec.at(i).c_str() << ", " <<
449-
*it_states.value_ptr_vec.at(i) * 180.0 / 3.141592);
450-
}
451-
}
452-
}
453-
}
454-
}
439+
SyncJointCommandWithStates();
455440
usleep(500 * 1000);
456441

457442
// Enable torque only for Dynamixels that have torque enabled in their parameters
@@ -846,24 +831,26 @@ bool DynamixelHardware::InitDxlWriteItems()
846831
if (!is_set_hdl_) {
847832
hdl_trans_commands_.clear();
848833
for (const hardware_interface::ComponentInfo & gpio : info_.gpios) {
849-
if (gpio.command_interfaces.size()) {
850-
uint8_t id = static_cast<uint8_t>(stoi(gpio.parameters.at("ID")));
851-
HandlerVarType temp_write;
852-
temp_write.id = id;
853-
temp_write.name = gpio.name;
854-
855-
temp_write.interface_name_vec.push_back("Goal Position");
856-
temp_write.value_ptr_vec.push_back(std::make_shared<double>(0.0));
857-
858-
for (auto it : gpio.command_interfaces) {
859-
if (it.name == "Goal Current") {
860-
temp_write.interface_name_vec.push_back("Goal Current");
861-
temp_write.value_ptr_vec.push_back(std::make_shared<double>(0.0));
862-
}
834+
if(gpio.parameters.at("type") != "dxl") {
835+
continue;
836+
}
837+
uint8_t id = static_cast<uint8_t>(stoi(gpio.parameters.at("ID")));
838+
HandlerVarType temp_write;
839+
temp_write.id = id;
840+
temp_write.name = gpio.name;
841+
842+
for (auto it : gpio.command_interfaces) {
843+
if (it.name != "Goal Position" &&
844+
it.name != "Goal Velocity" &&
845+
it.name != "Goal Current")
846+
{
847+
continue;
863848
}
864-
865-
hdl_trans_commands_.push_back(temp_write);
849+
temp_write.interface_name_vec.push_back(it.name);
850+
temp_write.value_ptr_vec.push_back(std::make_shared<double>(0.0));
866851
}
852+
853+
hdl_trans_commands_.push_back(temp_write);
867854
}
868855
is_set_hdl_ = true;
869856
}
@@ -958,90 +945,102 @@ void DynamixelHardware::SetMatrix()
958945
}
959946
void DynamixelHardware::CalcTransmissionToJoint()
960947
{
948+
// Define the indices and their corresponding state types
949+
const std::array<size_t, 3> indices = {
950+
PRESENT_POSITION_INDEX,
951+
PRESENT_VELOCITY_INDEX,
952+
PRESENT_EFFORT_INDEX
953+
};
954+
955+
// Process each joint
961956
for (size_t i = 0; i < num_of_joints_; i++) {
962-
double value = 0.0;
963-
for (size_t j = 0; j < num_of_transmissions_; j++) {
964-
value += transmission_to_joint_matrix_[i][j] *
965-
(*hdl_trans_states_.at(j).value_ptr_vec.at(PRESENT_POSITION_INDEX));
966-
}
967-
968-
if (hdl_joint_states_.at(i).name == conversion_joint_name_) {
969-
value = revoluteToPrismatic(value);
970-
}
971-
*hdl_joint_states_.at(i).value_ptr_vec.at(PRESENT_POSITION_INDEX) = value;
972-
}
957+
// Process each state type (position, velocity, effort)
958+
for (size_t state_idx : indices) {
959+
double value = 0.0;
960+
// Calculate value using transmission matrix
961+
for (size_t j = 0; j < num_of_transmissions_; j++) {
962+
value += transmission_to_joint_matrix_[i][j] *
963+
(*hdl_trans_states_.at(j).value_ptr_vec.at(state_idx));
964+
}
973965

974-
for (size_t i = 0; i < num_of_joints_; i++) {
975-
double value = 0.0;
976-
for (size_t j = 0; j < num_of_transmissions_; j++) {
977-
value += transmission_to_joint_matrix_[i][j] *
978-
(*hdl_trans_states_.at(j).value_ptr_vec.at(PRESENT_VELOCITY_INDEX));
979-
}
980-
*hdl_joint_states_.at(i).value_ptr_vec.at(PRESENT_VELOCITY_INDEX) = value;
981-
}
966+
// Apply conversion if needed (only for position)
967+
if (state_idx == PRESENT_POSITION_INDEX &&
968+
hdl_joint_states_.at(i).name == conversion_joint_name_) {
969+
value = revoluteToPrismatic(value);
970+
}
982971

983-
for (size_t i = 0; i < num_of_joints_; i++) {
984-
double value = 0.0;
985-
for (size_t j = 0; j < num_of_transmissions_; j++) {
986-
value += transmission_to_joint_matrix_[i][j] *
987-
(*hdl_trans_states_.at(j).value_ptr_vec.at(PRESENT_EFFORT_INDEX));
972+
// Store the calculated value
973+
*hdl_joint_states_.at(i).value_ptr_vec.at(state_idx) = value;
988974
}
989-
*hdl_joint_states_.at(i).value_ptr_vec.at(PRESENT_EFFORT_INDEX) = value;
990975
}
991976
}
992977

993978
void DynamixelHardware::CalcJointToTransmission()
994979
{
995980
for (size_t i = 0; i < num_of_transmissions_; i++) {
996981
double value = 0.0;
982+
bool temp_flag = false;
997983
for (size_t j = 0; j < num_of_joints_; j++) {
998-
value += joint_to_transmission_matrix_[i][j] *
999-
(*hdl_joint_commands_.at(j).value_ptr_vec.at(GOAL_POSITION_INDEX));
1000-
}
1001-
1002-
if (hdl_trans_commands_.at(i).name == conversion_dxl_name_) {
1003-
value = prismaticToRevolute(value);
1004-
}
1005-
*hdl_trans_commands_.at(i).value_ptr_vec.at(GOAL_POSITION_INDEX) = value;
1006-
}
1007-
1008-
for (size_t i = 0; i < num_of_transmissions_; i++) {
1009-
if (hdl_trans_commands_.at(i).interface_name_vec.size() > GOAL_CURRENT_INDEX &&
1010-
hdl_trans_commands_.at(i).interface_name_vec.at(GOAL_CURRENT_INDEX) == "Goal Current")
1011-
{
1012-
for (size_t j = 0; j < hdl_joint_commands_.size(); j++) {
1013-
if (hdl_joint_commands_.at(j).interface_name_vec.size() > GOAL_CURRENT_INDEX &&
1014-
hdl_joint_commands_.at(j).interface_name_vec.at(GOAL_CURRENT_INDEX) ==
1015-
hardware_interface::HW_IF_EFFORT)
1016-
{
1017-
double value = 0.0;
1018-
for (size_t k = 0; k < num_of_joints_; k++) {
1019-
value += joint_to_transmission_matrix_[i][k] *
1020-
(*hdl_joint_commands_.at(k).value_ptr_vec.at(GOAL_CURRENT_INDEX));
984+
for(size_t k = 0; k < hdl_joint_commands_.at(j).interface_name_vec.size(); k++) {
985+
value += joint_to_transmission_matrix_[i][j] *
986+
(*hdl_joint_commands_.at(j).value_ptr_vec.at(k));
987+
if(hdl_joint_commands_.at(j).name == "l_rh_r1_joint") {
988+
if(joint_to_transmission_matrix_[i][j] == 1.0) {
989+
temp_flag = true;
1021990
}
1022-
*hdl_trans_commands_.at(i).value_ptr_vec.at(GOAL_CURRENT_INDEX) = value;
1023991
}
1024992
}
1025993
}
994+
995+
for(size_t k = 0; k < hdl_trans_commands_.at(i).interface_name_vec.size(); k++) {
996+
if (hdl_trans_commands_.at(i).interface_name_vec.at(k) == "Goal Position" &&
997+
hdl_trans_commands_.at(i).name == conversion_dxl_name_) {
998+
value = prismaticToRevolute(value);
999+
}
1000+
if(hdl_trans_commands_.at(i).name == "dxl38") {
1001+
RCLCPP_INFO_STREAM(logger_, "hdl_trans_commands_.at(i).name: " << hdl_trans_commands_.at(i).name << ", cmd_idx: " << k << ", value: " << value);
1002+
}
1003+
*hdl_trans_commands_.at(i).value_ptr_vec.at(k) = value;
1004+
}
10261005
}
10271006
}
10281007

1008+
10291009
void DynamixelHardware::SyncJointCommandWithStates()
10301010
{
1031-
for (auto it_states : hdl_joint_states_) {
1032-
for (auto it_commands : hdl_joint_commands_) {
1011+
for (auto& it_states : hdl_joint_states_) {
1012+
for (auto& it_commands : hdl_joint_commands_) {
10331013
if (it_states.name == it_commands.name) {
1034-
for (size_t i = 0; i < it_states.interface_name_vec.size(); i++) {
1035-
if (it_commands.interface_name_vec.at(0) == it_states.interface_name_vec.at(i)) {
1036-
*it_commands.value_ptr_vec.at(0) = *it_states.value_ptr_vec.at(i);
1037-
RCLCPP_INFO_STREAM(
1038-
logger_, "Sync joint state to command (" <<
1039-
it_commands.interface_name_vec.at(0).c_str() << ", " <<
1040-
*it_commands.value_ptr_vec.at(0) << " <- " <<
1041-
it_states.interface_name_vec.at(i).c_str() << ", " <<
1042-
*it_states.value_ptr_vec.at(i));
1043-
}
1014+
std::string pos_cmd_name = hardware_interface::HW_IF_POSITION;
1015+
std::string pos_dxl_name = ros2_to_dxl_cmd_map.count(pos_cmd_name) ? ros2_to_dxl_cmd_map.at(pos_cmd_name) : pos_cmd_name;
1016+
// Find index in command interfaces
1017+
auto cmd_it = std::find(
1018+
it_commands.interface_name_vec.begin(),
1019+
it_commands.interface_name_vec.end(),
1020+
pos_cmd_name);
1021+
if (cmd_it == it_commands.interface_name_vec.end()) {
1022+
RCLCPP_WARN_STREAM(logger_, "No position interface found in command interfaces for joint '" << it_commands.name << "'. Skipping sync!");
1023+
continue;
1024+
}
1025+
size_t cmd_idx = std::distance(it_commands.interface_name_vec.begin(), cmd_it);
1026+
// Find index in state interfaces
1027+
auto state_it = std::find(
1028+
it_states.interface_name_vec.begin(),
1029+
it_states.interface_name_vec.end(),
1030+
pos_cmd_name);
1031+
if (state_it == it_states.interface_name_vec.end()) {
1032+
RCLCPP_WARN_STREAM(logger_, "No position interface found in state interfaces for joint '" << it_states.name << "'. Skipping sync!");
1033+
continue;
10441034
}
1035+
size_t state_idx = std::distance(it_states.interface_name_vec.begin(), state_it);
1036+
// Sync the value
1037+
*it_commands.value_ptr_vec.at(cmd_idx) = *it_states.value_ptr_vec.at(state_idx);
1038+
RCLCPP_INFO_STREAM(
1039+
logger_, "Sync joint state to command (joint: " << it_states.name << ", " <<
1040+
it_commands.interface_name_vec.at(cmd_idx).c_str() << ", " <<
1041+
*it_commands.value_ptr_vec.at(cmd_idx) << " <- " <<
1042+
it_states.interface_name_vec.at(state_idx).c_str() << ", " <<
1043+
*it_states.value_ptr_vec.at(state_idx));
10451044
}
10461045
}
10471046
}

0 commit comments

Comments
 (0)