Skip to content

Commit cc338de

Browse files
authored
Merge pull request #65 from ROBOTIS-GIT/feature-dy-error-code
Added Dynamixel Y error code handling logic
2 parents 02841dd + ccb8c01 commit cc338de

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1068
-378
lines changed

CHANGELOG.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
Changelog for package dynamixel_hardware_interface
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44

5+
1.4.10 (2025-07-18)
6+
------------------
7+
* Added unit system to model files
8+
* Added support for Dynamixel Y Error Code handling
9+
* Contributors: Woojin Wie
10+
511
1.4.9 (2025-06-24)
612
------------------
713
* Support ffw sensor model

CMakeLists.txt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,8 @@ add_library(
3939

4040
target_include_directories(
4141
${PROJECT_NAME}
42-
PRIVATE
43-
include
44-
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
42+
PUBLIC
43+
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
4544
$<INSTALL_INTERFACE:include>
4645
${dynamixel_sdk_INCLUDE_DIRS}
4746
${hardware_interface_INCLUDE_DIRS}
@@ -67,7 +66,10 @@ pluginlib_export_plugin_description_file(hardware_interface dynamixel_hardware_i
6766
# Install
6867
################################################################################
6968
install(TARGETS ${PROJECT_NAME}
70-
DESTINATION lib
69+
EXPORT export_${PROJECT_NAME}
70+
ARCHIVE DESTINATION lib
71+
LIBRARY DESTINATION lib
72+
RUNTIME DESTINATION bin
7173
)
7274

7375
install(DIRECTORY include/
@@ -98,6 +100,7 @@ endif()
98100
################################################################################
99101
ament_export_include_directories(include)
100102
ament_export_libraries(${PROJECT_NAME})
103+
ament_export_targets(export_${PROJECT_NAME} HAS_LIBRARY_TARGET)
101104
ament_export_dependencies(
102105
rclcpp
103106
rclcpp_lifecycle

include/dynamixel_hardware_interface/dynamixel/dynamixel.hpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ enum DxlError
6767
SET_BULK_READ_FAIL = -13, ///< Failed to configure bulk read.
6868
SET_READ_ITEM_FAIL = -14, ///< Failed to set read item.
6969
SET_WRITE_ITEM_FAIL = -15, ///< Failed to set write item.
70-
DLX_HARDWARE_ERROR = -16, ///< Hardware error detected.
70+
DXL_HARDWARE_ERROR = -16, ///< Hardware error detected.
7171
DXL_REBOOT_FAIL = -17 ///< Reboot failed.
7272
};
7373

@@ -260,6 +260,7 @@ class Dynamixel
260260
DxlError ProcessDirectReadData(
261261
uint8_t id,
262262
const std::vector<uint16_t> & item_addrs,
263+
const std::vector<std::string> & item_names,
263264
const std::vector<uint8_t> & item_sizes,
264265
const std::vector<std::shared_ptr<double>> & data_ptrs,
265266
std::function<uint32_t(uint8_t, uint16_t, uint8_t)> get_data_func);
@@ -292,6 +293,25 @@ class Dynamixel
292293
std::string item_name,
293294
uint16_t item_addr,
294295
uint8_t item_size);
296+
297+
// Helper function for value conversion with unit info
298+
double ConvertValueWithUnitInfo(
299+
uint8_t id,
300+
std::string item_name,
301+
uint32_t raw_value,
302+
uint8_t size,
303+
bool is_signed);
304+
305+
// Helper function for converting unit values to raw values
306+
uint32_t ConvertUnitValueToRawValue(
307+
uint8_t id,
308+
std::string item_name,
309+
double unit_value,
310+
uint8_t size,
311+
bool is_signed);
312+
313+
// Helper function for writing values to buffer
314+
void WriteValueToBuffer(uint8_t * buffer, uint8_t offset, uint32_t value, uint8_t size);
295315
};
296316

297317
} // namespace dynamixel_hardware_interface

include/dynamixel_hardware_interface/dynamixel/dynamixel_info.hpp

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,16 @@ typedef struct
4040

4141
typedef struct
4242
{
43-
double torque_constant;
4443
double min_radian;
4544
double max_radian;
4645
int32_t value_of_zero_radian_position;
4746
int32_t value_of_max_radian_position;
4847
int32_t value_of_min_radian_position;
4948
uint16_t model_num;
50-
double velocity_unit;
5149

5250
std::vector<ControlItem> item;
51+
std::map<std::string, double> unit_map;
52+
std::map<std::string, bool> sign_type_map;
5353
} DxlInfo;
5454

5555
class DynamixelInfo
@@ -73,27 +73,45 @@ class DynamixelInfo
7373
void ReadDxlModelFile(uint8_t id, uint16_t model_num);
7474
bool GetDxlControlItem(uint8_t id, std::string item_name, uint16_t & addr, uint8_t & size);
7575
bool CheckDxlControlItem(uint8_t id, std::string item_name);
76-
// bool GetDxlTypeInfo(
77-
// uint8_t id,
78-
// int32_t & value_of_zero_radian_position,
79-
// int32_t & value_of_max_radian_position,
80-
// int32_t & value_of_min_radian_position,
81-
// double & min_radian,
82-
// double & max_radian,
83-
// double & torque_constant,
84-
// double & velocity_unit);
76+
77+
bool GetDxlUnitValue(uint8_t id, std::string data_name, double & unit_value);
78+
bool GetDxlSignType(uint8_t id, std::string data_name, bool & is_signed);
79+
80+
// Template-based conversion methods
81+
template<typename T>
82+
double ConvertValueToUnit(uint8_t id, std::string data_name, T value);
83+
84+
template<typename T>
85+
T ConvertUnitToValue(uint8_t id, std::string data_name, double unit_value);
86+
87+
// Helper method for internal use
88+
double GetUnitMultiplier(uint8_t id, std::string data_name);
89+
8590
int32_t ConvertRadianToValue(uint8_t id, double radian);
8691
double ConvertValueToRadian(uint8_t id, int32_t value);
87-
inline int16_t ConvertEffortToCurrent(uint8_t id, double effort)
88-
{return static_cast<int16_t>(effort / dxl_info_[id].torque_constant);}
89-
inline double ConvertCurrentToEffort(uint8_t id, int16_t current)
90-
{return static_cast<double>(current * dxl_info_[id].torque_constant);}
91-
inline double ConvertValueRPMToVelocityRPS(uint8_t id, int32_t value_rpm)
92-
{return static_cast<double>(value_rpm * dxl_info_[id].velocity_unit / 60.0 * 2.0 * M_PI);}
93-
inline int32_t ConvertVelocityRPSToValueRPM(uint8_t id, double vel_rps)
94-
{return static_cast<int32_t>(vel_rps / dxl_info_[id].velocity_unit * 60.0 / 2.0 / M_PI);}
9592
};
9693

