From 0b414d0a30308a8c7eb30df696a282b32369763e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Fr=C3=B6hlich?= Date: Tue, 12 Mar 2024 20:37:28 +0100 Subject: [PATCH] Add GenericSystem to GPIO example (#429) * Add GenericSystem to GPIO example * Update doc * Clarify section with generic_system --- example_10/bringup/launch/rrbot.launch.py | 21 +++- .../ros2_control/rrbot.ros2_control.xacro | 26 +++-- example_10/description/urdf/rrbot.urdf.xacro | 3 +- example_10/doc/userdoc.rst | 103 +++++++++++++++++- 4 files changed, 140 insertions(+), 13 deletions(-) diff --git a/example_10/bringup/launch/rrbot.launch.py b/example_10/bringup/launch/rrbot.launch.py index 7e975d565..b277291d4 100644 --- a/example_10/bringup/launch/rrbot.launch.py +++ b/example_10/bringup/launch/rrbot.launch.py @@ -14,15 +14,27 @@ from launch import LaunchDescription -from launch.actions import RegisterEventHandler +from launch.actions import DeclareLaunchArgument, RegisterEventHandler from launch.event_handlers import OnProcessExit -from launch.substitutions import Command, FindExecutable, PathJoinSubstitution +from launch.substitutions import Command, FindExecutable, PathJoinSubstitution, LaunchConfiguration from launch_ros.actions import Node from launch_ros.substitutions import FindPackageShare def generate_launch_description(): + # Declare arguments + declared_arguments = [] + declared_arguments.append( + DeclareLaunchArgument( + "use_mock_hardware", + default_value="false", + description="Start robot with mock hardware mirroring command to its states.", + ) + ) + # Initialize Arguments + use_mock_hardware = LaunchConfiguration("use_mock_hardware") + # Get URDF via xacro robot_description_content = Command( [ @@ -35,6 +47,9 @@ def generate_launch_description(): "rrbot.urdf.xacro", ] ), + " ", + "use_mock_hardware:=", + use_mock_hardware, ] ) robot_description = {"robot_description": robot_description_content} @@ -94,4 +109,4 @@ def generate_launch_description(): delay_robot_controller_spawner_after_joint_state_broadcaster_spawner, ] - return LaunchDescription(nodes) + return LaunchDescription(declared_arguments + nodes) diff --git a/example_10/description/ros2_control/rrbot.ros2_control.xacro b/example_10/description/ros2_control/rrbot.ros2_control.xacro index e12bad4f7..77611c089 100644 --- a/example_10/description/ros2_control/rrbot.ros2_control.xacro +++ b/example_10/description/ros2_control/rrbot.ros2_control.xacro @@ -1,15 +1,23 @@ - + - - ros2_control_demo_example_10/RRBotSystemWithGPIOHardware - 0 - 3.0 - 100 - + + + ros2_control_demo_example_10/RRBotSystemWithGPIOHardware + 0 + 3.0 + 100 + + + + + mock_components/GenericSystem + true + + @@ -34,7 +42,9 @@ - + + 1.0 + diff --git a/example_10/description/urdf/rrbot.urdf.xacro b/example_10/description/urdf/rrbot.urdf.xacro index c941ac0c9..6931188eb 100644 --- a/example_10/description/urdf/rrbot.urdf.xacro +++ b/example_10/description/urdf/rrbot.urdf.xacro @@ -6,6 +6,7 @@ https://github.com/ros-simulation/gazebo_ros_demos/blob/kinetic-devel/rrbot_desc --> + @@ -24,6 +25,6 @@ https://github.com/ros-simulation/gazebo_ros_demos/blob/kinetic-devel/rrbot_desc + name="RRBot" prefix="$(arg prefix)" use_mock_hardware="$(arg use_mock_hardware)"/> diff --git a/example_10/doc/userdoc.rst b/example_10/doc/userdoc.rst index a7e9f6f82..7cb30932c 100644 --- a/example_10/doc/userdoc.rst +++ b/example_10/doc/userdoc.rst @@ -91,6 +91,103 @@ The *RRBot* URDF files can be found in the ``description/urdf`` folder. [RRBotSystemWithGPIOHardware]: Got command 0.5 for GP output 0! [RRBotSystemWithGPIOHardware]: Got command 0.7 for GP output 1! +7. Let's introspect the ros2_control hardware component. Calling + + .. code-block:: shell + + ros2 control list_hardware_components + + should give you + + .. code-block:: shell + + Hardware Component 1 + name: RRBot + type: system + plugin name: ros2_control_demo_example_10/RRBotSystemWithGPIOHardware + state: id=3 label=active + command interfaces + joint1/position [available] [claimed] + joint2/position [available] [claimed] + flange_analog_IOs/analog_output1 [available] [claimed] + flange_vacuum/vacuum [available] [claimed] + + This shows that the custom hardware interface plugin is loaded and running. If you work on a real + robot and don't have a simulator running, it is often faster to use the ``mock_components/GenericSystem`` + hardware component instead of writing a custom one. Stop the launch file and start it again with + an additional parameter + + .. code-block:: shell + + ros2 launch ros2_control_demo_example_10 rrbot.launch.py use_mock_hardware:=True + + Calling ``list_hardware_components`` with the ``-v`` option + + .. code-block:: shell + + ros2 control list_hardware_components -v + + now should give you + + .. code-block:: shell + + Hardware Component 1 + name: RRBot + type: system + plugin name: mock_components/GenericSystem + state: id=3 label=active + command interfaces + joint1/position [available] [claimed] + joint2/position [available] [claimed] + flange_analog_IOs/analog_output1 [available] [claimed] + flange_vacuum/vacuum [available] [claimed] + state interfaces + joint1/position [available] + joint2/position [available] + flange_analog_IOs/analog_output1 [available] + flange_analog_IOs/analog_input1 [available] + flange_analog_IOs/analog_input2 [available] + flange_vacuum/vacuum [available] + + One can see that the plugin ``mock_components/GenericSystem`` was now loaded instead: It will mirror the command interfaces to state interfaces with identical name. Call + + .. code-block:: shell + + ros2 topic echo /gpio_controller/inputs + + again and you should see that - unless commands are received - the values of the state interfaces are now ``nan`` except for the vacuum interface. + + .. code-block:: shell + + interface_names: + - flange_analog_IOs/analog_output1 + - flange_analog_IOs/analog_input1 + - flange_analog_IOs/analog_input2 + - flange_vacuum/vacuum + values: + - .nan + - .nan + - .nan + - 1.0 + + This is, because for the vacuum interface an initial value of ``1.0`` is set in the URDF file. + + .. code-block:: xml + + + + + 1.0 + + + + Call again + + .. code-block:: shell + + ros2 topic pub /gpio_controller/commands std_msgs/msg/Float64MultiArray "{data: [0.5,0.7]}" + + and you will see that the GPIO command interfaces will be mirrored to their respective state interfaces. Files used for this demos ------------------------- @@ -104,7 +201,11 @@ Files used for this demos - RViz configuration: `rrbot.rviz `__ -- Hardware interface plugin: `rrbot.cpp `__ +- Hardware interface plugin: + + + `rrbot.cpp `__ + + `generic_system.cpp `__ + - GPIO controller: `gpio_controller.cpp `__