How can I reduce drift in my robot's trajectory?
The Problem (TL;DR)
My robot used to travel in straight lines between point A and point B. Now it doesn’t. I want to figure out why and how I can make it do that again by forcing the local path planner to follow the global path as closely as possible. I've done my best to summarize the problem here, but if you don't want to read an essay skip to the solution to this ROS question where I've re-stated the problem more clearly, and the work-around.
The Problem (full explanation)
If a robot travels directly between two points and there are no obstacles in the way, then its trajectory between those points should be a perfectly straight line (in theory). My robot used to behave like this, as shown below:
And now it doesn't, it consistently follows a bowed/curved trajectory every time. The radius of the curve changes but otherwise the trajectory is identical. The final stretch back to the starting point also has a funny kink it. Example:
Now before I go any further, I do understand that this problem is largely aesthetic and doesn't matter. And I know that I could work around this by adding more goal points and breaking the longer lines down into a series of shorter ones. However the fact remains that I can't currently explain this behaviour and I'd like to solve the problem if only for my own education.
So I would like to correct this behaviour and answer a few questions
Here is all the relevant system information:
System Information
- OS: Ubuntu 14.04 (laptop), ROS Indigo Igloo (robot)
- Robot: Clearpath Robotics Jackal UGV (real, not simulated)
- Sensors: IMU, wheel encoders, high accuracy RTK GPS
Localization: package used is robot_localization. There are two instances of ekf_localization_node (local and global). IMU and encoder data is fused in the (local) /odom frame. IMU, encoder and GPS data is fused in the (global) /map frame - this is the frame /move_base uses for navigation. I can provide the specific launch files if requested.
The output from the global EKF is always accurate and doesn't drift. The local output accumulates error over time and tends to drift quite badly by the end of a run.
Navigation: I use the jackal_navigation package (version 2.2.2) to set up my navigation stack. I use the odom_navigation_demo.launch with the following parameter changes to local_base_planner and costmap_2d:
- xy_goal_tolerance increased to 0.35 m
- heading_scoring = true (false by default)
- Costmap size increased to 120x120 m
- All instances of any "global_frame" parameter have been changed to /map.
- All map (local and global) "update_frequency" parameters reduced from 20 Hz to 10 Hz
- Reduced "controller_frequency" and "planner_frequency" parameters from 20 HZ to 10 Hz
To the best of my knowledge, these are the only parameters that have changed between the two graphs shown above.
The full navigation parameter files are here
Currently, in all cases the global path is perfectly straight ...
Even though I cannot help you here, I'd like to give a big ThumbsUp for this nice problem description. IMO, the average question lately seems to be: "My robot is not working!!! What can I do?!?!?!"
So it is nice to read such a good problem description for a change! Thank you!
Its hard to say what your problem is, it could be so many different things. But the behavior your seeing can be caused by a constant force that the PID controller has to deal with, (like one of the motors being bad). You could put the robot up on blocks and test that all the wheels are still driven.
That's why its taking so long to debug. I've checked that all the wheels work, and they seem fine. But I think I've discovered what could be creating that constant force you mentioned - have a look at Update 1.
Most of the position estimators that I've worked with use the linear and angular velocity from odometry to propagate the previous position estimate to the new position estimate (and so the absolute heading from odometry is completely ignored)
So that's probably why the absolute odometry heading doesn't appear to be adversely affecting your EKF.
From the data, it looks like your robot drives slightly to the right when commanded to go straight. Maybe you need to re-tune the PID controllers now that the motors have worn in a bit?
You say is used to work and now it doesn't? Do you know what has changed between then and now?
Thanks very much for your help! I've addressed your comments in "Update 3"