From 8055cdf2c8a10c4fad120f64943b30278dc09a44 Mon Sep 17 00:00:00 2001 From: Bryce Grant Date: Tue, 11 Nov 2025 16:30:35 -0500 Subject: [PATCH 1/6] Add ROS2 Jazzy Jalisco support This commit adds full compatibility with ROS 2 Jazzy (Ubuntu 24.04). Changes: - Update ResourceManager API for Jazzy compatibility in tests - Implement new on_init(HardwareComponentInterfaceParams) signature - Fix nodiscard warnings by checking set_value() return values - Replace deprecated get_value() with get_optional() - Add proper error handling for command interfaces - Fix format string warnings in logging - Add CMake policy CMP0060 to suppress path cycle warnings - Update README with Jazzy installation instructions Tested on: - Ubuntu 24.04 LTS (Noble Numbat) - ROS 2 Jazzy Jalisco --- README.md | 65 +++++++++++++++++ robotiq_controllers/CMakeLists.txt | 5 ++ .../src/robotiq_activation_controller.cpp | 27 ++++++- .../robotiq_driver/hardware_interface.hpp | 12 ++- robotiq_driver/src/hardware_interface.cpp | 16 +++- ...est_robotiq_gripper_hardware_interface.cpp | 73 ++++++++----------- robotiq_hardware_tests/CMakeLists.txt | 5 ++ 7 files changed, 151 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index a53ce562..e123be33 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Initially this repo supported only the 2f-85 however we want to also support the ## Build status Currently the `main` branch is used for all current releases: Humble, Iron and Rolling. +The `jazzy` branch adds support for ROS 2 Jazzy Jalisco (Ubuntu 24.04). As this is not a core ROS 2 package API/ABI breakage is not guaranteed, it is done as best effort and takes into account maintenance costs. This is not sponsored or maintained by Robotiq we try to keep everything on main to reduce maintenance overhead. @@ -29,6 +30,11 @@ ROS2 Distro | Branch | Build status | Documentation | Released packages :---------: | :----: | :----------: | :-----------: | :---------------: **Iron** | [`main`](https://github.com/PickNikRobotics/ros2_robotiq_gripper/tree/main) | [![Iron Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-binary-build-main.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-binary-build-main.yml?branch=main)
[![Iron Semi-Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-semi-binary-build-main.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-semi-binary-build-main.yml?branch=main) | | [ros2_robotiq_gripper](https://index.ros.org/p/ros2_robotiq_gripper/github-PickNikRobotics-ros2_robotiq_grippper/#iron) + +ROS2 Distro | Branch | Build status | Documentation | Released packages +:---------: | :----: | :----------: | :-----------: | :---------------: +**Jazzy** | [`jazzy`](#) | N/A | | Not yet released + ### Explanation of different build types **NOTE**: There are three build stages checking current and future compatibility of the package. @@ -45,3 +51,62 @@ ROS2 Distro | Branch | Build status | Documentation | Released packages Uses repos file: `$NAME$.repos` 1. Source build - also core ROS packages are build from source. It shows potential issues in the mid future. + +--- + +## ROS 2 Jazzy Jalisco Support + +This fork adds support for **ROS 2 Jazzy Jalisco** (Ubuntu 24.04). The Jazzy branch includes API compatibility updates required for the newer ROS 2 release. + +### Installation (Jazzy) + +```bash +# Create workspace +mkdir -p ~/ws_robotiq/src +cd ~/ws_robotiq/src + +# Clone this repository (jazzy branch) +git clone -b jazzy https://github.com/YOUR_USERNAME/ros2_robotiq_gripper.git + +# Import dependencies (gets the serial package) +vcs import src < ros2_robotiq_gripper/ros2_robotiq_gripper.rolling.repos + +# Build +cd ~/ws_robotiq +colcon build --symlink-install + +# Source +source install/setup.bash +``` + +### Changes from Humble/Iron/Rolling + +The Jazzy port includes the following updates for API compatibility: + +1. **Hardware Interface API Updates** + - Updated `ResourceManager` constructor to use new Jazzy signature with `rclcpp::Clock` and `rclcpp::Logger` + - Implemented new `on_init(const HardwareComponentInterfaceParams&)` method alongside deprecated signature + - Changed from `rclcpp::ClockType::SYSTEM_TIME` to `RCL_SYSTEM_TIME` constant + +2. **Controller Interface Updates** + - Updated to check return values from `LoanedCommandInterface::set_value()` (now marked with `[[nodiscard]]`) + - Replaced deprecated `get_value()` with `get_optional()` for safer value retrieval + - Added proper error handling for command interface operations + +3. **CMake Updates** + - Added CMake policy CMP0060 to suppress harmless runtime search path warnings + - Fixed format string warnings in logging statements + +4. **Dependencies** + - Requires the `serial` package from [tylerjw/serial](https://github.com/tylerjw/serial) (imported via `.repos` file) + - All other dependencies remain the same as Humble/Iron/Rolling + +### Tested Environment + +- Ubuntu 24.04 LTS (Noble Numbat) +- ROS 2 Jazzy Jalisco +- All packages build successfully without errors + +### Contributing + +This Jazzy port was created to enable compatibility with Ubuntu 24.04 systems. If you encounter issues or have improvements, please open an issue or pull request. diff --git a/robotiq_controllers/CMakeLists.txt b/robotiq_controllers/CMakeLists.txt index c4334bc5..72ea8416 100644 --- a/robotiq_controllers/CMakeLists.txt +++ b/robotiq_controllers/CMakeLists.txt @@ -1,6 +1,11 @@ cmake_minimum_required(VERSION 3.8) project(robotiq_controllers) +# Suppress CMake warning about runtime search path cycles +if(POLICY CMP0060) + cmake_policy(SET CMP0060 NEW) +endif() + if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wall -Wextra -Wpedantic) endif() diff --git a/robotiq_controllers/src/robotiq_activation_controller.cpp b/robotiq_controllers/src/robotiq_activation_controller.cpp index aa63d214..02ebdef8 100644 --- a/robotiq_controllers/src/robotiq_activation_controller.cpp +++ b/robotiq_controllers/src/robotiq_activation_controller.cpp @@ -105,14 +105,33 @@ rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn Roboti bool RobotiqActivationController::reactivateGripper(std_srvs::srv::Trigger::Request::SharedPtr /*req*/, std_srvs::srv::Trigger::Response::SharedPtr resp) { - command_interfaces_[REACTIVATE_GRIPPER_RESPONSE].set_value(ASYNC_WAITING); - command_interfaces_[REACTIVATE_GRIPPER_CMD].set_value(1.0); + // Set values and check for success (required due to nodiscard attribute) + if (!command_interfaces_[REACTIVATE_GRIPPER_RESPONSE].set_value(ASYNC_WAITING)) + { + resp->success = false; + resp->message = "Failed to set gripper response interface"; + return false; + } + if (!command_interfaces_[REACTIVATE_GRIPPER_CMD].set_value(1.0)) + { + resp->success = false; + resp->message = "Failed to set gripper command interface"; + return false; + } - while (command_interfaces_[REACTIVATE_GRIPPER_RESPONSE].get_value() == ASYNC_WAITING) + // Use get_optional instead of deprecated get_value + while (true) { + auto response_opt = command_interfaces_[REACTIVATE_GRIPPER_RESPONSE].get_optional(); + if (response_opt.has_value() && response_opt.value() != ASYNC_WAITING) + { + break; + } std::this_thread::sleep_for(std::chrono::milliseconds(50)); } - resp->success = command_interfaces_[REACTIVATE_GRIPPER_RESPONSE].get_value(); + + auto final_response = command_interfaces_[REACTIVATE_GRIPPER_RESPONSE].get_optional(); + resp->success = final_response.has_value() && final_response.value() > 0.0; return resp->success; } diff --git a/robotiq_driver/include/robotiq_driver/hardware_interface.hpp b/robotiq_driver/include/robotiq_driver/hardware_interface.hpp index 517249ab..0a5eadf6 100644 --- a/robotiq_driver/include/robotiq_driver/hardware_interface.hpp +++ b/robotiq_driver/include/robotiq_driver/hardware_interface.hpp @@ -71,7 +71,7 @@ class RobotiqGripperHardwareInterface : public hardware_interface::SystemInterfa /** * Initialization of the hardware interface from data parsed from the - * robot's URDF. + * robot's URDF (deprecated signature for backward compatibility). * @param hardware_info Structure with data from URDF. * @returns CallbackReturn::SUCCESS if required data are provided and can be * parsed or CallbackReturn::ERROR if any error happens or data are missing. @@ -79,6 +79,16 @@ class RobotiqGripperHardwareInterface : public hardware_interface::SystemInterfa ROBOTIQ_DRIVER_PUBLIC CallbackReturn on_init(const hardware_interface::HardwareInfo& info) override; + /** + * Initialization of the hardware interface from data parsed from the + * robot's URDF (new Jazzy signature). + * @param params Parameters including hardware_info and executor. + * @returns CallbackReturn::SUCCESS if required data are provided and can be + * parsed or CallbackReturn::ERROR if any error happens or data are missing. + */ + ROBOTIQ_DRIVER_PUBLIC + CallbackReturn on_init(const hardware_interface::HardwareComponentInterfaceParams& params) override; + /** * Connect to the hardware. * @param previous_state The previous state. diff --git a/robotiq_driver/src/hardware_interface.cpp b/robotiq_driver/src/hardware_interface.cpp index b837af51..439afe54 100644 --- a/robotiq_driver/src/hardware_interface.cpp +++ b/robotiq_driver/src/hardware_interface.cpp @@ -37,6 +37,7 @@ #include #include +#include #include @@ -73,10 +74,19 @@ RobotiqGripperHardwareInterface::RobotiqGripperHardwareInterface(std::unique_ptr } hardware_interface::CallbackReturn RobotiqGripperHardwareInterface::on_init(const hardware_interface::HardwareInfo& info) +{ + // Call the new on_init with params struct for backward compatibility + hardware_interface::HardwareComponentInterfaceParams params; + params.hardware_info = info; + return on_init(params); +} + +hardware_interface::CallbackReturn RobotiqGripperHardwareInterface::on_init( + const hardware_interface::HardwareComponentInterfaceParams& params) { RCLCPP_DEBUG(kLogger, "on_init"); - if (hardware_interface::SystemInterface::on_init(info) != CallbackReturn::SUCCESS) + if (hardware_interface::SystemInterface::on_init(params) != CallbackReturn::SUCCESS) { return CallbackReturn::ERROR; } @@ -107,8 +117,8 @@ hardware_interface::CallbackReturn RobotiqGripperHardwareInterface::on_init(cons if (joint.command_interfaces[0].name != hardware_interface::HW_IF_POSITION) { - RCLCPP_FATAL(kLogger, "Joint '%s' has %s command interfaces found. '%s' expected.", joint.name.c_str(), - joint.command_interfaces[0].name.c_str(), hardware_interface::HW_IF_POSITION); + RCLCPP_FATAL(kLogger, "Joint '%s' does not have expected '%s' interface.", joint.name.c_str(), + hardware_interface::HW_IF_POSITION); return CallbackReturn::ERROR; } diff --git a/robotiq_driver/tests/test_robotiq_gripper_hardware_interface.cpp b/robotiq_driver/tests/test_robotiq_gripper_hardware_interface.cpp index ea700834..046e7082 100644 --- a/robotiq_driver/tests/test_robotiq_gripper_hardware_interface.cpp +++ b/robotiq_driver/tests/test_robotiq_gripper_hardware_interface.cpp @@ -29,13 +29,14 @@ #include #include -#if __has_include() -#include -#else -#include -#endif +#include -#include +#include +#include +#include + +#include +#include namespace robotiq_driver::test { @@ -46,46 +47,30 @@ namespace robotiq_driver::test */ TEST(TestRobotiqGripperHardwareInterface, load_urdf) { - std::string urdf = + std::string urdf_control_ = R"( - - - - - - - - - - - - - - robotiq_driver/RobotiqGripperHardwareInterface - 1.0 - 0.5 - /dev/ttyUSB0 - 0.7929 - - - - - 0.7929 - - - - - - )"; - - rclcpp::Node node{ "test_robotiq_gripper_hardware_interface" }; + + + robotiq_driver/RobotiqGripperHardwareInterface + 1.0 + 0.5 + /dev/ttyUSB0 + 0.7929 + + + + + 0.7929 + + + + + )"; -#if HARDWARE_INTERFACE_VERSION_GTE(4, 13, 0) - // Initialize the resource manager - hardware_interface::ResourceManager rm(urdf, node.get_node_clock_interface(), node.get_node_logging_interface()); -#else - hardware_interface::ResourceManager rm(urdf); -#endif + auto urdf = ros2_control_test_assets::urdf_head + urdf_control_ + ros2_control_test_assets::urdf_tail; + auto clock = std::make_shared(RCL_SYSTEM_TIME); + auto logger = rclcpp::get_logger("test_robotiq_gripper_hardware_interface"); + hardware_interface::ResourceManager rm(urdf, clock, logger); // Check interfaces EXPECT_EQ(1u, rm.system_components_size()); diff --git a/robotiq_hardware_tests/CMakeLists.txt b/robotiq_hardware_tests/CMakeLists.txt index 668cf319..ad137152 100644 --- a/robotiq_hardware_tests/CMakeLists.txt +++ b/robotiq_hardware_tests/CMakeLists.txt @@ -3,6 +3,11 @@ cmake_minimum_required(VERSION 3.8) project(robotiq_hardware_tests LANGUAGES CXX) +# Suppress CMake warning about runtime search path cycles +if(POLICY CMP0060) + cmake_policy(SET CMP0060 NEW) +endif() + # This module provides installation directories as per the GNU coding standards. include(GNUInstallDirs) From e41053a71eadec1533a78b3de45925b6078fab6e Mon Sep 17 00:00:00 2001 From: Bryce Grant Date: Tue, 11 Nov 2025 16:32:05 -0500 Subject: [PATCH 2/6] Updated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e123be33..69b40c7a 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ mkdir -p ~/ws_robotiq/src cd ~/ws_robotiq/src # Clone this repository (jazzy branch) -git clone -b jazzy https://github.com/YOUR_USERNAME/ros2_robotiq_gripper.git +git clone -b jazzy https://github.com/bryceag11/ros2_robotiq_gripper.git # Import dependencies (gets the serial package) vcs import src < ros2_robotiq_gripper/ros2_robotiq_gripper.rolling.repos From c3a463d522e44064437388ea61c37f64fa474a49 Mon Sep 17 00:00:00 2001 From: Bryce Grant <67086260+bryceag11@users.noreply.github.com> Date: Wed, 19 Nov 2025 12:50:04 -0500 Subject: [PATCH 3/6] Update package.xml --- robotiq_driver/package.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/robotiq_driver/package.xml b/robotiq_driver/package.xml index 856ed977..e3d35078 100644 --- a/robotiq_driver/package.xml +++ b/robotiq_driver/package.xml @@ -33,6 +33,8 @@ ament_cmake_gmock + + ros2_control_test_assets ament_cmake From f15e7963fa87ebc88508339f4d4e22d863f42050 Mon Sep 17 00:00:00 2001 From: Bryce Grant <67086260+bryceag11@users.noreply.github.com> Date: Wed, 19 Nov 2025 12:50:22 -0500 Subject: [PATCH 4/6] Update CMakeLists.txt --- robotiq_driver/tests/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/robotiq_driver/tests/CMakeLists.txt b/robotiq_driver/tests/CMakeLists.txt index 5db0b3c8..357e1d89 100644 --- a/robotiq_driver/tests/CMakeLists.txt +++ b/robotiq_driver/tests/CMakeLists.txt @@ -2,6 +2,7 @@ find_package(ament_cmake_gtest REQUIRED) find_package(ament_cmake_gmock REQUIRED) find_package(ament_lint_auto REQUIRED) +find_package(ros2_control_test_assets REQUIRED) ament_lint_auto_find_test_dependencies() @@ -20,7 +21,9 @@ target_include_directories(test_robotiq_gripper_hardware_interface PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ) target_link_libraries(test_robotiq_gripper_hardware_interface robotiq_driver) -ament_target_dependencies(test_robotiq_gripper_hardware_interface) +ament_target_dependencies(test_robotiq_gripper_hardware_interface + ros2_control_test_assets +) ############################################################################### # test_default_serial_factory From c80a1fe102b56600e159da824d97f384648f68e7 Mon Sep 17 00:00:00 2001 From: Bryce Grant <67086260+bryceag11@users.noreply.github.com> Date: Wed, 19 Nov 2025 12:50:48 -0500 Subject: [PATCH 5/6] Update hardware_interface.cpp --- robotiq_driver/src/hardware_interface.cpp | 47 +++++++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/robotiq_driver/src/hardware_interface.cpp b/robotiq_driver/src/hardware_interface.cpp index 439afe54..46ec298a 100644 --- a/robotiq_driver/src/hardware_interface.cpp +++ b/robotiq_driver/src/hardware_interface.cpp @@ -86,7 +86,7 @@ hardware_interface::CallbackReturn RobotiqGripperHardwareInterface::on_init( { RCLCPP_DEBUG(kLogger, "on_init"); - if (hardware_interface::SystemInterface::on_init(params) != CallbackReturn::SUCCESS) + if (hardware_interface::SystemInterface::on_init(params.hardware_info) != CallbackReturn::SUCCESS) { return CallbackReturn::ERROR; } @@ -166,11 +166,50 @@ RobotiqGripperHardwareInterface::on_configure(const rclcpp_lifecycle::State& pre return CallbackReturn::ERROR; } - // Open the serial port and handshake. - bool connected = driver_->connect(); + // Open the serial port and handshake with retry logic + // This allows time for tool communication (socat) to create virtual serial port + const int max_retries = 10; + const auto retry_delay = std::chrono::milliseconds(500); + bool connected = false; + + for (int attempt = 1; attempt <= max_retries && !connected; ++attempt) + { + try + { + RCLCPP_INFO(kLogger, "Attempting to connect to Robotiq gripper (attempt %d/%d)...", attempt, max_retries); + connected = driver_->connect(); + + if (!connected) + { + if (attempt < max_retries) + { + RCLCPP_WARN(kLogger, "Connection failed, retrying in %ld ms...", retry_delay.count()); + std::this_thread::sleep_for(retry_delay); + } + } + else + { + RCLCPP_INFO(kLogger, "Successfully connected to Robotiq gripper"); + } + } + catch (const std::exception& e) + { + if (attempt < max_retries) + { + RCLCPP_WARN(kLogger, "Connection attempt %d failed: %s. Retrying in %ld ms...", + attempt, e.what(), retry_delay.count()); + std::this_thread::sleep_for(retry_delay); + } + else + { + throw; // Re-throw on last attempt + } + } + } + if (!connected) { - RCLCPP_ERROR(kLogger, "Cannot connect to the Robotiq gripper"); + RCLCPP_ERROR(kLogger, "Cannot connect to the Robotiq gripper after %d attempts", max_retries); return CallbackReturn::ERROR; } } From 6133932519909e46b8fc3f8659be92d8f822f8c2 Mon Sep 17 00:00:00 2001 From: Malte Schrader Date: Fri, 5 Dec 2025 00:08:47 +0100 Subject: [PATCH 6/6] Updated README.md - fixed path in `vcs import` --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 69b40c7a..25f378e4 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ cd ~/ws_robotiq/src git clone -b jazzy https://github.com/bryceag11/ros2_robotiq_gripper.git # Import dependencies (gets the serial package) -vcs import src < ros2_robotiq_gripper/ros2_robotiq_gripper.rolling.repos +vcs import . < ros2_robotiq_gripper/ros2_robotiq_gripper.rolling.repos # Build cd ~/ws_robotiq