Rosanswers logo

I am trying to simulate my robot in Gazebo following the urdf tutorial found here to create an R2D2 model. The tutorial makes sense to me and I can successfully run it on my machine.

I tried to create my own model - a robot with left and right wheels in the center of a box and two casters on the front. I have modeled the casters as spheres setting the friction parameters to 0. The problem I am having is that my robot will only drive in the forward direction - it will not steer like the tutorial does. I am using the same rqt_robot_steering package to make the robot move but I cannot figure out why it does not turn. (Interesting side note - I copied the urdf tutorial files onto my machine and rant them in my bender_model package and was not successful in making R2D2 turn.)

All my code can be found on my github acount

I am running ROS Version: 1.12.12, Ubuntu 16.04 LTS, Gazebo 7.

I appreciate any help making my robot model turn!! I am not very good at ROS and out of ideas!!

I create my model from the model.urdf.xacro:

<?xml version="1.0"?>
<robot name="bender" xmlns:xacro="http://ros.org/wiki/xacro">

    <xacro:property name="pi" value="3.141592653589794" />
    <xacro:property name="base_len" value="0.89" />
    <xacro:property name="base_wid" value="0.80" />
    <xacro:property name="base_height" value="0.20" />
    <xacro:property name="caster_length" value="0.10" />
    <xacro:property name="caster_radius" value="0.15" />
    <xacro:property name="wheel_length" value="0.10" />
    <xacro:property name="wheel_radius" value="0.15" />
    <xacro:property name="update_rate" value="50"/>
    <xacro:property name="hokuyo_size" value="0.05"/>

    <xacro:macro name="default_inertial" params="mass">
          <mass value="${mass}" />
          <inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0" />

    <material name="white">
       <color rgba="1 1 1 1.5"/>

    <link name="base_link">
            <box size="${base_len} ${base_wid} ${base_height}"/>
          <material name="white"/>
              <box size="${base_len} ${base_wid} ${base_height}"/>
        <xacro:default_inertial mass="1"/>

    <xacro:macro name="caster" params="position reflect">
        <joint name="${position}_wheel_joint" type="fixed">
            <parent link="base_link"/>
            <child link="${position}_wheel"/>
            <axis xyz="0 0 1"/>
            <origin xyz="${reflect*(base_wid/2)} 0 ${-1 * base_height}" rpy="${pi/2} 0 0"/>
        <link name="${position}_wheel">
                    <sphere radius="${caster_radius}"/>
                <material name="white"/>
                  <sphere radius="${caster_radius}"/>
            <xacro:default_inertial mass="0.5"/>

<!-- This block provides the simulator (Gazebo) with information on a few additional
physical properties. See http://gazebosim.org/tutorials/?tut=ros_urdf for more-->
        <gazebo reference="${position}_wheel">
            <mu1 value = "0.0"/>
            <mu2 value = "0.0"/>
            <kp  value = "10000000.0"/>
            <kd  value = "1.0"/>

    <xacro:macro name="wheel" params="position reflect">
        <joint name="${position}_wheel_joint" type="continuous">
            <parent link="base_link"/>
            <child link="${position}_wheel"/>
            <axis xyz="0 0 1"/>
            <origin xyz="0 ${reflect*(base_wid/2)} ${-1*base_height}" rpy="${-pi/2} 0 0"/>
        <link name="${position}_wheel">
                    <cylinder length = "${wheel_length}" radius="${wheel_radius}"/>
                <material name="white"/>
                  <cylinder length = "${wheel_length}" radius="${wheel_radius}"/>
            <xacro:default_inertial mass="0.5"/>

<!-- This block provides the simulator (Gazebo) with information on a few additional
physical properties. See http://gazebosim.org/tutorials/?tut=ros_urdf for more-->
        <gazebo reference="${position}_wheel">
            <mu1 value = "200.0"/>
            <mu2 value = "100.0"/>
            <kp value="1000000.0" />
            <kd value="1.0" />
            <fdir1 value="1 0 0"/>

<!-- This block connects the wheel joint to an actuator (motor), which informs both
   simulation and visualization of the robot -->
       <transmission name="${position}_wheel_trans">
             <actuator name="${position}_wheel_motor">
         <joint name="${position}_wheel_joint">

    <xacro:caster position="front" reflect="1"/>
    <xacro:caster position="back"  reflect="-1"/>
    <xacro:wheel  position="right" reflect="1"/>
    <xacro:wheel  position="left"  reflect="-1"/>

 <!-- Gazebo plugin for ROS Control -->

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

