diff_drive_controller ignores acceleration limits
Hello community,
I have a real 2-wheeled robot and use diff_drive_controller. I'm able to drive around using teleop. It seems to work so far. But I'm curious about max_jerk and max_acceleration setting as they are not used for some reason. I tried different values and now even very low values but it doesn't make any difference.
From my understanding, diff_drive_controller subscribes to /cmd_vel and translate this to separate commands for each joint(wheel).
So when the current linear velocity is 0m/s and I publish a message to /cmd_vel telling to set linear velocity to 1m/s, robot instantly drives whith this speed. If I switch between forward/backward with max velocity, it jumps around.
My assumption is that diff_drive_controller takes care of acceleration limits resulting in a smooth movement of robot. I tried different max_velocity values just for check and these are used by diff_drive_controller
Any ideas of what is wrong here?
hoverboard_joint_publisher:
type: "joint_state_controller/JointStateController"
publish_rate: 50
left_wheel : 'left_wheel'
right_wheel : 'right_wheel'
hoverboard_velocity_controller:
type : "diff_drive_controller/DiffDriveController"
left_wheel : 'left_wheel'
right_wheel : 'right_wheel'
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.32
wheel_radius : 0.0825
# 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.5
# Base frame_id
base_frame_id: base_footprint #default: base_link
allow_multiple_cmd_vel_publishers: true
odom_frame_id: '/raw_odom'
enable_odom_tf: false
# Velocity and acceleration limits
# Whenever a min_* is unspecified, default to -max_*
linear:
x:
has_velocity_limits : true
max_velocity : 0.5 # m/s
has_acceleration_limits: true
max_acceleration : 0.01 # m/s^2
has_jerk_limits : true
max_jerk : 0.001 # m/s^3
angular:
z:
has_velocity_limits : true # was true
max_velocity : 6.28 # rad/s
has_acceleration_limits: true # was true
max_acceleration : 1.04 # rad/s^2
has_jerk_limits : true
max_jerk : 3.14 # rad/s^3
This is how launch file looks like
<launch>
<rosparam file="$(find hoverboard_driver)/config/hardware.yaml" command="load"/>
<rosparam file="$(find hoverboard_driver)/config/controllers.yaml" command="load"/>
<!-- PS4 joypad -->
<remap from="/cmd_vel" to="/hoverboard_velocity_controller/cmd_vel"/>
<include file="$(find ds4_driver)/launch/ds4_twist.launch">
<arg name="dof" value="2"/>
<!--<arg name="topic" value="joy_vel"/> -->
</include>
<node name="hoverboard_driver" pkg="hoverboard_driver" type="hoverboard_driver" output="screen"/>
<node name="controller_spawner" pkg="controller_manager" type="spawner" respawn="false" output="screen" ns="/"
args="hoverboard_joint_publisher hoverboard_velocity_controller" />
</launch>
rostopic list:
ubuntu@ubuntu:~$ rostopic list
/hoverboard/battery_voltage
/hoverboard/left_wheel/cmd
/hoverboard/left_wheel/position
/hoverboard/left_wheel/velocity
/hoverboard/right_wheel/cmd
/hoverboard/right_wheel/position
/hoverboard/right_wheel/velocity
/hoverboard/temperature
/hoverboard_velocity_controller/cmd_vel
/hoverboard_velocity_controller/odom
/hoverboard_velocity_controller/parameter_descriptions
/hoverboard_velocity_controller/parameter_updates
/joint_states
/pid/left/parameter_descriptions
/pid/left/parameter_updates
/pid/right/parameter_descriptions
/pid/right/parameter_updates
/rosout
/rosout_agg
/tf
Here the output of /joint_state. At beginning, robots velocity is set to 0m/s and ...
The diff_drive_controller source files do contain code to limit the acceleration. What makes you think it is not being used when you are using the navigation stack? Is this simulation or a real robot? If you monitor the JointState, does that jump too?
Please edit your question and append the output from
rosnode list
.This is a real robot. If I send cmd_vel with linear velocity of 1m/s, robot immediately starts to run with this speed. I just publish this message either by console or joystick. Does acceleration limit only gets respected when used navigation stack? Right now, my robot is just some kind of RC car as you see.
Anything published to cmd_vel should have accel limits applied. You are correct that joint velocity should not jump up like that in a couple hundred milliseconds. What are
/pid/left
and/pid/right
? How have you configured them?I found a bug inside my main loop.
prev_time was only set outside the loop but never inside the loop. I added
prev_time = time
right before rate.sleep. It works now if I set acceleration very low (0.1 m/s²) but if I set it higher, it still accelerates slow and starts to oscilate afterwards by running forward, backward, forward, backward even if there is no /cmd_vel message is applied anymoreThis is my currend PID setting. The entire code has been developed by other people and I still try to understand how it works.
Good work figuring out that bug. That oscillation happens because the PID controller is not configured properly, so the velocity output to the motor is unstable. If it were me, as a starting point for the PID, I would set p=0.1, i=0, d=0. I have no way to determine what
f
should be; whoever did this hardware interface layer should have provided the proper value, which I suspect is based on what the motor wants to see at its input.