From 5826ea371ab613d3d04fac7f28d2839bb46076ed Mon Sep 17 00:00:00 2001 From: Martin Pecka Date: Thu, 17 Apr 2025 05:02:00 +0200 Subject: [PATCH 1/2] Added example_17: chained controllers for diff drive using effort interface and Gazebo. Signed-off-by: Martin Pecka --- example_17/CMakeLists.txt | 22 ++ example_17/README.md | 5 + .../config/diffbot_chained_controllers.yaml | 85 +++++++ example_17/bringup/config/plotjuggler.xml | 72 ++++++ example_17/bringup/launch/demo_test.launch.py | 40 ++++ example_17/bringup/launch/demo_test_helper.py | 64 +++++ example_17/bringup/launch/diffbot.launch.py | 207 ++++++++++++++++ .../description/gazebo/diffbot.gazebo.xacro | 77 ++++++ .../description/launch/view_robot.launch.py | 114 +++++++++ .../ros2_control/diffbot.ros2_control.xacro | 26 ++ .../description/urdf/diffbot.urdf.xacro | 21 ++ example_17/doc/diffbot_velocities.png | Bin 0 -> 106853 bytes example_17/doc/userdoc.rst | 225 ++++++++++++++++++ example_17/package.xml | 44 ++++ example_17/test/test_diffbot_launch.py | 98 ++++++++ example_17/test/test_urdf_xacro.py | 77 ++++++ example_17/test/test_view_robot_launch.py | 54 +++++ .../urdf/diffbot_description.urdf.xacro | 4 +- 18 files changed, 1233 insertions(+), 2 deletions(-) create mode 100644 example_17/CMakeLists.txt create mode 100644 example_17/README.md create mode 100644 example_17/bringup/config/diffbot_chained_controllers.yaml create mode 100644 example_17/bringup/config/plotjuggler.xml create mode 100644 example_17/bringup/launch/demo_test.launch.py create mode 100644 example_17/bringup/launch/demo_test_helper.py create mode 100644 example_17/bringup/launch/diffbot.launch.py create mode 100644 example_17/description/gazebo/diffbot.gazebo.xacro create mode 100644 example_17/description/launch/view_robot.launch.py create mode 100644 example_17/description/ros2_control/diffbot.ros2_control.xacro create mode 100644 example_17/description/urdf/diffbot.urdf.xacro create mode 100644 example_17/doc/diffbot_velocities.png create mode 100644 example_17/doc/userdoc.rst create mode 100644 example_17/package.xml create mode 100644 example_17/test/test_diffbot_launch.py create mode 100644 example_17/test/test_urdf_xacro.py create mode 100644 example_17/test/test_view_robot_launch.py diff --git a/example_17/CMakeLists.txt b/example_17/CMakeLists.txt new file mode 100644 index 000000000..1efc53296 --- /dev/null +++ b/example_17/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.16) +project(ros2_control_demo_example_17) + +# INSTALL +install( + DIRECTORY description/gazebo description/launch description/ros2_control description/urdf + DESTINATION share/ros2_control_demo_example_17 +) +install( + DIRECTORY bringup/launch bringup/config + DESTINATION share/ros2_control_demo_example_17 +) + +if(BUILD_TESTING) + find_package(ament_cmake_pytest REQUIRED) + + ament_add_pytest_test(example_17_urdf_xacro test/test_urdf_xacro.py) + ament_add_pytest_test(view_example_17_launch test/test_view_robot_launch.py) + ament_add_pytest_test(run_example_17_launch test/test_diffbot_launch.py) +endif() + +ament_package() diff --git a/example_17/README.md b/example_17/README.md new file mode 100644 index 000000000..b83766bf6 --- /dev/null +++ b/example_17/README.md @@ -0,0 +1,5 @@ +# ros2_control_demo_example_17 + + *DiffBot*, or ''Differential Mobile Robot'', is a simple mobile base with differential drive. This example shows how to create chained controllers using diff_drive_controller and pid_controllers to control a differential drive robot using effort interface. + +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_17/doc/userdoc.html). diff --git a/example_17/bringup/config/diffbot_chained_controllers.yaml b/example_17/bringup/config/diffbot_chained_controllers.yaml new file mode 100644 index 000000000..53c971871 --- /dev/null +++ b/example_17/bringup/config/diffbot_chained_controllers.yaml @@ -0,0 +1,85 @@ +controller_manager: + ros__parameters: + use_sim_time: True # remove on real robots + update_rate: 100 # Hz + + joint_state_broadcaster: + type: joint_state_broadcaster/JointStateBroadcaster + + wheel_pids: + type: pid_controller/PidController + + diffbot_base_controller: + type: diff_drive_controller/DiffDriveController + +joint_state_broadcaster: + ros__parameters: + use_sim_time: True # remove on real robots + update_rate: 100 # Hz + +wheel_pids: + ros__parameters: + use_sim_time: True # remove on real robots + update_rate: 100 # Hz + + dof_names: + - left_wheel_joint + - right_wheel_joint + + command_interface: effort + + reference_and_state_interfaces: + - velocity + - effort + + gains: + # control the velocity through effort + left_wheel_joint: {"p": 0.1, "i": 1.0, "d": 0.0, "i_clamp_min": -20.0, "i_clamp_max": 20.0, "antiwindup": true, "feedforward_gain": 0.95} + right_wheel_joint: {"p": 0.1, "i": 1.0, "d": 0.0, "i_clamp_min": -20.0, "i_clamp_max": 20.0, "antiwindup": true, "feedforward_gain": 0.95} + +diffbot_base_controller: + ros__parameters: + use_sim_time: True # remove on real robots + update_rate: 100 # Hz + + left_wheel_names: ["wheel_pids/left_wheel_joint"] + right_wheel_names: ["wheel_pids/right_wheel_joint"] + + wheel_separation: 0.10 + wheel_radius: 0.015 + + # we have velocity feedback + position_feedback: false + + publish_rate: 50.0 + odom_frame_id: odom + base_frame_id: base_link + pose_covariance_diagonal : [0.001, 0.001, 0.001, 0.001, 0.001, 0.01] + twist_covariance_diagonal: [0.001, 0.001, 0.001, 0.001, 0.001, 0.01] + + open_loop: false + enable_odom_tf: true + + cmd_vel_timeout: 0.5 + publish_limited_velocity: true + + # Velocity and acceleration limits + # Whenever a min_* is unspecified, default to -max_* + linear.x.has_velocity_limits: true + linear.x.has_acceleration_limits: true + linear.x.has_jerk_limits: false + linear.x.max_velocity: 1.0 + linear.x.min_velocity: -1.0 + linear.x.max_acceleration: 1.0 + linear.x.max_jerk: .NAN + linear.x.min_jerk: .NAN + + angular.z.has_velocity_limits: true + angular.z.has_acceleration_limits: true + angular.z.has_jerk_limits: false + angular.z.max_velocity: 1.0 + angular.z.min_velocity: -1.0 + angular.z.max_acceleration: 1.0 + angular.z.min_acceleration: -1.0 + angular.z.max_jerk: .NAN + angular.z.min_jerk: .NAN diff --git a/example_17/bringup/config/plotjuggler.xml b/example_17/bringup/config/plotjuggler.xml new file mode 100644 index 000000000..b60278517 --- /dev/null +++ b/example_17/bringup/config/plotjuggler.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example_17/bringup/launch/demo_test.launch.py b/example_17/bringup/launch/demo_test.launch.py new file mode 100644 index 000000000..bab5f8f23 --- /dev/null +++ b/example_17/bringup/launch/demo_test.launch.py @@ -0,0 +1,40 @@ +# Copyright 2025 ros2_control Development Team +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from launch import LaunchDescription +from launch.substitutions import PathJoinSubstitution +from launch_ros.substitutions import FindPackageShare +from launch.actions import ExecuteProcess + + +def generate_launch_description(): + + return LaunchDescription( + [ + ExecuteProcess( + cmd=[ + "python3", + PathJoinSubstitution( + [ + FindPackageShare("ros2_control_demo_example_17"), + "launch", + "demo_test_helper.py", + ] + ), + ], + output="screen", + ) + ] + ) diff --git a/example_17/bringup/launch/demo_test_helper.py b/example_17/bringup/launch/demo_test_helper.py new file mode 100644 index 000000000..933d9de75 --- /dev/null +++ b/example_17/bringup/launch/demo_test_helper.py @@ -0,0 +1,64 @@ +# Copyright 2025 ros2_control Development Team +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import time +import rclpy +from rclpy.node import Node +from geometry_msgs.msg import TwistStamped +from std_srvs.srv import SetBool + + +class DiffbotChainedControllersTest(Node): + def __init__(self): + super().__init__("diffbot_chained_controllers_demo_helper_node") + # Enable feedforward control via service call + self.client_ = self.create_client(SetBool, "/wheel_pids/set_feedforward_control") + self.publisher_ = self.create_publisher(TwistStamped, "/cmd_vel", 10) + + def set_feedforward_control(self): + while not self.client_.wait_for_service(timeout_sec=1.0): + self.get_logger().info("Waiting for feedforward control service to be available...") + + request = SetBool.Request() + request.data = True + future = self.client_.call_async(request) + + rclpy.spin_until_future_complete(self, future) + + self.get_logger().info("Enabled feedforward control for both wheels.") + + def publish_cmd_vel(self, delay=0.1): + + twist_msg = TwistStamped() + twist_msg.twist.linear.x = 0.7 + twist_msg.twist.linear.y = 0.0 + twist_msg.twist.linear.z = 0.0 + twist_msg.twist.angular.x = 0.0 + twist_msg.twist.angular.y = 0.0 + twist_msg.twist.angular.z = 1.0 + + while rclpy.ok(): + self.get_logger().info(f"Publishing twist message to cmd_vel: {twist_msg}") + self.publisher_.publish(twist_msg) + time.sleep(delay) + + +if __name__ == "__main__": + rclpy.init() + test_node = DiffbotChainedControllersTest() + test_node.set_feedforward_control() + test_node.publish_cmd_vel(delay=0.1) + rclpy.spin(test_node) + test_node.destroy_node() + rclpy.shutdown() diff --git a/example_17/bringup/launch/diffbot.launch.py b/example_17/bringup/launch/diffbot.launch.py new file mode 100644 index 000000000..1fd0e9626 --- /dev/null +++ b/example_17/bringup/launch/diffbot.launch.py @@ -0,0 +1,207 @@ +# Copyright 2025 ros2_control Development Team +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, RegisterEventHandler, IncludeLaunchDescription +from launch.conditions import IfCondition, UnlessCondition +from launch.event_handlers import OnProcessExit +from launch.launch_description_sources import PythonLaunchDescriptionSource +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( + "gui", + default_value="true", + description="Start RViz2 automatically with this launch file.", + ) + ) + declared_arguments.append( + DeclareLaunchArgument( + "gazebo_gui", + default_value="true", + description="Whether to start Gazebo with GUI.", + ) + ) + declared_arguments.append( + DeclareLaunchArgument( + "fixed_frame_id", + default_value="odom", + description="Fixed frame id of the robot.", + ) + ) + + # Initialize Arguments + gui = LaunchConfiguration("gui") + gazebo_gui = LaunchConfiguration("gazebo_gui") + fixed_frame_id = LaunchConfiguration("fixed_frame_id") + + # gazebo + gazebo = IncludeLaunchDescription( + PythonLaunchDescriptionSource( + [FindPackageShare("ros_gz_sim"), "/launch/gz_sim.launch.py"] + ), + launch_arguments=[("gz_args", " -r -v 3 empty.sdf")], + condition=IfCondition(gazebo_gui), + ) + gazebo_headless = IncludeLaunchDescription( + PythonLaunchDescriptionSource( + [FindPackageShare("ros_gz_sim"), "/launch/gz_sim.launch.py"] + ), + launch_arguments=[("gz_args", ["--headless-rendering -s -r -v 3 empty.sdf"])], + condition=UnlessCondition(gazebo_gui), + ) + + # Gazebo bridge + gazebo_bridge = Node( + package="ros_gz_bridge", + executable="parameter_bridge", + arguments=["/clock@rosgraph_msgs/msg/Clock[gz.msgs.Clock"], + output="screen", + ) + + gz_spawn_entity = Node( + package="ros_gz_sim", + executable="create", + output="screen", + arguments=[ + "-topic", + "/robot_description", + "-name", + "diffdrive_robot", + "-z", + "0.02", + ], + ) + + # Get URDF via xacro + robot_description_content = Command( + [ + PathJoinSubstitution([FindExecutable(name="xacro")]), + " ", + PathJoinSubstitution( + [FindPackageShare("ros2_control_demo_example_17"), "urdf", "diffbot.urdf.xacro"] + ), + ] + ) + robot_description = {"robot_description": robot_description_content} + + robot_controllers = PathJoinSubstitution( + [ + FindPackageShare("ros2_control_demo_example_17"), + "config", + "diffbot_chained_controllers.yaml", + ] + ) + rviz_config_file = PathJoinSubstitution( + [FindPackageShare("ros2_control_demo_description"), "diffbot/rviz", "diffbot.rviz"] + ) + + robot_state_pub_node = Node( + package="robot_state_publisher", + executable="robot_state_publisher", + output="both", + parameters=[robot_description], + ) + + rviz_node = Node( + package="rviz2", + executable="rviz2", + name="rviz2", + output="log", + arguments=["-d", rviz_config_file, "-f", fixed_frame_id], + condition=IfCondition(gui), + ) + + joint_state_broadcaster_spawner = Node( + package="controller_manager", + executable="spawner", + arguments=[ + "joint_state_broadcaster", + "--param-file", + robot_controllers, + ], + ) + + pid_controllers_spawner = Node( + package="controller_manager", + executable="spawner", + arguments=[ + "wheel_pids", + "--param-file", + robot_controllers, + ], + ) + + robot_base_controller_spawner = Node( + package="controller_manager", + executable="spawner", + arguments=[ + "diffbot_base_controller", + "--param-file", + robot_controllers, + "--controller-ros-args", + "-r /diffbot_base_controller/cmd_vel:=/cmd_vel", + ], + ) + + # Delay rviz start after `joint_state_broadcaster` + delay_rviz_after_joint_state_broadcaster_spawner = RegisterEventHandler( + event_handler=OnProcessExit( + target_action=joint_state_broadcaster_spawner, + on_exit=[rviz_node], + ) + ) + + delay_robot_base_after_pid_controller_spawner = RegisterEventHandler( + event_handler=OnProcessExit( + target_action=pid_controllers_spawner, + on_exit=[robot_base_controller_spawner], + ) + ) + + # Delay start of joint_state_broadcaster after `robot_base_controller` + # TODO(anyone): This is a workaround for flaky tests. Remove when fixed. + delay_joint_state_broadcaster_after_robot_base_controller_spawner = RegisterEventHandler( + event_handler=OnProcessExit( + target_action=robot_base_controller_spawner, + on_exit=[joint_state_broadcaster_spawner], + ) + ) + + nodes = [ + gazebo, + gazebo_headless, + gazebo_bridge, + gz_spawn_entity, + robot_state_pub_node, + pid_controllers_spawner, + delay_robot_base_after_pid_controller_spawner, + delay_rviz_after_joint_state_broadcaster_spawner, + delay_joint_state_broadcaster_after_robot_base_controller_spawner, + ] + + return LaunchDescription(declared_arguments + nodes) diff --git a/example_17/description/gazebo/diffbot.gazebo.xacro b/example_17/description/gazebo/diffbot.gazebo.xacro new file mode 100644 index 000000000..06e786170 --- /dev/null +++ b/example_17/description/gazebo/diffbot.gazebo.xacro @@ -0,0 +1,77 @@ + + + + + + + + + $(find ros2_control_demo_example_17)/config/diffbot_chained_controllers.yaml + + + + + + + + + + + + + 1.0 + 1.0 + + + + + + + +:q! + + + + 1.0 + 1.0 + + + + + + + + 0.0 + 0.0 + + + + + + + + 0.0 + 0.0 + + + + + + + + diff --git a/example_17/description/launch/view_robot.launch.py b/example_17/description/launch/view_robot.launch.py new file mode 100644 index 000000000..66793b01c --- /dev/null +++ b/example_17/description/launch/view_robot.launch.py @@ -0,0 +1,114 @@ +# Copyright 2025 ros2_control Development Team +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch.conditions import IfCondition +from launch.substitutions import Command, FindExecutable, LaunchConfiguration, PathJoinSubstitution + +from launch_ros.actions import Node +from launch_ros.substitutions import FindPackageShare + + +def generate_launch_description(): + # Declare arguments + declared_arguments = [] + declared_arguments.append( + DeclareLaunchArgument( + "description_package", + default_value="ros2_control_demo_description", + description="Description package with robot URDF/xacro files. Usually the argument \ + is not set, it enables use of a custom description.", + ) + ) + declared_arguments.append( + DeclareLaunchArgument( + "description_file", + default_value="diffbot.urdf.xacro", + description="URDF/XACRO description file with the robot.", + ) + ) + declared_arguments.append( + DeclareLaunchArgument( + "gui", + default_value="true", + description="Start Rviz2 and Joint State Publisher gui automatically \ + with this launch file.", + ) + ) + declared_arguments.append( + DeclareLaunchArgument( + "prefix", + default_value='""', + description="Prefix of the joint names, useful for \ + multi-robot setup. If changed than also joint names in the controllers' configuration \ + have to be updated.", + ) + ) + + # Initialize Arguments + description_package = LaunchConfiguration("description_package") + description_file = LaunchConfiguration("description_file") + gui = LaunchConfiguration("gui") + prefix = LaunchConfiguration("prefix") + + # Get URDF via xacro + robot_description_content = Command( + [ + PathJoinSubstitution([FindExecutable(name="xacro")]), + " ", + PathJoinSubstitution( + [FindPackageShare("ros2_control_demo_example_17"), "urdf", description_file] + ), + " ", + "prefix:=", + prefix, + ] + ) + robot_description = {"robot_description": robot_description_content} + + rviz_config_file = PathJoinSubstitution( + [FindPackageShare(description_package), "diffbot/rviz", "diffbot_view.rviz"] + ) + + joint_state_publisher_node = Node( + package="joint_state_publisher_gui", + executable="joint_state_publisher_gui", + condition=IfCondition(gui), + ) + robot_state_publisher_node = Node( + package="robot_state_publisher", + executable="robot_state_publisher", + output="both", + parameters=[robot_description], + ) + + # start rviz2 with initial fixed frame id as base_link + rviz_node = Node( + package="rviz2", + executable="rviz2", + name="rviz2", + output="log", + arguments=["-d", rviz_config_file, "-f", "base_link"], + condition=IfCondition(gui), + ) + + nodes = [ + joint_state_publisher_node, + robot_state_publisher_node, + rviz_node, + ] + + return LaunchDescription(declared_arguments + nodes) diff --git a/example_17/description/ros2_control/diffbot.ros2_control.xacro b/example_17/description/ros2_control/diffbot.ros2_control.xacro new file mode 100644 index 000000000..11906e488 --- /dev/null +++ b/example_17/description/ros2_control/diffbot.ros2_control.xacro @@ -0,0 +1,26 @@ + + + + + + + + gz_ros2_control/GazeboSimSystem + + + + + + + + + + + + + + + + + + diff --git a/example_17/description/urdf/diffbot.urdf.xacro b/example_17/description/urdf/diffbot.urdf.xacro new file mode 100644 index 000000000..0a9661d63 --- /dev/null +++ b/example_17/description/urdf/diffbot.urdf.xacro @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/example_17/doc/diffbot_velocities.png b/example_17/doc/diffbot_velocities.png new file mode 100644 index 0000000000000000000000000000000000000000..33bae96ef6746407e8eb135e2839c9de5a6a20e8 GIT binary patch literal 106853 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%0A2)?%cOi(&%dO=tg~S@(kTMc_#py`$ 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 h_uH6?^ZqMvyn!iL6Jow1s&A0`47c2rg{JX literal 0 HcmV?d00001 diff --git a/example_17/doc/userdoc.rst b/example_17/doc/userdoc.rst new file mode 100644 index 000000000..6a9e8509a --- /dev/null +++ b/example_17/doc/userdoc.rst @@ -0,0 +1,225 @@ +:github_url: https://github.com/ros-controls/ros2_control_demos/blob/{REPOS_FILE_BRANCH}/example_17/doc/userdoc.rst + +.. _ros2_control_demos_example_17_userdoc: + +******************************************************** +DiffBot with Chained Controllers using effort interface. +******************************************************** + +This example shows how to create chained controllers using diff_drive_controller and pid_controllers to control a differential drive robot using effort interfaces. In contrast to *example_16* which uses velocity interface, control via effort interface is very suitable for simulation because it does not break physics (velocity-controlled objects are not affected by inertia etc.). If you haven't already, you can find the instructions for *example_16* in :ref:`ros2_control_demos_example_16_userdoc`. It is recommended to follow the steps given in that tutorial first before proceeding with this one. + +This example demonstrates controller chaining as described in :ref:`controller_chaining`. The control chain flows from the diff_drive_controller through two PID controllers to the DiffBot hardware. The diff_drive_controller converts desired robot twist into wheel velocity commands, which are then processed by the PID controllers to control the wheel motors' effort. Additionally, this example shows how to enable the feedforward mode for the PID controllers. + +Furthermore, this example shows how to use plotjuggler to visualize the controller states. + +The *DiffBot* URDF files can be found in ``description/urdf`` folder. + +.. include:: ../../doc/run_from_docker.rst + + +Tutorial steps +-------------------------- + +1. To start *DiffBot* example open a terminal, source your ROS2-workspace and execute its launch file with + + .. code-block:: shell + + ros2 launch ros2_control_demo_example_17 diffbot.launch.py + + The launch file loads and starts the robot hardware, controllers and opens *RViz* and *Gazebo GUI*. + In the starting terminal you will see output from the hardware implementation and simulator. + + If you can see an orange box in *RViz* and *Gazebo*, everything has started properly (the robot is pretty small, so make sure to zoom in on the robot in *Gazebo*). Let's introspect the control system before moving *DiffBot*. + +2. Check controllers + + .. code-block:: shell + + ros2 control list_controllers + + You should get + + .. code-block:: shell + + joint_state_broadcaster joint_state_broadcaster/JointStateBroadcaster active + diffbot_base_controller diff_drive_controller/DiffDriveController active + wheel_pids pid_controller/PidController active + + +3. Check the hardware interface loaded by opening another terminal and executing + + .. code-block:: shell + + ros2 control list_hardware_interfaces + + You should get + + .. code-block:: shell + + command interfaces + diffbot_base_controller/angular/velocity [available] [unclaimed] + diffbot_base_controller/linear/velocity [available] [unclaimed] + left_wheel_joint/effort [available] [claimed] + right_wheel_joint/effort [available] [claimed] + wheel_pids/left_wheel_joint/effort [available] [unclaimed] + wheel_pids/left_wheel_joint/velocity [available] [claimed] + wheel_pids/right_wheel_joint/effort [available] [unclaimed] + wheel_pids/right_wheel_joint/velocity [available] [claimed] + state interfaces + left_wheel_joint/effort + left_wheel_joint/position + left_wheel_joint/velocity + right_wheel_joint/effort + right_wheel_joint/position + right_wheel_joint/velocity + wheel_pids/left_wheel_joint/effort + wheel_pids/left_wheel_joint/velocity + wheel_pids/right_wheel_joint/effort + wheel_pids/right_wheel_joint/velocity + + + The ``[claimed]`` marker on command interfaces means that a controller has access to command *DiffBot*. There are two ``[claimed]`` interfaces from pid_controller, one for left wheel and one for right wheel. These interfaces are referenced by diff_drive_controller. By referencing them, diff_drive_controller can send commands to these interfaces. If you see these, we've successfully chained the controllers. + + There are also four ``[unclaimed]`` interfaces from diff_drive_controller, wheel_pids. You can ignore them since we don't use them in this example. + +4. We specified ``feedforward_gain`` as part of ``gains`` in diffbot_chained_controllers.yaml. To actually enable feedforward mode for the pid_controller, we need to use a service provided by pid_controller. Let's enable it. + + .. code-block:: shell + + ros2 service call /wheel_pids/set_feedforward_control std_srvs/srv/SetBool "data: true" + + You should get + + .. code-block:: shell + + response: + std_srvs.srv.SetBool_Response(success=True, message='') + +5. To see the pid_controller in action, let's subscribe to the controler_state topic, e.g. wheel_pids/controller_state topic. + + .. code-block:: shell + + ros2 topic echo /wheel_pids/controller_state + +6. Now we are ready to send a command to move the robot. Send a command to *Diff Drive Controller* by opening another terminal and executing + + .. code-block:: shell + + ros2 topic pub --rate 10 /cmd_vel geometry_msgs/msg/TwistStamped " + twist: + linear: + x: 0.7 + y: 0.0 + z: 0.0 + angular: + x: 0.0 + y: 0.0 + z: 1.0" + + You should now see robot is moving in circles in *RViz* and *Gazebo*. + +7. Let's go back to the terminal where we subscribed to the controller_state topic and see the changing states. + + .. code-block:: shell + + header: + stamp: + sec: 307 + nanosec: 909000000 + frame_id: '' + dof_states: + - name: left_wheel_joint + reference: 43.33333333333333 + feedback: 43.309162040088395 + feedback_dot: -0.00912764403084563 + error: 0.024171293244933167 + error_dot: .nan + time_step: 0.01 + output: 8.598921377572319 + - name: right_wheel_joint + reference: 50.0 + feedback: 50.029347324692814 + feedback_dot: 0.008966862676684506 + error: -0.029347324692814425 + error_dot: .nan + time_step: 0.01 + output: 10.067540181319677 + + +Visualize the convergence of DiffBot's wheel velocities and commands +--------------------------------------------------------------------- + +In the section below, we will use *plotjuggler* to observe the convergence of DiffBot's wheel velocities and commands from PID controllers. + +*plotjuggler* is an open-source data visualization tool and widely embraced by ROS2 community. If you don't have it installed, you can find the instructions from `plotjuggler website `__. + + +Before we proceed, we stop all previous steps from terminal and start from the beginning. + +1. To start *DiffBot* example open a terminal, source your ROS2-workspace and execute its launch file with + + .. code-block:: shell + + ros2 launch ros2_control_demo_example_17 diffbot.launch.py + + Like before, if you can see an orange box in *RViz*, everything has started properly. + +2. To start the plotjuggler with a provided layout file(plotjuggler.xml), open another terminal and run following command. + + .. code-block:: shell + + ros2 run plotjuggler plotjuggler --layout $(ros2 pkg prefix ros2_control_demo_example_17 --share)/config/plotjuggler.xml + + After this, you will see a few dialogs popping up. For example: + + .. code-block:: shell + + Start the previously used streaming plugin? + + ROS2 Topic Subscriber + + Click 'Yes' for the first dialog and 'OK" to the following two dialogs, then you will see the plotjuggler window. + +3. To enable feedforward mode and published a command to move the robot, instead of doing these manually, we will use the demo_test.launch.py. Open another terminal and execute + + .. code-block:: shell + + ros2 launch ros2_control_demo_example_17 demo_test.launch.py + +4. From the plotjuggler, you can see the controllers' states and commands being plotted, similar to following figure. From the figure, the DiffBot's wheel velocities and commands from PID controllers are converged to the target velocity fairly quickly. + + .. image:: diffbot_velocities.png + :width: 600 + :alt: Plotjuggler visualization of DiffBot velocities and commands + +5. Change the ``gains`` in the ``diffbot_chained_controllers.yaml`` file with some different values, repeat above steps and observe its effect to the pid_controller commands. For example, to change the ``feedforward_gain`` of the right wheel to 0.50, you can use the following command: + + .. code-block:: shell + + ros2 param set /wheel_pids gains.right_wheel_joint.feedforward_gain 0.50 + + +Files used for this demo +-------------------------- + +* Launch file: `diffbot.launch.py `__ +* Controllers yaml: `diffbot_chained_controllers.yaml `__ +* URDF file: `diffbot.urdf.xacro `__ + + * Description: `diffbot_description.urdf.xacro `__ + * ``ros2_control`` tag: `diffbot.ros2_control.xacro `__ + * ``gazebo`` tags: `diffbot.gazebo.xacro `__ + +* RViz configuration: `diffbot.rviz `__ + +* Demo helper utility: + + + demo test helper node: `demo_test_helper.py `__ + + demo test launch file: `demo_test.launch.py `__ + +Controllers from this demo +-------------------------- + +* ``Joint State Broadcaster`` (`ros2_controllers repository `__): :ref:`doc ` +* ``Diff Drive Controller`` (`ros2_controllers repository `__): :ref:`doc ` +* ``pid_controller`` (`ros2_controllers repository `__): :ref:`doc ` diff --git a/example_17/package.xml b/example_17/package.xml new file mode 100644 index 000000000..2c64ee5d4 --- /dev/null +++ b/example_17/package.xml @@ -0,0 +1,44 @@ + + + + ros2_control_demo_example_17 + 0.0.0 + Demo package of `ros2_control` hardware for DiffBot. + + Dr.-Ing. Denis Štogl + Bence Magyar + Christoph Froehlich + Sai Kishor Kothakota + + Apache-2.0 + + Martin Pecka + + ament_cmake + + controller_manager + diff_drive_controller + gz_ros2_control + joint_state_broadcaster + joint_state_publisher_gui + pid_controller + robot_state_publisher + ros2_control_demo_description + ros2_controllers_test_nodes + ros2controlcli + ros2launch + ros_gz_bridge + ros_gz_sim + rviz2 + xacro + + ament_cmake_pytest + launch_testing + launch + liburdfdom-tools + rclpy + + + ament_cmake + + diff --git a/example_17/test/test_diffbot_launch.py b/example_17/test/test_diffbot_launch.py new file mode 100644 index 000000000..4c7a25d74 --- /dev/null +++ b/example_17/test/test_diffbot_launch.py @@ -0,0 +1,98 @@ +# Copyright 2025 ros2_control Development Team +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import os + +import psutil +import pytest +import unittest + +from ament_index_python.packages import get_package_share_directory +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch_testing.actions import ReadyToTest + +import rclpy +from controller_manager.test_utils import ( + check_controllers_running, + check_if_js_published, + check_node_running, +) + + +# Executes the given launch file and checks if all nodes can be started +@pytest.mark.rostest +def generate_test_description(): + launch_include = IncludeLaunchDescription( + PythonLaunchDescriptionSource( + os.path.join( + get_package_share_directory("ros2_control_demo_example_17"), + "launch/diffbot.launch.py", + ) + ), + launch_arguments={"gui": "False", "gazebo_gui": "False"}.items(), + ) + + return LaunchDescription([launch_include, ReadyToTest()]) + + +# This is our test fixture. Each method is a test case. +# These run alongside the processes specified in generate_test_description() +class TestFixture(unittest.TestCase): + @classmethod + def setUpClass(cls): + rclpy.init() + + @classmethod + def tearDownClass(cls): + for proc in psutil.process_iter(): + # check whether the process name matches + if proc.name() == "ruby": + proc.kill() + if "gz sim" in proc.name(): + proc.kill() + rclpy.shutdown() + + def setUp(self): + self.node = rclpy.create_node("test_node") + + def tearDown(self): + self.node.destroy_node() + + def test_node_start(self, proc_output): + check_node_running(self.node, "robot_state_publisher") + + def test_controller_running(self, proc_output): + cnames = [ + "wheel_pids", + "diffbot_base_controller", + "joint_state_broadcaster", + ] + + check_controllers_running(self.node, cnames) + + def test_check_if_msgs_published(self): + check_if_js_published("/joint_states", ["left_wheel_joint", "right_wheel_joint"]) + + +# deactivating because gazebo returns -15 and does not stop properly +# @launch_testing.post_shutdown_test() +# # These tests are run after the processes in generate_test_description() have shutdown. +# class TestDescriptionCraneShutdown(unittest.TestCase): + +# def test_exit_codes(self, proc_info): +# """Check if the processes exited normally.""" +# launch_testing.asserts.assertExitCodes(proc_info) diff --git a/example_17/test/test_urdf_xacro.py b/example_17/test/test_urdf_xacro.py new file mode 100644 index 000000000..b3abe0ee8 --- /dev/null +++ b/example_17/test/test_urdf_xacro.py @@ -0,0 +1,77 @@ +# Copyright (c) 2022 FZI Forschungszentrum Informatik +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of the {copyright_holder} nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# Author: Lukas Sackewitz + +import os +import shutil +import subprocess +import tempfile + +from ament_index_python.packages import get_package_share_directory + + +def test_urdf_xacro(): + # General Arguments + description_package = "ros2_control_demo_example_17" + description_file = "diffbot.urdf.xacro" + + description_file_path = os.path.join( + get_package_share_directory(description_package), "urdf", description_file + ) + + (_, tmp_urdf_output_file) = tempfile.mkstemp(suffix=".urdf") + + # Compose `xacro` and `check_urdf` command + xacro_command = ( + f"{shutil.which('xacro')}" f" {description_file_path}" f" > {tmp_urdf_output_file}" + ) + check_urdf_command = f"{shutil.which('check_urdf')} {tmp_urdf_output_file}" + + # Try to call processes but finally remove the temp file + try: + xacro_process = subprocess.run( + xacro_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True + ) + + assert xacro_process.returncode == 0, " --- XACRO command failed ---" + + check_urdf_process = subprocess.run( + check_urdf_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True + ) + + assert ( + check_urdf_process.returncode == 0 + ), "\n --- URDF check failed! --- \nYour xacro does not unfold into a proper urdf robot description. Please check your xacro file." + + finally: + os.remove(tmp_urdf_output_file) + + +if __name__ == "__main__": + test_urdf_xacro() diff --git a/example_17/test/test_view_robot_launch.py b/example_17/test/test_view_robot_launch.py new file mode 100644 index 000000000..7d37de610 --- /dev/null +++ b/example_17/test/test_view_robot_launch.py @@ -0,0 +1,54 @@ +# Copyright (c) 2022 FZI Forschungszentrum Informatik +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of the {copyright_holder} nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# Author: Lukas Sackewitz + +import os +import pytest + +from ament_index_python.packages import get_package_share_directory +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch_testing.actions import ReadyToTest + + +# Executes the given launch file and checks if all nodes can be started +@pytest.mark.rostest +def generate_test_description(): + launch_include = IncludeLaunchDescription( + PythonLaunchDescriptionSource( + os.path.join( + get_package_share_directory("ros2_control_demo_example_17"), + "launch/view_robot.launch.py", + ) + ), + launch_arguments={"gui": "true"}.items(), + ) + + return LaunchDescription([launch_include, ReadyToTest()]) diff --git a/ros2_control_demo_description/diffbot/urdf/diffbot_description.urdf.xacro b/ros2_control_demo_description/diffbot/urdf/diffbot_description.urdf.xacro index a5be5c6ac..8af6ff52c 100644 --- a/ros2_control_demo_description/diffbot/urdf/diffbot_description.urdf.xacro +++ b/ros2_control_demo_description/diffbot/urdf/diffbot_description.urdf.xacro @@ -49,7 +49,7 @@ - + @@ -85,7 +85,7 @@ - + From 9e82b69468924143ccf3ab8b0af95fa59f07cb48 Mon Sep 17 00:00:00 2001 From: Martin Pecka Date: Thu, 17 Apr 2025 05:11:00 +0200 Subject: [PATCH 2/2] example_17: added to main readme. Signed-off-by: Martin Pecka --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 390feae4d..839a99a88 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,10 @@ The following examples are part of this demo repository: This example shows how to create chained controllers using diff_drive_controller and two pid_controllers to control a differential drive robot. +* Example 17: ["DiffBot with Chained Controllers using effort interface"](example_17) + + This example shows how to create chained controllers using diff_drive_controller and two pid_controllers to control a differential drive robot using effort interface. + ## Structure The repository is structured into `example_XY` folders that fully contained packages with names `ros2_control_demos_example_XY`.