Skip to content

Commit 88ba262

Browse files
authored
Merge pull request #15 from ROBOTIS-GIT/bump-1.3.0
Bump 1.3.0
2 parents ae46f55 + ab7956c commit 88ba262

File tree

10 files changed

+126
-48
lines changed

10 files changed

+126
-48
lines changed

.github/workflows/ros-ci.yml

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,57 @@
1-
name: ros-ci
1+
# The name of the workflow
2+
name: CI
23

3-
# Controls when the action will run. Triggers the workflow on push or pull request
4+
# Specifies the events that trigger the workflow
45
on:
56
push:
6-
branches: [ humble ]
7+
branches: [ main, humble, jazzy ]
78
pull_request:
8-
branches: [ humble ]
9+
branches: [ main, humble, jazzy ]
910

10-
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
11+
# Defines a set of jobs to be run as part of the workflow
1112
jobs:
12-
humble:
13+
# The name of the job
14+
ROS_CI:
1315
runs-on: ubuntu-22.04
1416
strategy:
1517
fail-fast: false
1618
matrix:
1719
ros_distribution:
1820
- humble
21+
- jazzy
22+
- rolling
1923
include:
24+
# ROS 2 Humble Hawksbill
2025
- docker_image: ubuntu:jammy
2126
ros_distribution: humble
2227
ros_version: 2
23-
# # Rolling
24-
# - docker_image: ubuntu:jammy
25-
# ros_distribution: rolling
26-
# ros_version: 2
28+
# ROS 2 Jazzy Jalisco
29+
- docker_image: ubuntu:noble
30+
ros_distribution: jazzy
31+
ros_version: 2
32+
# ROS 2 Rolling Ridley
33+
- docker_image: ubuntu:noble
34+
ros_distribution: rolling
35+
ros_version: 2
2736
container:
2837
image: ${{ matrix.docker_image }}
2938
steps:
30-
- name: Setup directories
39+
- name: Setup workspace
3140
run: mkdir -p ros_ws/src
32-
- name: checkout
33-
uses: actions/checkout@v3
41+
42+
- name: Checkout code
43+
uses: actions/checkout@v4
3444
with:
3545
path: ros_ws/src
46+
3647
- name: Setup ROS environment
37-
uses: ros-tooling/setup-ros@0.7.1
48+
uses: ros-tooling/setup-ros@v0.7
3849
with:
3950
required-ros-distributions: ${{ matrix.ros_distribution }}
51+
4052
- name: Build and Test
41-
uses: ros-tooling/action-ros-ci@0.3.5
53+
uses: ros-tooling/action-ros-ci@v0.3
4254
with:
43-
package-name: dynamixel_hardware_interface
4455
target-ros2-distro: ${{ matrix.ros_distribution }}
4556
vcs-repo-file-url: "https://raw.githubusercontent.com/ROBOTIS-GIT/dynamixel_hardware_interface/main/dynamixel_hardware_interface_ci.repos"
57+
package-name: dynamixel_hardware_interface

.github/workflows/ros-lint.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# The name of the workflow
2+
name: Lint
3+
4+
# Specifies the events that trigger the workflow
5+
on:
6+
pull_request:
7+
8+
# Defines a set of jobs to be run as part of the workflow
9+
jobs:
10+
ament_lint:
11+
runs-on: ubuntu-latest
12+
container:
13+
image: rostooling/setup-ros-docker:ubuntu-noble-ros-rolling-ros-base-latest
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
linter: [cppcheck, cpplint, uncrustify, flake8, pep257, lint_cmake, xmllint, copyright]
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v4
21+
22+
- name: Setup ROS environment
23+
uses: ros-tooling/[email protected]
24+
25+
- name: Run Linter
26+
env:
27+
AMENT_CPPCHECK_ALLOW_SLOW_VERSIONS: 1
28+
uses: ros-tooling/action-ros-lint@master
29+
with:
30+
linter: ${{ matrix.linter }}
31+
distribution: rolling
32+
package-name: "*"

