diff --git a/README.md b/README.md
index 971b98830..f0fd981d5 100644
--- a/README.md
+++ b/README.md
@@ -66,7 +66,9 @@ The following examples are part of this demo repository:
The example shows a simple chainable controller and its integration to form a controller chain to control the joints of *RRBot*.
-* Example 13: ["Multi-robot system with lifecycle management: adjust controllers at runtime"](example_13)
+* Example 13: ["Multi-robot system with lifecycle management"](example_13)
+
+ This example shows how to include multiple robots in a single controller manager instance.
* Example 14: ["Modular robots with actuators not providing states and with additional sensors"](example_14)
diff --git a/doc/index.rst b/doc/index.rst
index f4c4af214..45bfc20d5 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -75,7 +75,8 @@ Example 11: "Car-like robot using steering controller library (tba.)"
Example 12: "Controller chaining"
The example shows a simple chainable controller and its integration to form a controller chain to control the joints of *RRBot*.
-Example 13: "Multi-robot example (tba.)"
+Example 13: "Multi-robot system with lifecycle management"
+ This example shows how to include multiple robots in a single controller manager instance.
Example 14: "Modular robots with actuators not providing states and with additional sensors"
@@ -271,4 +272,5 @@ Examples
Example 9: Gazebo classic <../example_9/doc/userdoc.rst>
Example 10: Industrial robot with GPIO interfaces <../example_10/doc/userdoc.rst>
Example 12: Controller chaining <../example_12/doc/userdoc.rst>
+ Example 13: Multiple robots <../example_13/doc/userdoc.rst>
Example 14: Modular robots with actuators not providing states <../example_14/doc/userdoc.rst>
diff --git a/example_13/README.md b/example_13/README.md
index a2cbd3904..1050a8583 100644
--- a/example_13/README.md
+++ b/example_13/README.md
@@ -1,328 +1,5 @@
-### Example XX: "Multi-robot system with tools"
+# ros2_control_demo_example_13
-- Launch file: [three_robots.launch.py](ros2_control_demo_bringup/launch/three_robots.launch.py)
-- Controllers: [three_robots_controllers.yaml](ros2_control_demo_bringup/config/three_robots_controllers.yaml)
-- URDF: [three_robots.urdf.xacro](ros2_control_demo_bringup/config/three_robots.urdf.xacro)
-- ros2_control URDF: [three_robots.ros2_control.xacro](ros2_control_demo_description/rrbot_description/ros2_control/three_robots.ros2_control.xacro)
+ This example shows how to include multiple robots in a single controller manager instance.
-
-**Hardware and interfaces**:
-- RRBotSystemPositionOnly (auto-start)
- - Command interfaces:
- - rrbot_joint1/position
- - rrbot_joint2/position
- - State interfaces:
- - rrbot_joint1/position
- - rrbot_joint2/position
-
-- ExternalRRBotFTSensor (auto-start)
- - State interfaces:
- - rrbot_tcp_fts_sensor/force.x
- - rrbot_tcp_fts_sensor/force.y
- - rrbot_tcp_fts_sensor/force.z
- - rrbot_tcp_fts_sensor/torque.x
- - rrbot_tcp_fts_sensor/torque.y
- - rrbot_tcp_fts_sensor/torque.z
-
-- RRBotSystemWithSensor (auto-configure)
- - Command interfaces:
- - rrbot_with_sensor_joint1/position
- - rrbot_with_sensor_joint2/position
- - State interfaces:
- - rrbot_with_sensor_joint1/position
- - rrbot_with_sensor_joint2/position
- - rrbot_with_sensor_tcp_fts_sensor/force.x
- - rrbot_with_sensor_tcp_fts_sensor/torque.z
-
-- ThreeDofBot
- - Command interfaces
- - threedofbot_joint1/position
- - threedofbot_joint1/pid_gain
- - threedofbot_joint2/position
- - threedofbot_joint2/pid_gain
- - threedofbot_joint3/position
- - threedofbot_joint3/pid_gain
- - State interfaces:
- - threedofbot_joint1/position
- - threedofbot_joint1/pid_gain
- - threedofbot_joint2/position
- - threedofbot_joint2/pid_gain
- - threedofbot_joint3/position
- - threedofbot_joint3/pid_gain
-
-**Available controllers**:
-- `joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster]`
-
-- RRBotSystemPositionOnly
- - `rrbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster]`
- - `rrbot_position_controller[forward_command_controller/ForwardCommandController]`
-
-- ExternalRRBotFTSensor
- - `rrbot_external_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster]`
-
-- RRBotSystemPositionOnly
- - `rrbot_with_sensor_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster]`
- - `rrbot_with_sensor_position_controller[forward_command_controller/ForwardCommandController]`
- - `rrbot_with_sensor_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster]`
-
-- FakeThreeDofBot
- - `threedofbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster]`
- - `threedofbot_position_controller[forward_command_controller/ForwardCommandController]`
- - `threedofbot_pid_gain_controller[forward_command_controller/ForwardCommandController]`
-
-
-Caveats on hardware lifecycling:
-- There is currently no synchronization between available interface and controllers using them.
- This means that you should stop controller before making interfaces they are using unavailable.
- If you don't do this and deactivate/cleanup your interface first your computer will catch fire!
-- Global Joint State Broadcaster will not broadcast interfaces that become available after it is started.
- To solve this restart it manually, for now. During restart TF-transforms are not available.
-- There is a possibility that hardware lifecycling (state changes) interfere with the `update`-loop if you are trying to start/stop a controller at the same time.
-
-
-Notes:
- 1. After starting the example there should be the following scene:
- - right robot is moving (RRBotSystemPositionOnly - using auto-start)
- - All interfaces are available and position controller is started and receives commands
- - all controllers running
- - left robot is standing upright (RRBotWithSensor - using auto-configure)
- - only state interfaces are available therefore it can visualized, but not moved
- - only position command controller is not running
- - middle robot is "broken" (FakeThreeDofBot - it is only initialized)
- - no interfaces are available
- - all controllers inactive
-
- Hardware status: (`ros2 control list_hardware_components`)
-
- ```
- Hardware Component 1
- name: FakeThreeDofBot
- type: system
- plugin name: mock_components/GenericSystem
- state: id=1 label=unconfigured
- command interfaces
- threedofbot_joint1/position [unavailable] [unclaimed]
- threedofbot_joint1/pid_gain [unavailable] [unclaimed]
- threedofbot_joint2/position [unavailable] [unclaimed]
- threedofbot_joint2/pid_gain [unavailable] [unclaimed]
- threedofbot_joint3/position [unavailable] [unclaimed]
- threedofbot_joint3/pid_gain [unavailable] [unclaimed]
- Hardware Component 2
- name: RRBotSystemWithSensor
- type: system
- plugin name: ros2_control_demo_hardware/RRBotSystemWithSensorHardware
- state: id=2 label=inactive
- command interfaces
- rrbot_with_sensor_joint1/position [available] [unclaimed]
- rrbot_with_sensor_joint2/position [available] [unclaimed]
- Hardware Component 3
- name: ExternalRRBotFTSensor
- type: sensor
- plugin name: ros2_control_demo_hardware/ExternalRRBotForceTorqueSensorHardware
- state: id=3 label=active
- command interfaces
- Hardware Component 4
- name: RRBotSystemPositionOnly
- type: system
- plugin name: ros2_control_demo_hardware/RRBotSystemPositionOnlyHardware
- state: id=3 label=active
- command interfaces
- rrbot_joint1/position [available] [claimed]
- rrbot_joint2/position [available] [claimed]
- ```
-
- Controllers status: (`ros2 control list_controllers`)
- ```
- joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_external_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
- rrbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_position_controller[forward_command_controller/ForwardCommandController] active
- rrbot_with_sensor_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
- rrbot_with_sensor_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_with_sensor_position_controller[forward_command_controller/ForwardCommandController] inactive
- threedofbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] inactive
- threedofbot_pid_gain_controller[forward_command_controller/ForwardCommandController] inactive
- threedofbot_position_controller[forward_command_controller/ForwardCommandController] inactive
- ```
-
- 2. Activate `RRBotWithSensor` and its position controller. Call
- ```
- ros2 service call /controller_manager/set_hardware_component_state controller_manager_msgs/srv/SetHardwareComponentState "
- name: RRBotSystemWithSensor
- target_state:
- id: 0
- label: active"
- ros2 control switch_controllers --activate rrbot_with_sensor_position_controller
- ```
-
- Scenario state:
- - right robot is moving
- - left robot is moving
- - middle robot is "broken"
-
- Hardware status: `RRBotSystemWithSensor` is in state active
- Controllers status, `rrbot_with_sensor_position_controller` is now active:
- ```
- $ ros2 control list_controllers
- joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_external_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
- rrbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_position_controller[forward_command_controller/ForwardCommandController] active
- rrbot_with_sensor_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
- rrbot_with_sensor_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_with_sensor_position_controller[forward_command_controller/ForwardCommandController] active
- threedofbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] inactive
- threedofbot_pid_gain_controller[forward_command_controller/ForwardCommandController] inactive
- threedofbot_position_controller[forward_command_controller/ForwardCommandController] inactive
- ```
-
- 3. Configure `FakeThreeDofBot` and its joint state broadcaster and non-movement command interfaces. Call
- ```
- ros2 service call /controller_manager/set_hardware_component_state controller_manager_msgs/srv/SetHardwareComponentState "
- name: FakeThreeDofBot
- target_state:
- id: 0
- label: inactive"
- ros2 control switch_controllers --activate threedofbot_joint_state_broadcaster threedofbot_pid_gain_controller
- ```
-
- Scenario state:
- - right robot is moving
- - left robot is moving
- - middle robot is still "broken"
-
-
- Hardware status: `FakeThreeDofBot` is in inactive state.
- Controllers status, `threedofbot_joint_state_broadcaster` and `threedofbot_pid_gain_controller` are in active state now:
- ```
- $ ros2 control list_controllers
- joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_external_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
- rrbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_position_controller[forward_command_controller/ForwardCommandController] active
- rrbot_with_sensor_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
- rrbot_with_sensor_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_with_sensor_position_controller[forward_command_controller/ForwardCommandController] active
- threedofbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- threedofbot_pid_gain_controller[forward_command_controller/ForwardCommandController] active
- threedofbot_position_controller[forward_command_controller/ForwardCommandController] inactive
- ```
-
- 1. Restart global joint state broadcaster to broadcast all available states from the framework.
- First check output to have comparison:
- ```
- ros2 topic echo /joint_states --once
- ```
- Restart:
- ```
- ros2 control switch_controllers --deactivate joint_state_broadcaster
- ros2 control switch_controllers --activate joint_state_broadcaster
- ```
- Check output for comparison, now the joint_states of `threedofbot` and `rrbot_with_sensor` are broadcasted, too.
- ```
- ros2 topic echo /joint_states --once
- ```
-
- Scenario state (everything is broken during `joint_state_broadcaster` restart):
- - right robot is moving
- - left robot is moving
- - middle robot is now still "standing"
-
- 1. Activate `FakeThreeDofBot` and its joint state broadcaster and non-movement command interfaces. Call
- ```
- ros2 service call /controller_manager/set_hardware_component_state controller_manager_msgs/srv/SetHardwareComponentState "
- name: FakeThreeDofBot
- target_state:
- id: 0
- label: active"
- ros2 control switch_controllers --activate threedofbot_position_controller
- ```
-
- Scenario state:
- - right robot is moving
- - left robot is moving
- - middle robot is moving
-
- Hardware status: `FakeThreeDofBot` is in active state.
- Controllers status (all active now):
- ```
- $ ros2 control list_controllers
- joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_external_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
- rrbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_position_controller[forward_command_controller/ForwardCommandController] active
- rrbot_with_sensor_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
- rrbot_with_sensor_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_with_sensor_position_controller[forward_command_controller/ForwardCommandController] active
- threedofbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- threedofbot_pid_gain_controller[forward_command_controller/ForwardCommandController] active
- threedofbot_position_controller[forward_command_controller/ForwardCommandController] active
- ```
-
- 1. Deactivate `RRBotSystemPositionOnly` and its position controller (first). Call
- ```
- ros2 control switch_controllers --deactivate rrbot_position_controller
- ros2 service call /controller_manager/set_hardware_component_state controller_manager_msgs/srv/SetHardwareComponentState "
- name: RRBotSystemPositionOnly
- target_state:
- id: 0
- label: inactive"
- ```
-
- Scenario state:
- - right robot is "standing"
- - left robot is moving
- - middle robot is moving
-
- Hardware status: `RRBotSystemPositionOnly` is in inactive state.
- Controllers status: `rrbot_position_controller` is now in inactive state
- ```
- $ ros2 control list_controllers
- joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_external_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
- rrbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_position_controller[forward_command_controller/ForwardCommandController] inactive
- rrbot_with_sensor_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
- rrbot_with_sensor_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_with_sensor_position_controller[forward_command_controller/ForwardCommandController] active
- threedofbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- threedofbot_pid_gain_controller[forward_command_controller/ForwardCommandController] active
- threedofbot_position_controller[forward_command_controller/ForwardCommandController] active
- ```
-
- 1. Set `RRBotSystemPositionOnly` in unconfigured state, and deactivate its joint state broadcaster.
- Also restart global joint state broadcaster. Call
- ```
- ros2 control switch_controllers --deactivate rrbot_joint_state_broadcaster joint_state_broadcaster
- ros2 service call /controller_manager/set_hardware_component_state controller_manager_msgs/srv/SetHardwareComponentState "
- name: RRBotSystemPositionOnly
- target_state:
- id: 0
- label: unconfigured"
- ros2 service call /controller_manager/set_hardware_component_state controller_manager_msgs/srv/SetHardwareComponentState "
- name: RRBotSystemPositionOnly
- target_state:
- id: 0
- label: finalized"
- ros2 control switch_controllers --activate joint_state_broadcaster
- ```
-
- Scenario state (everything is broken during `joint_state_broadcaster` restart):
- - right robot is "broken"
- - left robot is moving
- - middle robot is moving
-
- Hardware status:
- Controllers status: (`ros2 control list_controllers`)
- ```
- joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_external_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
- rrbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] inactive
- rrbot_position_controller[forward_command_controller/ForwardCommandController] inactive
- rrbot_with_sensor_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
- rrbot_with_sensor_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- rrbot_with_sensor_position_controller[forward_command_controller/ForwardCommandController] active
- threedofbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
- threedofbot_pid_gain_controller[forward_command_controller/ForwardCommandController] active
- threedofbot_position_controller[forward_command_controller/ForwardCommandController] active
- ```
+Find the documentation in [doc/userdoc.rst](doc/userdoc.rst) or on [control.ros.org](https://control.ros.org/master/doc/ros2_control_demos/example_13/doc/userdoc.html).
diff --git a/example_13/doc/userdoc.rst b/example_13/doc/userdoc.rst
new file mode 100644
index 000000000..91a5ec87c
--- /dev/null
+++ b/example_13/doc/userdoc.rst
@@ -0,0 +1,391 @@
+:github_url: https://github.com/ros-controls/ros2_control_demos/blob/{REPOS_FILE_BRANCH}/example_13/doc/userdoc.rst
+
+.. _ros2_control_demos_example_13_userdoc:
+
+Example 13: Multi-robot system with lifecycle management
+==========================================================
+
+- Launch file: [three_robots.launch.py](ros2_control_demo_bringup/launch/three_robots.launch.py)
+- Controllers: [three_robots_controllers.yaml](ros2_control_demo_bringup/config/three_robots_controllers.yaml)
+- URDF: [three_robots.urdf.xacro](ros2_control_demo_bringup/config/three_robots.urdf.xacro)
+- ros2_control URDF: [three_robots.ros2_control.xacro](ros2_control_demo_description/rrbot_description/ros2_control/three_robots.ros2_control.xacro)
+
+
+Hardware and interfaces
+-------------------------
+
+- RRBotSystemPositionOnly (auto-start)
+
+ - Command interfaces:
+
+ - rrbot_joint1/position
+ - rrbot_joint2/position
+
+ - State interfaces:
+
+ - rrbot_joint1/position
+ - rrbot_joint2/position
+
+- ExternalRRBotFTSensor (auto-start)
+
+ - State interfaces:
+
+ - rrbot_tcp_fts_sensor/force.x
+ - rrbot_tcp_fts_sensor/force.y
+ - rrbot_tcp_fts_sensor/force.z
+ - rrbot_tcp_fts_sensor/torque.x
+ - rrbot_tcp_fts_sensor/torque.y
+ - rrbot_tcp_fts_sensor/torque.z
+
+- RRBotSystemWithSensor (auto-configure)
+
+ - Command interfaces:
+
+ - rrbot_with_sensor_joint1/position
+ - rrbot_with_sensor_joint2/position
+
+ - State interfaces:
+
+ - rrbot_with_sensor_joint1/position
+ - rrbot_with_sensor_joint2/position
+ - rrbot_with_sensor_tcp_fts_sensor/force.x
+ - rrbot_with_sensor_tcp_fts_sensor/torque.z
+
+- ThreeDofBot
+
+ - Command interfaces
+
+ - threedofbot_joint1/position
+ - threedofbot_joint1/pid_gain
+ - threedofbot_joint2/position
+ - threedofbot_joint2/pid_gain
+ - threedofbot_joint3/position
+ - threedofbot_joint3/pid_gain
+
+ - State interfaces:
+
+ - threedofbot_joint1/position
+ - threedofbot_joint1/pid_gain
+ - threedofbot_joint2/position
+ - threedofbot_joint2/pid_gain
+ - threedofbot_joint3/position
+ - threedofbot_joint3/pid_gain
+
+Available controllers
+-------------------------
+
+- ``joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster]``
+
+- RRBotSystemPositionOnly
+
+ - ``rrbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster]``
+ - ``rrbot_position_controller[forward_command_controller/ForwardCommandController]``
+
+- ExternalRRBotFTSensor
+
+ - ``rrbot_external_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster]``
+
+- RRBotSystemPositionOnly
+
+ - ``rrbot_with_sensor_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster]``
+ - ``rrbot_with_sensor_position_controller[forward_command_controller/ForwardCommandController]``
+ - ``rrbot_with_sensor_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster]``
+
+- FakeThreeDofBot
+
+ - ``threedofbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster]``
+ - ``threedofbot_position_controller[forward_command_controller/ForwardCommandController]``
+ - ``threedofbot_pid_gain_controller[forward_command_controller/ForwardCommandController]``
+
+
+Caveats on hardware lifecycling
+--------------------------------
+
+- There is currently no synchronization between available interface and controllers using them.
+ This means that you should stop controller before making interfaces they are using unavailable.
+ If you don't do this and deactivate/cleanup your interface first your computer will catch fire!
+- Global Joint State Broadcaster will not broadcast interfaces that become available after it is started.
+ To solve this restart it manually, for now. During restart TF-transforms are not available.
+- There is a possibility that hardware lifecycling (state changes) interfere with the ``update``-loop
+ if you are trying to start/stop a controller at the same time.
+
+
+Tutorial steps
+--------------------------
+
+.. include:: ../../doc/run_from_docker.rst
+
+1. After starting the example there should be the following scene:
+ - right robot is moving (RRBotSystemPositionOnly - using auto-start)
+ - All interfaces are available and position controller is started and receives commands
+ - all controllers running
+ - left robot is standing upright (RRBotWithSensor - using auto-configure)
+ - only state interfaces are available therefore it can visualized, but not moved
+ - only position command controller is not running
+ - middle robot is "broken" (FakeThreeDofBot - it is only initialized)
+ - no interfaces are available
+ - all controllers inactive
+
+ Hardware status: (``ros2 control list_hardware_components``)
+
+ .. code-block:: shell
+
+ Hardware Component 1
+ name: FakeThreeDofBot
+ type: system
+ plugin name: mock_components/GenericSystem
+ state: id=1 label=unconfigured
+ command interfaces
+ threedofbot_joint1/position [unavailable] [unclaimed]
+ threedofbot_joint1/pid_gain [unavailable] [unclaimed]
+ threedofbot_joint2/position [unavailable] [unclaimed]
+ threedofbot_joint2/pid_gain [unavailable] [unclaimed]
+ threedofbot_joint3/position [unavailable] [unclaimed]
+ threedofbot_joint3/pid_gain [unavailable] [unclaimed]
+ Hardware Component 2
+ name: RRBotSystemWithSensor
+ type: system
+ plugin name: ros2_control_demo_hardware/RRBotSystemWithSensorHardware
+ state: id=2 label=inactive
+ command interfaces
+ rrbot_with_sensor_joint1/position [available] [unclaimed]
+ rrbot_with_sensor_joint2/position [available] [unclaimed]
+ Hardware Component 3
+ name: ExternalRRBotFTSensor
+ type: sensor
+ plugin name: ros2_control_demo_hardware/ExternalRRBotForceTorqueSensorHardware
+ state: id=3 label=active
+ command interfaces
+ Hardware Component 4
+ name: RRBotSystemPositionOnly
+ type: system
+ plugin name: ros2_control_demo_hardware/RRBotSystemPositionOnlyHardware
+ state: id=3 label=active
+ command interfaces
+ rrbot_joint1/position [available] [claimed]
+ rrbot_joint2/position [available] [claimed]
+
+ Controllers status:
+
+ .. code-block:: shell
+
+ $ ros2 control list_controllers
+ joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_external_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
+ rrbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_position_controller[forward_command_controller/ForwardCommandController] active
+ rrbot_with_sensor_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
+ rrbot_with_sensor_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_with_sensor_position_controller[forward_command_controller/ForwardCommandController] inactive
+ threedofbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] inactive
+ threedofbot_pid_gain_controller[forward_command_controller/ForwardCommandController] inactive
+ threedofbot_position_controller[forward_command_controller/ForwardCommandController] inactive
+
+
+2. Activate ``RRBotWithSensor`` and its position controller. Call
+
+ .. code-block:: shell
+
+ ros2 service call /controller_manager/set_hardware_component_state controller_manager_msgs/srv/SetHardwareComponentState "
+ name: RRBotSystemWithSensor
+ target_state:
+ id: 0
+ label: active"
+ ros2 control switch_controllers --activate rrbot_with_sensor_position_controller
+
+ Scenario state:
+
+ - right robot is moving
+ - left robot is moving
+ - middle robot is "broken"
+
+ Hardware status: ``RRBotSystemWithSensor`` is in state active
+
+ Controllers status: ``rrbot_with_sensor_position_controller`` is now active:
+
+ .. code-block:: shell
+
+ $ ros2 control list_controllers
+ joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_external_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
+ rrbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_position_controller[forward_command_controller/ForwardCommandController] active
+ rrbot_with_sensor_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
+ rrbot_with_sensor_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_with_sensor_position_controller[forward_command_controller/ForwardCommandController] active
+ threedofbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] inactive
+ threedofbot_pid_gain_controller[forward_command_controller/ForwardCommandController] inactive
+ threedofbot_position_controller[forward_command_controller/ForwardCommandController] inactive
+
+
+3. Configure ``FakeThreeDofBot`` and its joint state broadcaster and non-movement command interfaces. Call
+
+ .. code-block:: shell
+
+ ros2 service call /controller_manager/set_hardware_component_state controller_manager_msgs/srv/SetHardwareComponentState "
+ name: FakeThreeDofBot
+ target_state:
+ id: 0
+ label: inactive"
+ ros2 control switch_controllers --activate threedofbot_joint_state_broadcaster threedofbot_pid_gain_controller
+
+ Scenario state:
+
+ - right robot is moving
+ - left robot is moving
+ - middle robot is still "broken"
+
+ Hardware status: ``FakeThreeDofBot`` is in inactive state.
+
+ Controllers status, ``threedofbot_joint_state_broadcaster`` and ``threedofbot_pid_gain_controller`` are in active state now:
+
+ .. code-block:: shell
+
+ $ ros2 control list_controllers
+ joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_external_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
+ rrbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_position_controller[forward_command_controller/ForwardCommandController] active
+ rrbot_with_sensor_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
+ rrbot_with_sensor_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_with_sensor_position_controller[forward_command_controller/ForwardCommandController] active
+ threedofbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ threedofbot_pid_gain_controller[forward_command_controller/ForwardCommandController] active
+ threedofbot_position_controller[forward_command_controller/ForwardCommandController] inactive
+
+
+4. Restart global joint state broadcaster to broadcast all available states from the framework. First check output to have comparison:
+
+ .. code-block:: shell
+
+ ros2 topic echo /joint_states --once
+
+ Restart:
+
+ .. code-block:: shell
+
+ ros2 control switch_controllers --deactivate joint_state_broadcaster
+ ros2 control switch_controllers --activate joint_state_broadcaster
+
+ Check output for comparison, now the joint_states of ``threedofbot`` and ``rrbot_with_sensor`` are broadcasted, too.
+
+ .. code-block:: shell
+
+ ros2 topic echo /joint_states --once
+
+ Scenario state (everything is broken during ``joint_state_broadcaster`` restart):
+
+ - right robot is moving
+ - left robot is moving
+ - middle robot is now still "standing"
+
+5. Activate ``FakeThreeDofBot`` and its joint state broadcaster and non-movement command interfaces. Call
+
+ .. code-block:: shell
+
+ ros2 service call /controller_manager/set_hardware_component_state controller_manager_msgs/srv/SetHardwareComponentState "
+ name: FakeThreeDofBot
+ target_state:
+ id: 0
+ label: active"
+ ros2 control switch_controllers --activate threedofbot_position_controller
+
+ Scenario state:
+
+ - right robot is moving
+ - left robot is moving
+ - middle robot is moving
+
+ Hardware status: ``FakeThreeDofBot`` is in active state.
+
+ Controllers status (all active now):
+
+ .. code-block:: shell
+
+ $ ros2 control list_controllers
+ joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_external_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
+ rrbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_position_controller[forward_command_controller/ForwardCommandController] active
+ rrbot_with_sensor_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
+ rrbot_with_sensor_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_with_sensor_position_controller[forward_command_controller/ForwardCommandController] active
+ threedofbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ threedofbot_pid_gain_controller[forward_command_controller/ForwardCommandController] active
+ threedofbot_position_controller[forward_command_controller/ForwardCommandController] active
+
+
+6. Deactivate ``RRBotSystemPositionOnly`` and its position controller (first). Call
+
+ .. code-block:: shell
+
+ ros2 control switch_controllers --deactivate rrbot_position_controller
+ ros2 service call /controller_manager/set_hardware_component_state controller_manager_msgs/srv/SetHardwareComponentState "
+ name: RRBotSystemPositionOnly
+ target_state:
+ id: 0
+ label: inactive"
+
+ Scenario state:
+
+ - right robot is "standing"
+ - left robot is moving
+ - middle robot is moving
+
+ Hardware status: ``RRBotSystemPositionOnly`` is in inactive state.
+
+ Controllers status: ``rrbot_position_controller`` is now in inactive state
+
+ .. code-block:: shell
+
+ $ ros2 control list_controllers
+ joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_external_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
+ rrbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_position_controller[forward_command_controller/ForwardCommandController] inactive
+ rrbot_with_sensor_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
+ rrbot_with_sensor_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_with_sensor_position_controller[forward_command_controller/ForwardCommandController] active
+ threedofbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ threedofbot_pid_gain_controller[forward_command_controller/ForwardCommandController] active
+ threedofbot_position_controller[forward_command_controller/ForwardCommandController] active
+
+
+7. Set ``RRBotSystemPositionOnly`` in unconfigured state, and deactivate its joint state broadcaster. Also restart global joint state broadcaster. Call
+
+ .. code-block:: shell
+
+ ros2 control switch_controllers --deactivate rrbot_joint_state_broadcaster joint_state_broadcaster
+ ros2 service call /controller_manager/set_hardware_component_state controller_manager_msgs/srv/SetHardwareComponentState "
+ name: RRBotSystemPositionOnly
+ target_state:
+ id: 0
+ label: unconfigured"
+ ros2 service call /controller_manager/set_hardware_component_state controller_manager_msgs/srv/SetHardwareComponentState "
+ name: RRBotSystemPositionOnly
+ target_state:
+ id: 0
+ label: finalized"
+ ros2 control switch_controllers --activate joint_state_broadcaster
+
+ Scenario state (everything is broken during ``joint_state_broadcaster`` restart):
+
+ - right robot is "broken"
+ - left robot is moving
+ - middle robot is moving
+
+ Controllers status:
+
+ .. code-block:: shell
+
+ $ ros2 control list_controllers
+ joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_external_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
+ rrbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] inactive
+ rrbot_position_controller[forward_command_controller/ForwardCommandController] inactive
+ rrbot_with_sensor_fts_broadcaster[force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster] active
+ rrbot_with_sensor_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ rrbot_with_sensor_position_controller[forward_command_controller/ForwardCommandController] active
+ threedofbot_joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
+ threedofbot_pid_gain_controller[forward_command_controller/ForwardCommandController] active
+ threedofbot_position_controller[forward_command_controller/ForwardCommandController] active
diff --git a/example_13/package.xml b/example_13/package.xml
index 6f6640f25..00cc2eb39 100644
--- a/example_13/package.xml
+++ b/example_13/package.xml
@@ -16,8 +16,6 @@
ament_cmake
- rrbot_description
- r3bot_description
ros2_control_demo_example_4
ros2_control_demo_example_5
rviz2