<!-- Hokuyo Laser Senso -->
    <link name="hokuyo_link">
        <origin xyz="0 0 0" rpy="0 0 0" />
          <box size="${hokuyo_size} ${hokuyo_size} ${1.5*hokuyo_size}"/>
        <material name="Blue" />
    <joint name="hokuyo_joint" type="fixed">
      <origin xyz="${base_wid/2} 0 ${base_height+hokuyo_size/4}" rpy="0 0 0" />
      <parent link="base_link"/>
      <child link="hokuyo_link" />
    <gazebo reference="hokuyo_link">
      <sensor type="ray" name="head_hokuyo_sensor">
        <pose>${hokuyo_size/2} 0 0 0 0 0</pose>
        <plugin name="gazebo_ros_head_hokuyo_controller" filename="libgazebo_ros_laser.so">

I then configure with my file joints.yaml:

# specifying what ROS code we want to pass to the Gazebo simulator
# they are initially loaded into the ROS parameter space

type: "joint_state_controller/JointStateController"
publish_rate: 50

and my file diffdrive.yaml:

type: "diff_drive_controller/DiffDriveController"
publish_rate: 50

left_wheel: ['left_wheel_joint']
right_wheel: ['right_wheel_joint']

wheel_separation: 0.44

# Odometry covariances for the encoder output of the robot. These values should
# be tuned to your robot's sample odometry data, but these values are a good place
# to start
pose_covariance_diagonal: [0.001, 0.001, 0.001, 0.001, 0.001, 0.03]
twist_covariance_diagonal: [0.001, 0.001, 0.001, 0.001, 0.001, 0.03]

# Top level frame (link) of the robot description
base_frame_id: base_link

# Velocity and acceleration limits for the robot
    has_velocity_limits    : true
    max_velocity           : 5.0   # m/s
    has_acceleration_limits: true
    max_acceleration       : 0.6   # m/s^2
    has_velocity_limits    : true
    max_velocity           : 2.0   # rad/s
    has_acceleration_limits: true
max_acceleration           : 6.0 # rad/s^2

I launch with my launch file bender_simulation.launch:


    <arg name="model" default="$(find bender_model)/model.urdf.xacro"/>
    <arg name="gui" default="false" />
    <arg name="rvizconfig" default="$(find bender_model)/urdf.rviz"/>

    <include file="$(find bender_model)/gazebo.launch">
      <arg name="model" value="$(arg model)" />

    <node name="rviz" pkg="rviz" type="rviz" args="-d $(arg rvizconfig)" />

    <rosparam command="load"
              file="$(find bender_model)/joints.yaml"
              ns="bender_joint_state_controller" />

    <rosparam command="load"
              file="$(find bender_model)/diffdrive.yaml"
              ns="bender_diff_drive_controller" />

    <node name="bender_controller_spawner" pkg="controller_manager" type="spawner"
        output="screen" args="bender_joint_state_controller

    <node name="rqt_robot_steering" pkg="rqt_robot_steering" type="rqt_robot_steering">
      <param name="default_topic" value="/bender_diff_drive_controller/cmd_vel"/>


which uses the file gazebo.launch:


  <!-- these are the arguments you can pass this launch file, for example paused:=true -->
  <arg name="paused" default="false"/>
  <arg name="use_sim_time" default="true"/>
  <arg name="gui" default="true"/>
  <arg name="headless" default="false"/>
  <arg name="debug" default="false"/>
  <arg name="model" default="$(find bender_model)/model.urdf.xacro"/>

  <!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="debug" value="$(arg debug)" />
    <arg name="gui" value="$(arg gui)" />
    <arg name="paused" value="$(arg paused)"/>
    <arg name="use_sim_time" value="$(arg use_sim_time)"/>
    <arg name="headless" value="$(arg headless)"/>

  <param name="robot_description" command="$(find xacro)/xacro '$(find bender_model)/model.urdf.xacro'" />

  <!-- push robot_description to factory and spawn robot in gazebo -->
  <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model"
        args="-z 1.0 -unpause -urdf -model robot -param robot_description" respawn="false" output="screen" />

  <node pkg="robot_state_publisher" type="robot_state_publisher"  name="robot_state_publisher">
    <param name="publish_frequency" type="double" value="30.0" />