CHANGELOG.rst

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

5+
1.3.0 (2025-02-17)
6+
------------------
7+
* Enhance Error Handling and Timeout Management
8+
* Use GroupFastSyncRead and GroupFastBulkRead
9+
* Remove deprecated parameter ros_update_freq_ to prevent stoi failure
10+
* Contributors: Woojin Wie
11+
512
1.2.0 (2025-01-17)
613
------------------
714
* Extend Bulk/Sync Selection Logic to Include Indirect Operations

README.md

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,6 @@ ROS 2 package providing a hardware interface for controlling [Dynamixel](https:/
1111

1212
This package currently supports ROS 2 Humble only. Ensure that ROS 2 Humble is properly installed (ROS 2 Humble installation guide).
1313

14-
- [Dynamixel SDK](https://github.com/ROBOTIS-GIT/DynamixelSDK):
15-
- Install the Dynamixel SDK using the following command:
16-
17-
```bash
18-
sudo apt install ros-humble-dynamixel-sdk
19-
```
20-
2114
- Hardware Requirements:
2215

2316
- Dynamixel servos
@@ -31,6 +24,7 @@ This package currently supports ROS 2 Humble only. Ensure that ROS 2 Humble is p
3124

3225
```bash
3326
cd ~/${WORKSPACE}/src
27+
git clone -b humble https://github.com/ROBOTIS-GIT/DynamixelSDK.git
3428
git clone -b humble https://github.com/ROBOTIS-GIT/dynamixel_hardware_interface.git
3529
git clone -b humble https://github.com/ROBOTIS-GIT/dynamixel_interfaces.git
3630
```

dynamixel_hardware_interface_ci.repos

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ repositories:
22
utils/DynamixelSDK:
33
type: git
44
url: https://github.com/ROBOTIS-GIT/DynamixelSDK.git
5-
version: humble
5+
version: main
66
dynamixel_hardware_interface/dynamixel_interfaces:
77
type: git
88
url: https://github.com/ROBOTIS-GIT/dynamixel_interfaces.git
9-
version: humble
9+
version: main

include/dynamixel_hardware_interface/dynamixel/dynamixel.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,12 @@ class Dynamixel
125125
std::vector<RWItemList> read_data_list_;
126126

127127
// sync read
128-
dynamixel::GroupSyncRead * group_sync_read_;
128+
dynamixel::GroupFastSyncRead * group_sync_read_;
129129
// indirect inform for sync read
130130
std::map<uint8_t /*id*/, IndirectInfo> indirect_info_read_;
131131

132132
// bulk read
133-
dynamixel::GroupBulkRead * group_bulk_read_;
133+
dynamixel::GroupFastBulkRead * group_bulk_read_;
134134

135135
// write item (sync or bulk) variable
136136
bool write_type_;

include/dynamixel_hardware_interface/dynamixel_hardware_interface.hpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
#include "dynamixel_interfaces/srv/set_data_to_dxl.hpp"
3939
#include "dynamixel_interfaces/srv/reboot_dxl.hpp"
4040

41-
#include "realtime_tools/realtime_publisher.h"
42-
#include "realtime_tools/realtime_buffer.h"
41+
#include "realtime_tools/realtime_publisher.hpp"
42+
#include "realtime_tools/realtime_buffer.hpp"
4343

4444
#include "std_srvs/srv/set_bool.hpp"
4545

@@ -181,7 +181,12 @@ class DynamixelHardware : public
181181
std::map<uint8_t /*id*/, uint8_t /*err*/> dxl_hw_err_;
182182
DxlTorqueStatus dxl_torque_status_;
183183
std::map<uint8_t /*id*/, bool /*enable*/> dxl_torque_state_;
184-
double err_timeout_sec_;
184+
double err_timeout_ms_;
185+
rclcpp::Duration read_error_duration_{0, 0};
186+
rclcpp::Duration write_error_duration_{0, 0};
187+
bool is_read_in_error_{false};
188+
bool is_write_in_error_{false};
189+
185190
bool use_revolute_to_prismatic_{false};
186191
std::string conversion_dxl_name_{""};
187192
std::string conversion_joint_name_{""};
@@ -322,8 +327,6 @@ class DynamixelHardware : public
322327
double revoluteToPrismatic(double revolute_value);
323328

324329
double prismaticToRevolute(double prismatic_value);
325-
326-
int ros_update_freq_;
327330
};
328331

329332
} // namespace dynamixel_hardware_interface

