In this video we are going to see how to configure the differential drive ROS controller for a wheeled robot using a Gazebo simulation.
This is a video trying to answer the question of Jaime posted at the ROS answers forum about how he cannot make the controller work, and receiving the error:
Controller Spawner couldn’t find the expected controller_manager ROS interface
Step1. Create Project
Let’s start with creating a new project in ROS development studio.
Notice: If you haven’t had an account yet. You can register one here for free.
Step2. Spawn a robot
As an example, we’ll use a self-build two-wheel differential drive robot.
You can test the code with your own robot with differential drive configuration.
Step3. Add the controller configuration file for your robot
Put the configuration file(e.g. the my_diff_drive.yaml file shows here) under the config folder, your source tree may look like this.
Let’s start by pasting the whole code from the question into the my_diff_drive.yaml file.
mobile_base_controller: type : "diff_drive_controller/DiffDriveController" left_wheel : 'wheel_left_joint' right_wheel : 'wheel_right_joint' publish_rate: 50.0 # default: 50 pose_covariance_diagonal : [0.001, 0.001, 1000000.0, 1000000.0, 1000000.0, 1000.0] twist_covariance_diagonal: [0.001, 0.001, 1000000.0, 1000000.0, 1000000.0, 1000.0] # Wheel separation and diameter. These are both optional. # diff_drive_controller will attempt to read either one or both from the # URDF if not specified as a parameter wheel_separation : 1.0 wheel_radius : 0.3 # Wheel separation and radius multipliers wheel_separation_multiplier: 1.0 # default: 1.0 wheel_radius_multiplier : 1.0 # default: 1.0 # Velocity commands timeout [s], default 0.5 cmd_vel_timeout: 0.25 # Base frame_id base_frame_id: base_footprint #default: base_link # Velocity and acceleration limits # Whenever a min_* is unspecified, default to -max_* linear: x: has_velocity_limits : true max_velocity : 1.0 # m/s min_velocity : -0.5 # m/s has_acceleration_limits: true max_acceleration : 0.8 # m/s^2 min_acceleration : -0.4 # m/s^2 has_jerk_limits : true max_jerk : 5.0 # m/s^3 angular: z: has_velocity_limits : true max_velocity : 1.7 # rad/s has_acceleration_limits: true max_acceleration : 1.5 # rad/s^2 has_jerk_limits : true max_jerk : 2.5 # rad/s^3
Step4. Create Launch file
For our case, the launch file should look something similar like this.
<?xml version="1.0" encoding="UTF-8"?> <launch> <param name="robot_description" command="cat '$(find two_wheels_description)/urdf/two_wheels.urdf'" /> <arg name="x" default="-2"/> <arg name="y" default="0"/> <arg name="z" default="0.1"/> <node name="mybot_spawn" pkg="gazebo_ros" type="spawn_model" output="screen" args="-urdf -param robot_description -model mybot -x $(arg x) -y $(arg y) -z $(arg z)" /> <rosparam file="$(find two_wheels_description)/config/my_diff_drive.yaml" command="load" /> <node name="SARA_controller manager" pkg="controller_manager" type="spawner" respawn="false" output="screen" args="mobile_base_controller" /> </launch>
NOTICE:
Two errors are the spot when we are doing this.
- The args for the controller should have the same name in the .yaml file which is “mobile_base_controller”
- According to the .yaml file, there is no namespace /robot here, so we don’t need to add this to the controller node.
Things to make sure:
- The left wheel and right wheel in the .yaml file should be the same as your robot’s URDF definition.
- The gazebo controller should be added to the URDF definition as well as the transmission tag which will be used for the gazebo controller. In our case, we add the following code in the .urdf to add gazebo control in it.
... <transmission name="left_wheel_transmission"> <type>transmission_interface/SimpleTransmission</type> <joint name="wheel_left_joint"> <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface> </joint> <actuator name="left_wheel_actuator"> <mechanicalReduction>7</mechanicalReduction> <hardwareInterface>VelocityJointInterface</hardwareInterface> </actuator> </transmission> <transmission name="right_wheel_transmission"> <type>transmission_interface/SimpleTransmission</type> <joint name="wheel_right_joint"> <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface> </joint> <actuator name="right_wheel_actuator"> <mechanicalReduction>7</mechanicalReduction> <hardwareInterface>VelocityJointInterface</hardwareInterface> </actuator> </transmission> ... <gazebo> <plugin name="gazebo_ros_control" filename="libgazebo_ros_contol.so"> </plugin> </gazebo>
Step4. Lanch again
It’s better to compile again and run:
cd ~/simulation_ws
catkin_make
source devel/setup.bash
roslaunch two_wheel_drscription question.launch
Then you can use
rostopic list
If you see the following topics, then your controller is up and run correctly.
Takeaway today:
- The arg name of the controller node should be the same as in the controller configuration file.
- Don’t specify robot namespace if you are not using it.
- The joint name in the controller configuration file should be the same as the name in urdf
- The gazebo_ros_control plugin should also be added to the urdf file.
- Remember to compile again before you run.
If you want to learn more about ROS control and how to build a two-wheel robot in ROS from scratch, please visit Robot Ignite Academy for more information.
// RELATED LINKS
▸ Original question: https://answers.ros.org/question/289561/help-to-run-diff_drive_controller/
▸ Robot Ignite Academy: https://goo.gl/pF81sN
▸ ROS Basics in 5 days (Python): https://goo.gl/HGPP1M
▸ ROS Basics in 5 days (C++): https://goo.gl/evXQCA
▸ ROS Development Studio: https://goo.gl/FzHTQU
hi, This is a very helpful video about ros_control using diff_drive.
I have a question about “libgazebo_ros_control.so” in URDF, because I check the turtlebot3’s URDF, it’s using “libgazebo_ros_diff_drive.so” instead this on in video.
What’s the difference between “libgazebo_ros_control.so” and “libgazebo_ros_diff_drive.so”?
The “libgazebo_ros_diff_drive.so” seems don’t need another config.yaml file to set up the “left_wheel”,”right_wheel”, “wheel_separation” and so on..
All the setting seems directly write in the URDF itself like these.
15
16
17 cmd_vel
18 odom
19 odom
20 base_footprint
21 false
22 true
23 false
24 100
25 wheel_left_joint
26 wheel_right_joint
27 0.160
28 0.066
29 1
30 10
31
32
The whole file is here https://github.com/ROBOTIS-GIT/turtlebot3/blob/master/turtlebot3_description/urdf/turtlebot3_burger.gazebo.xacro
Thanks
Hi Kai,
1. `libgazebo_ros_control.so` is a plugin that supports several controllers (effort, trajectory, velocity, diff drive, etc.,) listed here: https://github.com/ros-controls/ros_controllers including the `diff_drive_controller` (https://github.com/ros-controls/ros_controllers/tree/noetic-devel/diff_drive_controller)
2. `libgazebo_ros_diff_drive.so` is a plugin that only supports a differential drive controller; check the source file (https://github.com/ros-simulation/gazebo_ros_pkgs/blob/kinetic-devel/gazebo_plugins/src/gazebo_ros_diff_drive.cpp)
You can use either one (not both) of them on a differential drive robot. Both these plugins do the same thing: subscribe to the velocity commands from say a /move_base stack (/cmd_vel topic) and publish the Odometry (/odom topic). They also give you the transformation between the /odom frame and /base_link frame.
In this tutorial, only `libgazebo_ros_control.so` is explained. Note that the velocity and odometry topics are under the namespace of the controller (/mobile_base_controller/cmd_vel and /mobile_base_controller/odom). You have to remap the corresponding topic from and to /mpve_base to the same names.
I have the exact steps as given. But I am spawning multiple robots in the gazebo so I have changed the name robot_description. Because of this gazebo could not load this controller because still gazebo is searching for robot_descripton.
This guy is also has a similar problem.
https://answers.ros.org/question/217573/how-to-open-controller-manager-for-a-different-robot_description/
Is there any solution for this?
Your launch file contains a node named “SARA_controller manager”.
The space in this name is an illegal character.
Would suggest you change the name to “SARA_controller_manager”
How can I get this robot and their files in a rosject? I want to simulate in Gazebo the same robot and understand in details these kind of issues.
Thanks