Robots with Multiple Interfaces

This example demonstrates how to implement a multi-interface robot hardware, taking care of the interfaces used.

For example_3, the hardware interface plugin supports multiple command and state interfaces:

  • Communication is done using a proprietary API to interact with the robot control box.

  • Data for all joints is exchanged simultaneously.

  • Examples: KUKA FRI, ABB Yumi, Schunk LWA4p, etc.

Two intentionally misconfigured controllers demonstrate how the hardware interface can reject invalid joint interface claims.

Tutorial Steps

1. Launch RRBot Visualization

ros2 launch ros2_control_demo_example_3 view_robot.launch.py

Note: Warnings like Invalid frame ID "odom" are expected while joint_state_publisher_gui initializes. It provides a GUI to generate random configurations displayed in RViz.

2. Start RRBot with Multi-Interface Support

ros2 launch ros2_control_demo_example_3 rrbot_system_multi_interface.launch.py

Useful options:

  • robot_controller:=forward_position_controller: spawns a position controller.

  • robot_controller:=forward_acceleration_controller: spawns an acceleration controller.

This launch file loads the hardware, controllers, and RViz. Console output will show the internal hardware state (for demonstration only).

If RViz shows two orange and one yellow rectangles, the system has started correctly.

3. Verify Hardware Interface

ros2 control list_hardware_interfaces

Expected output:

command interfaces
    joint1/acceleration [available] [unclaimed]
    joint1/position [available] [unclaimed]
    joint1/velocity [available] [claimed]
    joint2/acceleration [available] [unclaimed]
    joint2/position [available] [unclaimed]
    joint2/velocity [available] [claimed]
state interfaces
    joint1/acceleration
    joint1/position
    joint1/velocity
    joint2/acceleration
    joint2/position
    joint2/velocity

4. Check Active Controllers

ros2 control list_controllers

Example output:

joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
forward_velocity_controller[velocity_controllers/JointGroupVelocityController] active

This output varies based on the robot_controller argument used.

5. Send Commands

a. Using CLI

  • For forward_position_controller:

ros2 topic pub /forward_position_controller/commands std_msgs/msg/Float64MultiArray "data:
- 0.5
- 0.5"
  • For forward_velocity_controller (default):

ros2 topic pub /forward_velocity_controller/commands std_msgs/msg/Float64MultiArray "data:
- 5
- 5"
  • For forward_acceleration_controller:

ros2 topic pub /forward_acceleration_controller/commands std_msgs/msg/Float64MultiArray "data:
- 10
- 10"

b. Using Demo Node (for position controller):

ros2 launch ros2_control_demo_example_3 test_forward_position_controller.launch.py

Terminal will log updates:

[INFO] Writing commands:
  command pos: 0.00, vel: 5.00, acc: 0.00 for joint 0
  command pos: 0.00, vel: 5.00, acc: 0.00 for joint 1
[INFO] Reading states:
  pos: 0.67, vel: 5.00, acc: 0.00 for joint 0
  pos: 0.67, vel: 5.00, acc: 0.00 for joint 1

6. Switch Controllers at Runtime

Load a new controller (if not already active):

ros2 control load_controller forward_position_controller $(ros2 pkg prefix ros2_control_demo_example_3 --share)/config/rrbot_multi_interface_forward_controllers.yaml
ros2 control set_controller_state forward_position_controller inactive

Then switch controllers:

ros2 control switch_controllers --deactivate forward_velocity_controller --activate forward_position_controller

Check updated interface claims:

ros2 control list_controllers
ros2 control list_hardware_interfaces

Now send commands using the new controller.

7. Demonstrate Illegal Controllers

Launch with:

  • robot_controller:=forward_illegal1_controller or

  • robot_controller:=forward_illegal2_controller

Expected error output:

[ERROR] [resource_manager]: Component 'RRBotSystemMultiInterface' did not accept new command resource combination:
  Start interfaces:
    joint1/position
  Stop interfaces:
    (none)
[ERROR] [controller_manager]: Could not switch controllers since prepare command mode switch was rejected.
[ERROR] [spawner_forward_illegal1_controller]: Failed to activate controller

Run:

ros2 control list_hardware_interfaces

Output:

command interfaces
  joint1/acceleration [available] [unclaimed]
  joint1/position [available] [unclaimed]
  joint1/velocity [available] [unclaimed]
  joint2/acceleration [available] [unclaimed]
  joint2/position [available] [unclaimed]
  joint2/velocity [available] [unclaimed]
ros2 control list_controllers

Output:

joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
forward_illegal1_controller[forward_command_controller/ForwardCommandController] inactive

Files Used in This Demo

Controllers in This Demo

  • Joint State Broadcaster (docs)

  • Forward Command Controller (docs)