package.xml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,25 @@
11
<?xml version='1.0' encoding='UTF-8'?>
22
<package format="3">
33
<name>dynamixel_hardware_interface</name>
4-
<version>1.2.0</version>
4+
<version>1.3.0</version>
55
<description>
66
ROS 2 package providing a hardware interface for controlling Dynamixel motors via the ROS 2 control framework.
77
</description>
88
<maintainer email="[email protected]">Pyo</maintainer>
99
<license>Apache 2.0</license>
1010
<author email="[email protected]">Hye-Jong KIM</author>
1111
<author email="[email protected]">Sungho Woo</author>
12-
12+
<author email="[email protected]">Woojin Wie</author>
1313
<buildtool_depend>ament_cmake</buildtool_depend>
14-
1514
<depend>rclcpp</depend>
1615
<depend>hardware_interface</depend>
1716
<depend>pluginlib</depend>
1817
<depend>realtime_tools</depend>
1918
<depend>dynamixel_sdk</depend>
2019
<depend>std_srvs</depend>
2120
<depend>dynamixel_interfaces</depend>
22-
2321
<test_depend>ament_lint_auto</test_depend>
2422
<test_depend>ament_lint_common</test_depend>
25-
2623
<export>
2724
<build_type>ament_cmake</build_type>
2825
</export>

src/dynamixel/dynamixel.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ DxlError Dynamixel::SetSyncReadHandler(std::vector<uint8_t> id_arr)
799799
IN_ADDR, indirect_info_read_[id_arr.at(0)].size);
800800

801801
group_sync_read_ =
802-
new dynamixel::GroupSyncRead(
802+
new dynamixel::GroupFastSyncRead(
803803
port_handler_, packet_handler_,
804804
IN_ADDR, indirect_info_read_[id_arr.at(0)].size);
805805

@@ -917,7 +917,7 @@ DxlError Dynamixel::SetBulkReadHandler(std::vector<uint8_t> id_arr)
917917
IN_ADDR, indirect_info_read_[id_arr.at(0)].size);
918918
}
919919

920-
group_bulk_read_ = new dynamixel::GroupBulkRead(port_handler_, packet_handler_);
920+
group_bulk_read_ = new dynamixel::GroupFastBulkRead(port_handler_, packet_handler_);
921921