$ roslaunch bender_model bender_simulation.launch

I run the launch file using $ roslaunch bender_model bender_simulation.launch

and the terminal output is as follows:

... logging to /home/connor_fuhrman/.ros/log/964d2a16-1712-11e8-950e-4437e6440589/roslaunch-cmfuhrmanstation-14937.log
Checking log directory for disk usage. This may take awhile.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

xacro: Traditional processing is deprecated. Switch to --inorder processing!
To check for compatibility of your document, use option --check-order.
For more infos, see http://wiki.ros.org/xacro#Processing_Order
redefining global property: pi
when processing file: /home/connor_fuhrman/catkin_ws/src/bender_model/model.urdf.xacro
started roslaunch server http://cmfuhrmanstation:46313/


 * /bender_diff_drive_controller/angular/z/has_acceleration_limits: True
 * /bender_diff_drive_controller/angular/z/has_velocity_limits: True
 * /bender_diff_drive_controller/angular/z/max_velocity: 2.0
 * /bender_diff_drive_controller/base_frame_id: base_link
 * /bender_diff_drive_controller/left_wheel: ['left_wheel_joint']
 * /bender_diff_drive_controller/linear/x/has_acceleration_limits: True
 * /bender_diff_drive_controller/linear/x/has_velocity_limits: True
 * /bender_diff_drive_controller/linear/x/max_acceleration: 0.6
 * /bender_diff_drive_controller/linear/x/max_velocity: 5.0
 * /bender_diff_drive_controller/max_acceleration: 6.0
 * /bender_diff_drive_controller/pose_covariance_diagonal: [0.001, 0.001, 0....
 * /bender_diff_drive_controller/publish_rate: 50
 * /bender_diff_drive_controller/right_wheel: ['right_wheel_joi...
 * /bender_diff_drive_controller/twist_covariance_diagonal: [0.001, 0.001, 0....
 * /bender_diff_drive_controller/type: diff_drive_contro...
 * /bender_diff_drive_controller/wheel_separation: 0.44
 * /bender_joint_state_controller/publish_rate: 50
 * /bender_joint_state_controller/type: joint_state_contr...
 * /robot_description: <?xml version="1....
 * /robot_state_publisher/publish_frequency: 30.0
 * /rosdistro: kinetic
 * /rosversion: 1.12.12
 * /rqt_robot_steering/default_topic: /bender_diff_driv...
 * /use_sim_time: True

    bender_controller_spawner (controller_manager/spawner)
    gazebo (gazebo_ros/gzserver)
    gazebo_gui (gazebo_ros/gzclient)
    robot_state_publisher (robot_state_publisher/robot_state_publisher)
    rqt_robot_steering (rqt_robot_steering/rqt_robot_steering)
    rviz (rviz/rviz)
    urdf_spawner (gazebo_ros/spawn_model)

auto-starting new master
process[master]: started with pid [14952]

setting /run_id to 964d2a16-1712-11e8-950e-4437e6440589
process[rosout-1]: started with pid [14965]
started core service [/rosout]
process[gazebo-2]: started with pid [14968]
process[gazebo_gui-3]: started with pid [14970]
process[urdf_spawner-4]: started with pid [14972]
process[robot_state_publisher-5]: started with pid [14977]
process[rviz-6]: started with pid [14980]
process[bender_controller_spawner-7]: started with pid [14986]
process[rqt_robot_steering-8]: started with pid [14988]
[INFO] [1519222927.064274, 0.000000]: Controller Spawner: Waiting for service controller_manager/load_controller
[ INFO] [1519222933.224445442]: Finished loading Gazebo ROS API Plugin.
[ INFO] [1519222933.225102347]: waitForService: Service [/gazebo/set_physics_properties] has not been advertised, waiting...
[ INFO] [1519222934.242137149, 0.023000000]: waitForService: Service [/gazebo/set_physics_properties] is now available.
[ INFO] [1519222934.295122457, 0.071000000]: Physics dynamic reconfigure ready.
SpawnModel script started
[INFO] [1519222937.693263, 3.421000]: Loading model XML from ros parameter
[INFO] [1519222937.696414, 3.424000]: Waiting for service /gazebo/spawn_urdf_model
[INFO] [1519222937.698314, 3.427000]: Calling service /gazebo/spawn_urdf_model
[INFO] [1519222938.666068, 3.565000]: Spawn status: SpawnModel: Successfully spawned entity
[ INFO] [1519222938.687348418, 3.565000000]: Laser Plugin: Using the 'robotNamespace' param: '/'
[ INFO] [1519222938.687910135, 3.565000000]: Starting Laser Plugin (ns = /)
[ INFO] [1519222938.691877658, 3.565000000]: Laser Plugin (ns = /)  <tf_prefix_>, set to ""
[ INFO] [1519222938.865649200, 3.565000000]: Loading gazebo_ros_control plugin
[ INFO] [1519222938.866325335, 3.565000000]: Starting gazebo_ros_control plugin in namespace: /
[ INFO] [1519222938.873725108, 3.565000000]: gazebo_ros_control plugin is waiting for model URDF in parameter [robot_description] on the ROS param server.
[urdf_spawner-4] process has finished cleanly
log file: /home/connor_fuhrman/.ros/log/964d2a16-1712-11e8-950e-4437e6440589/urdf_spawner-4*.log
[ INFO] [1519222939.024847829, 3.565000000]: Loaded gazebo_ros_control.
[INFO] [1519222939.178346, 3.715000]: Controller Spawner: Waiting for service controller_manager/switch_controller
[INFO] [1519222939.180618, 3.717000]: Controller Spawner: Waiting for service controller_manager/unload_controller
[INFO] [1519222939.182938, 3.718000]: Loading controller: bender_joint_state_controller
[INFO] [1519222939.202153, 3.736000]: Loading controller: bender_diff_drive_controller
[ INFO] [1519222939.214286424, 3.749000000]: Controller state will be published at 50Hz.
[ INFO] [1519222939.215813319, 3.750000000]: Wheel separation will be multiplied by 1.
[ INFO] [1519222939.216600979, 3.751000000]: Wheel radius will be multiplied by 1.
[ INFO] [1519222939.217173222, 3.751000000]: Velocity rolling window size of 10.
[ INFO] [1519222939.219212369, 3.752000000]: Velocity commands will be considered old if they are older than 0.5s.
[ INFO] [1519222939.221002029, 3.752000000]: Allow mutiple cmd_vel publishers is enabled
[ INFO] [1519222939.223104828, 3.752000000]: Base frame_id set to base_link
[ INFO] [1519222939.223809388, 3.752000000]: Odometry frame_id set to odom
[ INFO] [1519222939.224924769, 3.752000000]: Publishing to tf is enabled
[ INFO] [1519222939.247336653, 3.783000000]: Odometry params : wheel separation 0.44, wheel radius 0.15
[ INFO] [1519222939.250525913, 3.786000000]: Adding left wheel with joint name: left_wheel_joint and right wheel with joint name: right_wheel_joint
[INFO] [1519222939.255988, 3.792000]: Controller Spawner: Loaded controllers: bender_joint_state_controller, bender_diff_drive_controller
[INFO] [1519222939.259439, 3.796000]: Started controllers: bender_joint_state_controller, bender_diff_drive_controller

This generates a Gazebo simulation, and rviz window, and the rqt_robot_steering window that allows my robot to move forward but not steer. The result of the launch file looks like this

Originally posted by cmfuhrman on ROS Answers with karma: 200 on 2018-02-21

Post score: 1


1 Answer 1


Rosanswers logo

Looks like a typo in your diffdrive.yaml:

    has_velocity_limits    : true
    max_velocity           : 2.0   # rad/s
    has_acceleration_limits: true
max_acceleration           : 6.0 # rad/s^2

See the last line, it is not indented into the angular->z namespace so DiffDriveController reads the default 0 for this value. Without acceleration there is of course no movement. Correct the indention to the same level as has_acceleration_limits and you should be able to turn.

Originally posted by Humpelstilzchen with karma: 1504 on 2018-02-21

This answer was ACCEPTED on the original site

Post score: 2

Original comments

Comment by cmfuhrman on 2018-02-21:
Sir, Thank you!! Indenting max_acceleration solved my problem!!


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.