Robotiq ROS 2 packages 1.1.0
This release introduces the gripper packages — robotiq_driver, robotiq_controllers, robotiq_description, robotiq_hardware_tests — and carries the accumulated TSF-85 work. Humble, Jazzy and Lyrical are supported from the single main branch; Rolling is built and watched but does not gate.
From this release the repository is versioned as a whole: every package carries the same version and one v<version> tag covers both stacks. Earlier tags were per-stack — V1.0.0 released the TSF packages, 0.0.1 was PickNik's original gripper release — so the first unified tag continues from the highest of them rather than restarting.
Gripper packages
Robotiq's ROS 2 ros2_control driver for the 2F adaptive grippers, running on the Robotiq C++ grippers SDK 1.0.0 — the extern/grippers submodule — instead of an in-tree Modbus implementation.
Descriptions ship for the 2F-85 and 2F-140. This release is hardware-validated on a 2F-85; the 2F-140 description ships untested on hardware. The driver itself is model-agnostic — it needs a serial link and gripper_closed_position — so a Hand-E works once you supply a URDF for it, but no Hand-E description ships yet.
It continues PickNik Robotics' ros2_robotiq_gripper (BSD-3-Clause), which Robotiq now develops and supports: issues go to robotiq/ros/issues.
Migrating from PickNik
Migration is easy at the workspace level. Package names, launch files, controller names, the xacro macro arguments and the /robotiq_gripper_controller/gripper_cmd action are unchanged, and on Humble the controller and action types are identical to PickNik's humble branch — existing action clients, launch overrides and xacro arguments keep working untouched. robotiq_control.launch.py picks the matching controller config from $ROS_DISTRO on its own.
Watch for these, though:
- Clone with
--recurse-submodules. The SDK arrives as theextern/gripperssubmodule; without itrobotiq_driverwill not build. Already cloned?git submodule update --init. - Remove both old sources from the workspace:
- the PickNik clone (
rm -rf src/ros2_robotiq_gripper, otherwise colcon fails on duplicate package names) - the
vcs importedserialpackage (rm -rf src/serial)
Thenrm -rf build installto clear artifacts built from the PickNik sources.
- the PickNik clone (
- No more
vcs import. The.reposfile no longer pullstylerjw/serial; the transport comes from the SDK submodule. Any script or CI job that ranvcs import < ros2_robotiq_gripper.*.reposneeds that step deleted. - libserialport has no rosdep key. Install it yourself (
sudo apt install libserialport-dev) and runrosdep install --from-paths src --ignore-src -y --skip-keys libserialport. Plainrosdep installfails. - Jazzy / Lyrical action type. If you move off Humble at the same time, the goal type changes from
control_msgs/action/GripperCommandtoParallelGripperCommand(aJointStatenaming the knuckle joint). This break is upstream ROS's —gripper_controllersis gone in Kilted+ — not ours (PickNik PR #103). Staying on Humble requires no change. - On Humble, per-goal speed and force still come from the xacro. Humble's
gripper_controllershas no parameters for theset_gripper_max_effort/set_gripper_max_velocityinterfaces, so it cannot claim them (PickNik'suse_effort_interface/use_speed_interfaceentries were silently ignored there too). Usegripper_speed_multiplier/gripper_force_multiplier. use_dummychanged meaning: it now drives the SDK's fake gripper — no port opened, instant activation, fingers report their last command — while keeping the real plugin loaded so the gripper and activation controllers still bind. That is what distinguishes it fromuse_fake_hardware:=true, which swaps inmock_components/GenericSystemand exports neither the speed/effort interfaces nor thereactivate_gripperGPIO.- Activating the hardware component still releases any grip and runs the full calibration sweep, and deactivating resets the gripper the same way — unchanged PickNik behaviour, but keep the workspace clear and do not restart the stack with a part held. A conservative alternative exists in the SDK and is not wired up yet: #28.
- Exchange rate is platform-limited.
connection_frequencydefaults to 100 Hz; the default macOS FTDI driver caps around 60 Hz and Windows timer quantization (~15.6 ms) limits periods below ~16 ms. Set it to what your platform can carry.
Improvements over PickNik
- One FC 0x17 (read/write multiple registers) transaction per cycle, in the SDK's background exchange thread, replacing the separate read and write transactions issued from inside
read()/write(). Half the bus traffic per cycle, the gripper link no longer paced by the controller manager's update loop, andread()/write()become process-image copies that never block on serial. - libserialport replaces the
vcs importedtylerjw/serialfork — a maintained, cross-platform transport with no workspace-level dependency step, and the FTDIlatency_timerlowered to 1 ms automatically on Linux (the 16 ms kernel default triples Modbus latency). - Configurable hardware parameters in the
<hardware>block:baudrate,timeout(default 500 ms),slave_address,connection_frequency(default 100 Hz),activation_timeout(default 15 s),gripper_max_speed/gripper_max_force(SI full scale for the command interfaces),use_dummy. A malformed value is reported and the default stands; onlygripper_closed_positionfails the transition. - Activation and fault recovery are bounded by
activation_timeout. The old driver had no timeout and could block a lifecycle transition indefinitely. - Three live LTS distros from one branch (Humble / Jazzy / Lyrical), with GitHub Actions building all of them plus Rolling as a non-blocking heads-up.
- Docs and CI back in-tree. PickNik's README and CI were removed upstream; documentation lives in the repo README and issues go to robotiq/ros/issues. A unified Docker image with device mapping is included (
./docker/run.sh gripper).
PickNik bugs fixed
- PickNikRobotics/ros2_robotiq_gripper#114 —
robotiq_controllers.yamlreferenced command interfaces that the hardware interface does not export, so the controller failed to activate on real hardware. Interface names corrected toset_gripper_max_effort/set_gripper_max_velocity, and the temporarysedpatch in the Dockerfile removed. - PickNikRobotics/ros2_robotiq_gripper#88 —
ros2_control_nodecrashed when the gripper was not connected at startup. Connection failures now failon_configurecleanly with an actionable message (24 V power, RS-485 wiring,COM_port/slave_address/baudratehints) instead of escaping as an unhandled exception.
Still open
- #26 — the hardware interface still exports only position and velocity state interfaces; object detection (
gOBJ) and measured effort (gCU) are not exposed. Carried over from PickNikRobotics/ros2_robotiq_gripper#118. - #27 — the
ros2_controlspawners keep retrying afterros2_control_nodeexits, so a bringup with no gripper attached ends in a retry loop rather than a clean exit. - #28 —
on_activateruns the full reset-then-activate handshake every time, so it releases anything held; a conservative activate-only path is wanted. - #29 — the
velocitystate interface is always0.0(the gripper's status block carries position and current only), which trips the gripper controller's velocity-based stall detection on every goal: motion completes normally and the action reportsSUCCEEDED, butresult.reached_goalisfalseandstalledistrue. Check the action status, or the joint position against your tolerance, rather thanreached_goal. Carried over from PickNik.
TSF-85 packages
Because the repository is now versioned as a whole, this tag also publishes the robotiq_tsf work accumulated since V1.0.0:
poll_data_nodeis replaced bypoll_data_sdk_node, which parses through the vendor SDK (extern/tactile_sensors, libserialport). The old node misparsedStaticDatain a bistable per-plug-event way and segfaulted on Ctrl-C; the new one is hardware-verified, adds USB-descriptor autodetect and a first-data watchdog, and exits cleanly on SIGINT. Subscribers need no change — all seven topics (TactileSensor/StaticData,Dynamic,Accelerometer,Gyroscope,Quaternion,EulerAngle,Timestamp) keep their names and message types. Only the executable name changed, so a launch file, script or unit invokingpoll_data_nodedirectly must be repointed; launch files in this repo already default to the new poller, and expose apollerargument to override it.extern/tactile_sensorsupdated to v2.0.0.- AHRS quaternion and per-finger IMU math migrated to Eigen.
- Tactile sensor RViz visualization added.
- Builds on Humble and Lyrical; one gtest binary per package; unused OpenCV and libusb dependencies dropped.
Repository
- One version, one tag.
VERSIONat the repo root is the authoritative version string.package.xmlmust hold a literal version — ament, rosdep and bloom parse it statically — sodev/version.pypropagates it into all five packages and a pre-commit hook fails on drift. - CI: colcon build and test on Humble, Jazzy and Lyrical (merge-gating) plus Rolling (non-blocking), a repo-wide pre-commit formatting job (clang-format, black, flake8, codespell) and ament lint.
- Not released through bloom or the ROS build farm:
libserialporthas no rosdep key, so these are source installs — clone the tag and build.