922922
for (auto it_id : id_arr) {
923923
uint8_t ID = it_id;

src/dynamixel_hardware_interface.cpp

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ DynamixelHardware::DynamixelHardware()
3535
{
3636
dxl_status_ = DXL_OK;
3737
dxl_torque_status_ = TORQUE_ENABLED;
38-
err_timeout_sec_ = 3.0;
38+
err_timeout_ms_ = 500;
39+
is_read_in_error_ = false;
40+
is_write_in_error_ = false;
41+
read_error_duration_ = rclcpp::Duration(0, 0);
42+
write_error_duration_ = rclcpp::Duration(0, 0);
3943
}
4044

4145
DynamixelHardware::~DynamixelHardware()
@@ -64,7 +68,13 @@ hardware_interface::CallbackReturn DynamixelHardware::on_init(
6468

6569
port_name_ = info_.hardware_parameters["port_name"];
6670
baud_rate_ = info_.hardware_parameters["baud_rate"];
67-
err_timeout_sec_ = stod(info_.hardware_parameters["error_timeout_sec"]);
71+
try {
72+
err_timeout_ms_ = stod(info_.hardware_parameters["error_timeout_ms"]);
73+
} catch (const std::exception & e) {
74+
RCLCPP_ERROR(
75+
logger_, "Failed to parse error_timeout_ms parameter: %s, using default value",
76+
e.what());
77+
}
6878

6979
RCLCPP_INFO_STREAM(
7080
logger_,
@@ -269,8 +279,6 @@ hardware_interface::CallbackReturn DynamixelHardware::on_init(
269279
str_set_dxl_torque_srv_name,
270280
std::bind(&DynamixelHardware::set_dxl_torque_srv_callback, this, _1, _2));
271281

272-
ros_update_freq_ = stoi(info_.hardware_parameters["ros_update_freq"]);
273-
274282
return hardware_interface::CallbackReturn::SUCCESS;
275283
}
276284

@@ -394,11 +402,24 @@ hardware_interface::return_type DynamixelHardware::read(
394402
} else if (dxl_status_ == DXL_OK || dxl_status_ == COMM_ERROR) {
395403
dxl_comm_err_ = CheckError(dxl_comm_->ReadMultiDxlData());
396404
if (dxl_comm_err_ != DxlError::OK) {
405+
if (!is_read_in_error_) {
406+
is_read_in_error_ = true;
407+
read_error_duration_ = rclcpp::Duration(0, 0);
408+
}
409+
read_error_duration_ = read_error_duration_ + period;
410+
397411
RCLCPP_ERROR_STREAM(
398412
logger_,
399-
"Dynamixel Read Fail :" << Dynamixel::DxlErrorToString(dxl_comm_err_));
400-
return hardware_interface::return_type::ERROR;
413+
"Dynamixel Read Fail (Duration: " << read_error_duration_.seconds() * 1000 << "ms/" <<
414+
err_timeout_ms_ << "ms)");
415+
416+
if (read_error_duration_.seconds() * 1000 >= err_timeout_ms_) {
417+
return hardware_interface::return_type::ERROR;
418+
}
419+
return hardware_interface::return_type::OK;
401420
}
421+
is_read_in_error_ = false;
422+
read_error_duration_ = rclcpp::Duration(0, 0);
402423
} else if (dxl_status_ == HW_ERROR) {
403424
dxl_comm_err_ = CheckError(dxl_comm_->ReadMultiDxlData());
404425
if (dxl_comm_err_ != DxlError::OK) {
@@ -434,7 +455,6 @@ hardware_interface::return_type DynamixelHardware::read(
434455
}
435456
return hardware_interface::return_type::OK;
436457
}
437-
438458
hardware_interface::return_type DynamixelHardware::write(
439459
const rclcpp::Time & time, const rclcpp::Duration & period)
440460
{
@@ -447,16 +467,29 @@ hardware_interface::return_type DynamixelHardware::write(
447467

448468
dxl_comm_->WriteMultiDxlData();
449469

470+
is_write_in_error_ = false;
471+
write_error_duration_ = rclcpp::Duration(0, 0);
472+
450473
return hardware_interface::return_type::OK;
451474
} else {
452-
RCLCPP_ERROR_STREAM(logger_, "Dynamixel Write Fail");
453-
return hardware_interface::return_type::ERROR;
475+
write_error_duration_ = write_error_duration_ + period;
476+
477+
RCLCPP_ERROR_STREAM(
478+
logger_,
479+
"Dynamixel Write Fail (Duration: " << write_error_duration_.seconds() * 1000 << "ms/" <<
480+
err_timeout_ms_ << "ms)");
481+
482+
if (write_error_duration_.seconds() * 1000 >= err_timeout_ms_) {
483+
return hardware_interface::return_type::ERROR;
484+
}
485+
return hardware_interface::return_type::OK;
454486
}
455487
}
456488

457489
DxlError DynamixelHardware::CheckError(DxlError dxl_comm_err)
458490
{
459491
DxlError error_state = DxlError::OK;
492+
dxl_status_ = DXL_OK;
460493

461494
// check comm error
462495
if (dxl_comm_err != DxlError::OK) {

0 commit comments

Comments
 (0)