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 usingmove_base
? Also how are you giving goals?Try using only
move_base
. The computedcmd_vels
should come only from the local_plannerDWAPlannerROS
.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:
Asked by pavel92 on 2019-10-10 08:25:12 UTC
@pavel92: which node would be responsible for converting
Twist
s 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, eitherdiff_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 thecmd_vel
then the problem probably lies in the controller config since you are dealing with a custom made robotAsked 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
, notros_control
, sodiff_drive_controller
would not work / be loaded.Asked by gvdhoorn on 2019-10-10 09:15:07 UTC
made me smile .. ;)
Asked by gvdhoorn on 2019-10-10 11:32:57 UTC