[ROS Q&A] 126 – How to configure the differential drive ROS controller


Written by Ricardo Tellez



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.

  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_*
      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
      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"?>
    <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" />


Two errors are the spot when we are doing this. 

  1. The args for the controller should have the same name in the .yaml file which is “mobile_base_controller”
  2. 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:

  1. The left wheel and right wheel in the .yaml file should be the same as your robot’s URDF definition.
  2. 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">
  <joint name="wheel_left_joint">
  <actuator name="left_wheel_actuator">

<transmission name="right_wheel_transmission">
  <joint name="wheel_right_joint">
  <actuator name="right_wheel_actuator">


  <plugin name="gazebo_ros_control" filename="libgazebo_ros_contol.so">


Step4. Lanch again

It’s better to compile again and run:

cd ~/simulation_ws


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:

  1. The arg name of the controller node should be the same as in the controller configuration file.
  2. Don’t specify robot namespace if you are not using it.
  3. The joint name in the controller configuration file should be the same as the name in urdf
  4. The gazebo_ros_control plugin should also be added to the urdf file.
  5. 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.



▸ 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

Masterclass 2023 batch2 blog banner

Check Out These Related Posts


  1. Kai Chang

    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.

    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

    The whole file is here https://github.com/ROBOTIS-GIT/turtlebot3/blob/master/turtlebot3_description/urdf/turtlebot3_burger.gazebo.xacro


  2. Joshua Hughes

    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”

  3. stefano

    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.


Submit a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Pin It on Pinterest

Share This