Robotics StackExchange | Archived questions

How to make ROS differential drive robot move forward with teleop?

Hi. I'm new to ROS and Gazebo simulation. I tried to create a differential drive robot for various experiments such sa SLAM etc.

I have set my joint to rotate on the y-axis as setting them on x or z makes them move weird. But when I try to make my robot move forward using teleop, the wheels move vertically instead of horizontally.

Tried on Ubuntu 18.04 LTS, ROS Melodic, Gazebo 9 and 20.04 LTS, ROS Noetic, Gazebo 11

EDIT: Added yaml code

EDIT2: Added launch code

Here is the relevant part of my urdf:

 <link name="base_link">
 </link>

<joint name="base_joint" type="fixed">
    <parent link="base_link"/>
    <child link="chassis"/>
</joint>

<link name="chassis">

    <inertial>
        <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
        <mass value="25"/>
        <inertia ixx="3.002" ixy="0.0" ixz="0.0" iyy="4.011" iyz="0.0" izz="2.8465"/>
    </inertial>
    <visual name="chassis_visual">
        <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
        <geometry>
            <box size="0.962 0.664 1" />
        </geometry>
    </visual>
    <collision name="chassis_collision">
        <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
        <geometry>
            <box size="0.962 0.664 1" />
        </geometry>
    </collision>
</link>

<link name="front_left_wheel">
    <inertial>
        <origin xyz="0.3 0.232 -0.525" rpy="1.5707 0.0 0.0"/>
        <mass value="5"/>
        <inertia ixx="0.02" ixy="0.0" ixz="0.0" iyy="0.02" iyz="0.0" izz="0.02"/>
    </inertial>
   <visual name="front_left_wheel_visual">
        <origin xyz="0.3 0.232 -0.525" rpy="1.5707 0.0 0.0"/>
        <geometry>
            <cylinder radius="0.1" length="0.1"/>
        </geometry>
    </visual>
    <collision name="front_left_wheel_collision">
        <origin xyz="0.3 0.232 -0.525" rpy="1.5707 0.0 0.0"/>
        <geometry>
            <cylinder radius="0.1" length="0.1"/>
        </geometry>
    </collision>
</link>

<link name="front_right_wheel">
    <inertial>
        <origin xyz="0.3 -0.232 -0.525" rpy="1.5707 0.0 0.0"/>
        <mass value="5"/>
        <inertia ixx="0.02" ixy="0.0" ixz="0.0" iyy="0.02" iyz="0.0" izz="0.02"/>
    </inertial>
    <visual name="front_right_wheel_visual">
        <origin xyz="0.3 -0.232 -0.525" rpy="1.5707 0.0 0.0"/>
        <geometry>
            <cylinder radius="0.1" length="0.1"/>
        </geometry>
    </visual>
    <collision name="front_right_wheel_collision">
        <origin xyz="0.3 -0.232 -0.525" rpy="1.5707 0.0 0.0"/>
        <geometry>
            <cylinder radius="0.1" length="0.1"/>
        </geometry>
    </collision>
</link>

<link name="rear_left_wheel">
    <inertial>
        <origin xyz="-0.3 0.232 -0.525" rpy="1.5707 0.0 0.0"/>
        <mass value="5"/>
        <inertia ixx="0.02" ixy="0.0" ixz="0.0" iyy="0.02" iyz="0.0" izz="0.02"/>
    </inertial>
    <visual name="rear_left_wheel_visual">
        <origin xyz="-0.3 0.232 -0.525" rpy="1.5707 0.0 0.0"/>
        <geometry>
            <cylinder radius="0.1" length="0.1"/>
        </geometry>
    </visual>
    <collision name="rear_left_wheel_collision">
        <origin xyz="-0.3 0.232 -0.525" rpy="1.5707 0.0 0.0"/>
        <geometry>
            <cylinder radius="0.1" length="0.1"/>
        </geometry>
    </collision>
</link>

<link name="rear_right_wheel">
    <inertial>
        <origin xyz="-0.3 -0.232 -0.525" rpy="1.5707 0.0 0.0"/>
        <mass value="5"/>
        <inertia ixx="0.02" ixy="0.0" ixz="0.0" iyy="0.02" iyz="0.0" izz="0.02"/>
    </inertial>
    <visual name="rear_right_wheel_visual">
        <origin xyz="-0.3 -0.232 -0.525" rpy="1.5707 0.0 0.0"/>
        <geometry>
            <cylinder radius="0.1" length="0.1"/>
        </geometry>
    </visual>
    <collision name="rear_right_wheel_collision">
        <origin xyz="-0.3 -0.232 -0.525" rpy="1.5707 0.0 0.0"/>
        <geometry>
            <cylinder radius="0.1" length="0.1"/>
        </geometry>
    </collision>
</link>

<joint name="front_left_wheel_hinge" type="continuous">
    <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
    <parent link="chassis"/>
    <child link="front_left_wheel"/>
    <axis xyz="0.0 1.0 0.0"/>
    <limit effort="100" velocity="100"/>
</joint>

<joint name="front_right_wheel_hinge" type="continuous">
    <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
    <parent link="chassis"/>
    <child link="front_right_wheel"/>
    <axis xyz="0.0 1.0 0.0"/>
    <limit effort="100" velocity="100"/>
</joint>

<joint name="rear_left_wheel_hinge" type="fixed">
    <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
    <parent link="chassis"/>
    <child link="rear_left_wheel"/>
    <axis xyz="0.0 1.0 0.0"/>
    <dynamics friction="0.0" />
    <limit lower="0.0" upper="0.0" effort="100" velocity="100"/>
</joint>

<joint name="rear_right_wheel_hinge" type="fixed">
    <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
    <parent link="chassis"/>
    <child link="rear_right_wheel"/>
    <axis xyz="0.0 1.0 0.0"/>
    <dynamics friction="0.0" />
    <limit lower="0.0" upper="0.0" effort="100" velocity="100"/>
</joint>

<gazebo>
    <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
    <robotNamespace>/test_robot</robotNamespace> -->
    </plugin>
</gazebo>

<transmission name="chassis_to_front_left_wheel_transmission">
    <type>transmission_interface/SimpleTransmission</type>
    <actuator name="motor1">
        <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
        <mechanicalReduction>1</mechanicalReduction>
    </actuator>
    <joint name="front_left_wheel_hinge">
        <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
    </joint>
</transmission>

<transmission name="chassis_to_front_right_wheel_transmission">
    <type>transmission_interface/SimpleTransmission</type>
    <actuator name="motor2">
        <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
        <mechanicalReduction>1</mechanicalReduction>
    </actuator>
    <joint name="front_right_wheel_hinge">
        <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
    </joint>
</transmission>

<gazebo>
    <plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so">
        <updateRate>20</updateRate>
        <leftJoint>front_left_wheel_hinge</leftJoint>
        <rightJoint>front_right_wheel_hinge</rightJoint>
        <wheelSeparation>0.464</wheelSeparation>
        <wheelDiameter>0.2</wheelDiameter>
        <wheelAcceleration>1.0</wheelAcceleration>
        <wheelTorque>20</wheelTorque>
        <commandTopic>/test_robot/diff_drive_controller/cmd_vel</commandTopic>
        <odometryTopic>/test_robot/diff_drive_controller/odom</odometryTopic>
        <odometryFrame>/test_robot/diff_drive_controller/odom</odometryFrame>
        <robotBaseFrame>base_link</robotBaseFrame>
        <odometrySource>1</odometrySource>
        <publishWheelTF>true</publishWheelTF>
        <publishOdom>true</publishOdom>
        <publishWheelJointState>true</publishWheelJointState>
        <legacyMode>false</legacyMode>
    </plugin>
</gazebo>

Here is my yaml code:

test_robot:
  joint_state_controller:
    type: joint_state_controller/JointStateController
    publish_rate: 50

  diff_drive_controller:
    type        : "diff_drive_controller/DiffDriveController"
    left_wheel  : 'front_left_wheel_hinge'
    right_wheel : 'front_right_wheel_hinge'
    publish_rate: 50.0               # default: 50
    pose_covariance_diagonal : [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
    twist_covariance_diagonal: [0.0, 0.0, 0.0, 0.0, 0.0, 0.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 : 0.464
    wheel_radius : 0.1

    # 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: chassis #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

Here is the launch code:

 <launch>

  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" value="$(find test_robot_gazebo)/worlds/test_robot.world"/>
  </include>

  <node name="rviz" pkg="rviz" type="rviz" />

  <param name="robot_description" textfile="$(find test_robot_description)/model/test_robot.urdf" />

  <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-file $(find test_robot_description)/model/test_robot.urdf -urdf -z 1 -model test_robot" />

  <rosparam file="$(find test_robot_description)/config/diff_drive.yaml" command="load" />
  <node name="controller_spawner" pkg="controller_manager" type="spawner" respawn="false" output="screen" ns="/test_robot" args="joint_state_controller diff_drive_controller" />
    <remap from="/cmd_vel" to="/test_robot/diff_drive_controller/cmd_vel" />

  <rosparam file="$(find test_robot_description)/config/gazebo_ros_control_params.yaml" command="load"/>

  <arg name="gui" default="True" />
   <param name="use_gui" value="True"/>
   <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
   <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" respawn="false" output="screen" />
    <remap from="/joint_states" to="/test_robot/joint_states" />


</launch>

Asked by jcjmagno on 2020-12-15 23:21:12 UTC

Comments

is this a duplicate of your other question #q367681? If yes, please close this one and add additional information to the other question by editing it. Thank you.

Asked by mgruhler on 2020-12-16 03:57:55 UTC

Can you post your publisher code? Are you using twist messages or Float64? In other words, are you using the ros_control plugin or the differential plugin?

Asked by patrchri on 2020-12-16 11:51:42 UTC

Hi. I used this for teleop: http://wiki.ros.org/teleop_twist_keyboard I tried both ros_control and differential drive gazebo plugin When I set the joint axis to y, the wheels move upward instead of forward. When set to x, the wheels revolve around the robot vertically. When set to y, the wheels then move like a propeller.

Asked by jcjmagno on 2020-12-16 20:25:32 UTC

The joint axis of the wheels should be set to y. I see in your urdf file, you have the rear wheels as fixed joints. Have you checked if converting them to continuous will change the results? Also remove the parts regarding ros_control and try it step-by-step; firstly make the front differential to work.

Asked by patrchri on 2020-12-17 09:20:33 UTC

Hi. Thank you for your comments, really appreciate it. I tried changing the joints of the rear wheels to continuous and it didn't change the results. Also, I get warnings if I remove the ros control plugin so I just leave it in.

Asked by jcjmagno on 2020-12-17 20:05:30 UTC

What warning do you get? If you just want to use the differential plugin, ros_control could be removed.

Asked by patrchri on 2020-12-18 11:45:32 UTC

I get this warning: [WARN] [1608340560.795287, 11.265000]: Controller Spawner couldn't find the expected controller_manager ROS interface.

I just edited the post, added my launch file just in case it may help.

Asked by jcjmagno on 2020-12-18 20:20:16 UTC

Answers