94+
// Template implementations
95+
template<typename T>
96+
double DynamixelInfo::ConvertValueToUnit(uint8_t id, std::string data_name, T value)
97+
{
98+
auto it = dxl_info_[id].unit_map.find(data_name);
99+
if (it != dxl_info_[id].unit_map.end()) {
100+
return static_cast<double>(value) * it->second;
101+
}
102+
return static_cast<double>(value);
103+
}
104+
105+
template<typename T>
106+
T DynamixelInfo::ConvertUnitToValue(uint8_t id, std::string data_name, double unit_value)
107+
{
108+
auto it = dxl_info_[id].unit_map.find(data_name);
109+
if (it != dxl_info_[id].unit_map.end()) {
110+
return static_cast<T>(unit_value / it->second);
111+
}
112+
return static_cast<T>(unit_value);
113+
}
114+
97115
} // namespace dynamixel_hardware_interface
98116

99117
#endif // DYNAMIXEL_HARDWARE_INTERFACE__DYNAMIXEL__DYNAMIXEL_INFO_HPP_

include/dynamixel_hardware_interface/dynamixel_hardware_interface.hpp

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,80 @@
5050
namespace dynamixel_hardware_interface
5151
{
5252

53+
// Hardware Error Status bit definitions
54+
struct HardwareErrorStatusBitInfo
55+
{
56+
int bit;
57+
const char * label;
58+
const char * description;
59+
};
60+
61+
static constexpr HardwareErrorStatusBitInfo HardwareErrorStatusTable[] = {
62+
{0, "Input Voltage Error", "Detects that input voltage exceeds the configured operating voltage"},
63+
{1, "Motor Hall Sensor Error", "Detects that Motor hall sensor value exceeds normal range"},
64+
{2, "Overheating Error",
65+
"Detects that internal temperature exceeds the configured operating temperature"},
66+
{3, "Motor Encoder Error", "Detects malfunction of the motor encoder"},
67+
{4,
68+
"Electrical Shock Error",
69+
"Detects electric shock on the circuit or insufficient power to operate the motor"},
70+
{5, "Overload Error", "Detects that persistent load exceeds maximum output"},
71+
{6, "Not used", "Always 0"},
72+
{7, "Not used", "Always 0"}
73+
};
74+
75+
inline const HardwareErrorStatusBitInfo * get_hardware_error_status_bit_info(int bit)
76+
{
77+
for (const auto & entry : HardwareErrorStatusTable) {
78+
if (entry.bit == bit) {return &entry;}
79+
}
80+
return nullptr;
81+
}
82+
83+
// Error Code (153) definitions
84+
struct ErrorCodeInfo
85+
{
86+
int value;
87+
const char * label;
88+
const char * description;
89+
};
90+
91+
static constexpr ErrorCodeInfo ErrorCodeTable[] = {
92+
{0x00, "No Error", "No error"},
93+
{0x01, "Over Voltage Error", "Device supply voltage exceeds the Max Voltage Limit(60)"},
94+
{0x02, "Low Voltage Error", "Device supply voltage exceeds the Min Voltage Limit(62)"},
95+
{0x03,
96+
"Inverter Overheating Error",
97+
"The inverter temperature has exceeded the Inverter Temperature Limit(56)"},
98+
{0x04,
99+
"Motor Overheating Error",
100+
"The motor temperature has exceeded the Motor Temperature Limit(57)"},
101+
{0x05, "Overload Error", "Operating current exceeding rated current for an extended duration"},
102+
{0x07, "Inverter Error", "An issue has occurred with the inverter"},
103+
{0x09, "Battery Warning", "Low Multi-turn battery voltage. Replacement recommended"},
104+
{0x0A, "Battery Error", "Multi-turn battery voltage is too low, causing issues"},
105+
{0x0B, "Magnet Error", "Multi-turn position lost. Multi-turn reset required"},
106+
{0x0C, "Multi-turn Error", "An issue has occurred with the Multi-turn IC"},
107+
{0x0D, "Encoder Error", "An issue has occurred with the Encoder IC"},
108+
{0x0E, "Hall Sensor Error", "An issue has occurred with the Hall Sensor"},
109+
{0x0F, "Calibration Error", "Cannot find calibration Data"},
110+
{0x11, "Following Error", "Position control error exceeds the Following Error Threshold(44)"},
111+
{0x12, "Bus Watchdog Error", "An issue has occurred with the Bus Watchdog"},
112+
{0x13, "Over Speed Error", "Rotates at a speed of 120% or more than the Velocity Limit(72)"},
113+
{0x14,
114+
"Position Limit Reached Error",
115+
"In position control mode, the current position has moved beyond the Max/Min Position Limit"
116+
" + Position Limit Threshold(38) range."}
117+
};
118+
119+
inline const ErrorCodeInfo * get_error_code_info(int value)
120+
{
121+
for (const auto & entry : ErrorCodeTable) {
122+
if (entry.value == value) {return &entry;}
123+
}
124+
return nullptr;
125+
}
126+
53127
/**
54128
* @brief Constants for hardware state interface names.
55129
*/
@@ -175,14 +249,16 @@ class DynamixelHardware : public
175249
private:
176250
///// ros
177251
rclcpp::Logger logger_;
252+
rclcpp::Clock clock_;
178253

179254
///// dxl error
180255
DxlStatus dxl_status_;
181256
DxlError dxl_comm_err_;
182257
std::map<uint8_t /*id*/, uint8_t /*err*/> dxl_hw_err_;
258+
std::map<uint8_t /*id*/, uint8_t /*error code*/> dxl_error_code_;
183259
DxlTorqueStatus dxl_torque_status_;
184260
std::map<uint8_t /*id*/, bool /*enable*/> dxl_torque_state_;
185-
std::map<uint8_t /*id*/, bool /*enable*/> dxl_torque_enable_;
261+
std::vector<uint8_t> torque_enabled_ids_;
186262
double err_timeout_ms_;
187263
rclcpp::Duration read_error_duration_{0, 0};
188264
rclcpp::Duration write_error_duration_{0, 0};
@@ -298,8 +374,9 @@ class DynamixelHardware : public
298374
///// function
299375
/**
300376
* @brief Sets up the joint-to-transmission and transmission-to-joint matrices.
377+
* @return True if matrices were set up successfully, false otherwise.
301378
*/
302-
void SetMatrix();
379+
bool SetMatrix();
303380

304381
/**
305382
* @brief Calculates the joint states from transmission states.
@@ -346,12 +423,30 @@ class DynamixelHardware : public
346423
const std::shared_ptr<std_srvs::srv::SetBool::Request> request,
347424
std::shared_ptr<std_srvs::srv::SetBool::Response> response);
348425

426+
rclcpp::Service<dynamixel_interfaces::srv::GetDataFromDxl>::SharedPtr get_dxl_error_summary_srv_;
427+
void get_dxl_error_summary_srv_callback(
428+
const std::shared_ptr<dynamixel_interfaces::srv::GetDataFromDxl::Request> request,
429+
std::shared_ptr<dynamixel_interfaces::srv::GetDataFromDxl::Response> response);
430+
349431
void initRevoluteToPrismaticParam();
350432

351433
double revoluteToPrismatic(double revolute_value);
352434

353435
double prismaticToRevolute(double prismatic_value);
354436

437+
/**
438+
* @brief Get a formatted error summary for a specific Dynamixel ID
439+
* @param id The Dynamixel ID
440+
* @return A string containing the error summary
441+
*/
442+
std::string getErrorSummary(uint8_t id) const;
443+
444+
/**
445+
* @brief Get error summaries for all Dynamixel IDs
446+
* @return A string containing error summaries for all Dynamixels
447+
*/
448+
std::string getAllErrorSummaries() const;
449+
355450
void MapInterfaces(
356451
size_t outer_size,
357452
size_t inner_size,

package.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
33
<package format="3">
44
<name>dynamixel_hardware_interface</name>
5-
<version>1.4.9</version>
5+
<version>1.4.10</version>
66
<description>
77
ROS 2 package providing a hardware interface for controlling Dynamixel motors via the ROS 2 control framework.
88
</description>
@@ -12,16 +12,20 @@
1212
<author email="[email protected]">Sungho Woo</author>
1313
<author email="[email protected]">Woojin Wie</author>
1414
<author email="[email protected]">Wonho Yun</author>
15+
1516
<buildtool_depend>ament_cmake</buildtool_depend>
17+
1618
<depend>rclcpp</depend>
1719
<depend>hardware_interface</depend>
1820
<depend>pluginlib</depend>
1921
<depend>realtime_tools</depend>
2022
<depend>dynamixel_sdk</depend>
2123
<depend>std_srvs</depend>
2224
<depend>dynamixel_interfaces</depend>
25+
2326
<test_depend>ament_lint_auto</test_depend>
2427
<test_depend>ament_lint_common</test_depend>
28+
2529
<export>
2630
<build_type>ament_cmake</build_type>
2731
</export>

param/dxl_model/2xc430_w250.model

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ value_of_max_radian_position 4095
55
value_of_min_radian_position 0
66
min_radian -3.14159265
77
max_radian 3.14159265
8-
velocity_unit 0.229
8+
9+
[unit info]
10+
Data Name value unit Sign Type
11+
Present Velocity 0.0239691227 rad/s signed
12+
Goal Velocity 0.0239691227 rad/s signed
913

1014
[control table]
1115
Address Size Data Name

param/dxl_model/2xl430_w250.model

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ value_of_max_radian_position 4095
55
value_of_min_radian_position 0
66
min_radian -3.14159265
77
max_radian 3.14159265
8-
velocity_unit 0.229
8+
9+
[unit info]
10+
Data Name value unit Sign Type
11+
Present Velocity 0.0239691227 rad/s signed
12+
Goal Velocity 0.0239691227 rad/s signed
913

1014
[control table]
1115
Address Size Data Name

param/dxl_model/ffw_sg2_drive_1.model

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ value_of_max_radian_position 262144
55
value_of_min_radian_position -262144
66
min_radian -3.14159265
77
max_radian 3.14159265
8-
velocity_unit 0.01
8+
9+
[unit info]
10+
Data Name value unit Sign Type
11+
Present Velocity 0.0010471976 rad/s signed
12+
Goal Velocity 0.0010471976 rad/s signed
913

1014
[control table]
1115
Address Size Data Name

param/dxl_model/ffw_sg2_drive_2.model

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ value_of_max_radian_position 262144
55
value_of_min_radian_position -262144
66
min_radian -3.14159265
77
max_radian 3.14159265
8-
velocity_unit 0.01
8+
9+
[unit info]
10+
Data Name value unit Sign Type
11+
Present Velocity 0.0010471976 rad/s signed
12+
Goal Velocity 0.0010471976 rad/s signed
913

1014
[control table]
1115
Address Size Data Name

0 commit comments

Comments
 (0)