Skip to content

ros2_control_node aborts if the gripper is not connected when the driver starts #38

Description

@ebarnett3

If /dev/ttyUSB0 does not exist (gripper unplugged) or is inaccessible when robotiq_control.launch.py starts, ros2_control_node dies with SIGABRT instead of staying unconfigured and retrying. The only way back is to plug the gripper in and relaunch everything.

Carried over from PickNik: PickNikRobotics/ros2_robotiq_gripper#88.

Reproduce

Either path produces the same failure.

In the container, with the gripper unplugged so run.sh maps no serial device:

cd <your clone of robotiq/ros>
./docker/run.sh build       # rebuild the image from the current checkout: run.sh reuses an
                            # existing image, so a branch switch alone changes nothing inside it
./docker/run.sh gripper     # logs "detecting serial devices (/dev/ttyUSB*) ..." and finds none

# then, at the container prompt:
ros2 launch robotiq_description robotiq_control.launch.py com_port:=/dev/ttyUSB0

ROS_DISTRO=humble ./docker/run.sh gripper reproduces it on the Humble image too.

That form needs neither hardware nor a container and takes the identical path: the port
lookup fails before anything is opened.

Observed (ROS 2 Jazzy, abridged)

[resource_manager]: 'configure' hardware 'RobotiqGripperHardwareInterface'
[RobotiqGripperHardwareInterface]: Cannot connect to the Robotiq gripper:
    SerialIOException: no serial port named '/dev/ttyUSB0' (is the device connected?)
[resource_manager]: Failed to 'configure' hardware 'RobotiqGripperHardwareInterface'
terminate called after throwing an instance of 'std::runtime_error'
  what():  Failed to set the initial state of the component
           : RobotiqGripperHardwareInterface to active
... (stack trace through ControllerManager::init_resource_manager)
Aborted (Signal sent by tkill() 30 0)
[ERROR] [ros2_control_node-1]: process has died [pid 30, exit code -6, ...]

Analysis

  1. The SDK raises SerialIOException when the port cannot be opened.
  2. The hardware interface's on_configure correctly returns ERROR — that part follows the ros2_control lifecycle.
  3. But the launch configuration asks for initial state active. When configure fails, ControllerManager re-throws as an uncaught std::runtime_errorstd::terminateSIGABRT. The whole ros2_control_node dies.

The diagnostic half of this has already improved: the message now names the port and asks whether the device is connected, instead of surfacing a raw IO Exception (2) with a library source path. The crash itself is unchanged.

Expected

Configure fails → the hardware stays unconfigured → the node keeps running, retries periodically (or exposes a service for a manual retry). The user can plug the gripper in afterwards and recover without relaunching.

Related

After this crash the three spawners poll /controller_manager/list_controllers forever — #27.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions