Robotics StackExchange | Archived questions

Move base stay at max speed

Hi, I'm trying to use the navigation package for ros on a virtual robot in gazebo and I have some troubles.

(Using Ros-kinetic, move_base package, gmapping SLAM, diff drive control)

The problem seems to be that when the nav sends a linear x speed to cmd_vel, he never put it back to 0, so the robot rushes forward until he hit a wall (or fall over, depending on the max speed). I don't understand if that comes from the nav package (a bad config ? ) or from the controller package.

The path showed in rviz seems correct, and he tries to correct his trajectory when he goes too far, but he doesn't seem capable of slowing down or move backward. I am new on ros, and I don't really know where to look :/ I use everything in launch file and yaml config. (don't know how much I need to send, so tell me if you need more ) Thanks :)

dummy_navigation.launch :

include file="$(find dummy_description)/launch/amcl.launch.xml"
arg name="cmd_vel_topic" default="cmd_vel" 
arg name="odom_topic" default="/robot/odom_diffdrive"
arg name="move_forward_only" default="true"

node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen"

<param name="base_local_planner" value="dwa_local_planner/DWAPlannerROS"/>

<rosparam file="$(find dummy_description)/param/costmap_common_params.yaml" command="load" ns="global_costmap" />
<rosparam file="$(find dummy_description)/param/costmap_common_params.yaml" command="load" ns="local_costmap" />
<rosparam file="$(find dummy_description)/param/local_costmap_params.yaml" command="load"/>
<rosparam file="$(find dummy_description)/param/global_costmap_params.yaml" command="load"/>
<rosparam file="$(find dummy_description)/param/move_base_params.yaml" command="load"/>
<rosparam file="$(find dummy_description)/param/dwa_local_planner_params.yaml" command="load"/>
<remap from="cmd_vel" to="$(arg cmd_vel_topic)"/>
<remap from="odom" to="$(arg odom_topic)"/>
<param name="DWAPlannerROS/min_vel_x" value="0.0" if="$(arg move_forward_only)" />

dwalocalplanner DWAPlannerROS: maxvelx: 0.5 minvelx: -0.88

 max_vel_y: 0.0 # diff drive robot
 min_vel_y: 0.001 # diff drive robot
 max_trans_vel: 0.88
 min_trans_vel: -0.2
 max_rot_vel: 0.08
 min_rot_vel: -0.05

 acc_lim_x: 0.1
 acc_lim_y: 0.0
 acc_lim_theta: 0.01

 yaw_goal_tolerance: 0.15
 xy_goal_tolerance: 0.2

 sim_time: 5.0
 vx_samples: 8
 vy_samples: 0
 vtheta_samples: 2
 controller_frequency: 20.0

path_distance_bias: 32.0
goal_distance_bias: 20.0
occdist_scale: 0.02
forward_point_distance: 0.325
stop_time_buffer: 0.2
scaling_speed: 0.25
max_scaling_factor: 0.2
oscillation_reset_dist: 0.05

publish_traj_pc: true
publish_cost_grid_pc: true
 global_frame_id: odom

Diff driver inside xacro :

    <gazebo>
  <plugin name="diff_drive_controller" filename="libgazebo_ros_diff_drive.so">
    <commandTopic>cmd_vel</commandTopic>
    <odometryTopic>robot/odom_diffdrive</odometryTopic>
    <odometryFrame>odom</odometryFrame>
    <publishOdomTF>true</publishOdomTF>
    <robotBaseFrame>base_footprint</robotBaseFrame>
    <publishWheelTF>true</publishWheelTF>
    <publishTf>true</publishTf>
    <publishWheelJointState>true</publishWheelJointState>
    <legacyMode>false</legacyMode>
    <updateRate>30</updateRate>
    <leftJoint>wheel_left_join</leftJoint>
    <rightJoint>wheel_right_join</rightJoint>
    <wheelSeparation>0.386</wheelSeparation>
    <wheelDiameter>0.032</wheelDiameter>
    <wheelAcceleration>1</wheelAcceleration>
    <wheelTorque>10</wheelTorque>
    <rosDebugLevel>na</rosDebugLevel>
  </plugin>
</gazebo> 

robot_controle.yaml :

 robot:
# Publish all joint states -----------------------------------
joint_state_controller:
type: joint_state_controller/JointStateController
publish_rate: 50  

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 : 0.386
wheel_radius : 0.032

# 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 

# Velocity and acceleration limits
# Whenever a min_* is unspecified, default to -max_*
linear:
  x:
    has_velocity_limits    : true
    max_velocity           : 0.01  # m/s
    min_velocity           : -0.01 # m/s
    has_acceleration_limits: true
    max_acceleration       : 0.001  # m/s^2
    min_acceleration       : -0.001 # m/s^2
    has_jerk_limits        : true
    max_jerk               : 0.5  # m/s^3
angular:
  z:
    has_velocity_limits    : true
    max_velocity           : 0.02  # rad/s
    has_acceleration_limits: true
    max_acceleration       : 0.001  # rad/s^2
    min_acceleration       : -0.001  # rad/s^2
    has_jerk_limits        : true
    max_jerk               : 0.25  # rad/s^3

Edit : I remove the plugin gazebo diff drive, and add robot_localization

   <!-- Odom-IMU Extended Kalman Filter-->
<node pkg="robot_localization" type="ekf_localization_node" name="ekf_localization_odom" clear_params="true"> 
    <rosparam command="load" file="$(find dummy_description)/param/robot_localization_odom.yaml" />
</node>

Robotlocalizationodom.yaml :

frequency: 10

two_d_mode: true

odom0: /odom
odom0_config: [false, false, false,
           false, false, false,
           true, true, false,
           false, false, true,
           false, false, false]

odom0_differential: true

imu0: /imu/data
imu0_config: [false, false, false,
          false, false, true,
          false, false, false,
          false, false, true,
          false, false, false]

imu0_differential: true
imu0_relative: true 

odom_frame: odom
base_link_frame: base_footprint
world_frame: odom
publish_tf: true

process_noise_covariance: [0.05, 0,    0,    0,    0,    0,    0,     0,     0,    0,    0,    0,    0,    0,    0,
                       0,    0.05, 0,    0,    0,    0,    0,     0,     0,    0,    0,    0,    0,    0,    0,
                       0,    0,    0.06, 0,    0,    0,    0,     0,     0,    0,    0,    0,    0,    0,    0,
                       0,    0,    0,    0.03, 0,    0,    0,     0,     0,    0,    0,    0,    0,    0,    0,
                       0,    0,    0,    0,    0.03, 0,    0,     0,     0,    0,    0,    0,    0,    0,    0,
                       0,    0,    0,    0,    0,    0.06, 0,     0,     0,    0,    0,    0,    0,    0,    0,
                       0,    0,    0,    0,    0,    0,    0.025, 0,     0,    0,    0,    0,    0,    0,    0,
                       0,    0,    0,    0,    0,    0,    0,     0.025, 0,    0,    0,    0,    0,    0,    0,
                       0,    0,    0,    0,    0,    0,    0,     0,     0.04, 0,    0,    0,    0,    0,    0,
                       0,    0,    0,    0,    0,    0,    0,     0,     0,    0.01, 0,    0,    0,    0,    0,
                       0,    0,    0,    0,    0,    0,    0,     0,     0,    0,    0.01, 0,    0,    0,    0,
                       0,    0,    0,    0,    0,    0,    0,     0,     0,    0,    0,    0.02, 0,    0,    0,
                       0,    0,    0,    0,    0,    0,    0,     0,     0,    0,    0,    0,    0.01, 0,    0,
                       0,    0,    0,    0,    0,    0,    0,     0,     0,    0,    0,    0,    0,    0.01, 0,
                       0,    0,    0,    0,    0,    0,    0,     0,     0,    0,    0,    0,    0,    0,    0.015]

initial_estimate_covariance: [1e-9, 0,    0,    0,    0,    0,    0,    0,    0,    0,     0,     0,     0,    0,    0,
                          0,    1e-9, 0,    0,    0,    0,    0,    0,    0,    0,     0,     0,     0,    0,    0,
                          0,    0,    1e-9, 0,    0,    0,    0,    0,    0,    0,     0,     0,     0,    0,    0,
                          0,    0,    0,    1e-9, 0,    0,    0,    0,    0,    0,     0,     0,     0,    0,    0,
                          0,    0,    0,    0,    1e-9, 0,    0,    0,    0,    0,     0,     0,     0,    0,    0,
                          0,    0,    0,    0,    0,    1e-9, 0,    0,    0,    0,     0,     0,     0,    0,    0,
                          0,    0,    0,    0,    0,    0,    1e-9, 0,    0,    0,     0,     0,     0,    0,    0,
                          0,    0,    0,    0,    0,    0,    0,    1e-9, 0,    0,     0,     0,     0,    0,    0,
                          0,    0,    0,    0,    0,    0,    0,    0,    1e-9, 0,     0,     0,     0,    0,    0,
                          0,    0,    0,    0,    0,    0,    0,    0,    0,    1e-9,  0,     0,     0,    0,    0,
                          0,    0,    0,    0,    0,    0,    0,    0,    0,    0,     1e-9,  0,     0,    0,    0,
                          0,    0,    0,    0,    0,    0,    0,    0,    0,    0,     0,     1e-9,  0,    0,    0,
                          0,    0,    0,    0,    0,    0,    0,    0,    0,    0,     0,     0,     1e-9, 0,    0,
                          0,    0,    0,    0,    0,    0,    0,    0,    0,    0,     0,     0,     0,    1e-9, 0,
                          0,    0,    0,    0,    0,    0,    0,    0,    0,    0,     0,     0,     0,    0,    1e-9]

But now the robot isn't responsive to cmd_vel, and I don't know where I got it wrong. I added to my xacro file :

  <!-- transmission -->
<transmission name="wheel_${name}_transmission">
  <type>transmission_interface/SimpleTransmission</type>
  <joint name="wheel_${name}_joint">
    <hardwareInterface>VelocityJointInterface</hardwareInterface>
  </joint>
  <actuator name="wheel_${name}_motor">
    <mechanicalReduction>1</mechanicalReduction>
  </actuator>
</transmission>

And following the code of jackas I added a twist_mux.yaml :

topics:
- name    : external
 topic   : cmd_vel
 timeout : 0.5
 priority: 1
 locks:
- name    : e_stop
  topic   : e_stop
  timeout : 0.0
  priority: 255

But I am not really sure that's useful (or exactly what this do. Put a timeout on cmd_vel to limit the speed ? )

Asked by Jérémy_Synergize on 2019-10-10 04:11:36 UTC

Comments

Why do you need the diff_drive_controller if you are using move_base? Also how are you giving goals?
Try using only move_base. The computed cmd_vels should come only from the local_planner DWAPlannerROS.

Asked by pavel92 on 2019-10-10 04:57:01 UTC

I give a goal with rviz. The diff_drive_controller is the one creating Odom, without that don't work :/

Where should odom be generate if the diff drive is replaced by move base? And I'm not sure if I have a DWAPlannerROS, is it inside the move_base or did I need to add it somewhere else?

Thanks for your help.

Asked by Jérémy_Synergize on 2019-10-10 05:17:45 UTC

Which robot are you using? I am not sure if you can use diff_drive_controller as odometry provider for the navigation stack.You should receive odometry from localization. From what you have posted I can see that you are using amcl. You can also check robot_localization package.
jackal_navigation also gives a good example for navigation configuration for a diff drive robot.

Asked by pavel92 on 2019-10-10 05:51:53 UTC

I will try with the packages you mention and I will come back to you. The robot is a self-made, with 2 wheels, 2 balls (for balance), and (for now ) one lidar. Because his structure is similar I based a lot of my try on the turtlebot.

Asked by Jérémy_Synergize on 2019-10-10 06:45:32 UTC

I added robot_localization and it seems to work, (I got an odom, and the position looks correct), but I am not able to move the robot anymore (I guess the diff drive was the one doing all the work. ), how I'm supposed to have move_base actually set to move the robot ? Did the "mobile_base_controller" in my robot_control.yaml is still useful or was its link to the gazebo plugin?

Asked by Jérémy_Synergize on 2019-10-10 08:01:06 UTC

I would not use the robot controllers (diff_drive_controller) at all. The local planner from move_base should compute the cmd_vels. Make sure you revert the remap from:

arg name="odom_topic" default="/robot/odom_diffdrive"

Asked by pavel92 on 2019-10-10 08:25:12 UTC

I would not use the robot controllers (diff_drive_controller) at all.

@pavel92: which node would be responsible for converting Twists into wheel velocities then?

Asked by gvdhoorn on 2019-10-10 08:26:36 UTC

My move_base sends the cmd_vel , but I have nothing to translate then and make the robot move. I think I forget to add something obvious which does this.

Asked by Jérémy_Synergize on 2019-10-10 08:31:43 UTC

I expressed myself quite bad, I meant to say not to publish directly to the controller and bypass move_base . Of course you need the controller in the end, either diff_drive_controller/DiffDriveController or you can try writing your own custom PID controller if you have the time. If you can make sure that the controller is receiving the cmd_vel then the problem probably lies in the controller config since you are dealing with a custom made robot

Asked by pavel92 on 2019-10-10 09:11:37 UTC

Try to use the jackal's controller config for reference

Asked by pavel92 on 2019-10-10 09:13:59 UTC

Please note: the OP already has libgazebo_ros_diff_drive.so, not ros_control, so diff_drive_controller would not work / be loaded.

Asked by gvdhoorn on 2019-10-10 09:15:07 UTC

And following the code of jackas I added [..]

made me smile .. ;)

Asked by gvdhoorn on 2019-10-10 11:32:57 UTC

Answers