This week was all about getting the robot to move sideways using different local planners. In my last update, although I had not completely fine-tuned all move_base parameters, I was sufficiently happy about its initial performance. I used Base Local Planner plugin as a local planner, and despite trying everything, the robot only moved in 2 degrees of freedom (x direction, and rotation around z). I really wanted to try the robot to plan a smooth, holonomic local path, but as you can see in this video, the robot only moves in a holonomic fashion (3 degrees of freedom) when extremely close to obstacles. The base_local_planner package implements local trajectory planning in two flavors: Trajectory Rollout and Dynamic Window Approach (DWA), and I had chosen to use the DWA method. As per the base_local_planner wiki, the DWA method differs from Trajectory Rollout in how the robot’s control space is sampled. DWA is much more computationally efficient because samples from a set of achievable velocities for a single simulation step, unlike Trajectory Rollout which samples velocities in the entire forward simulation period. Unfortunately, the base_local_planner mostly supports velocity and acceleration constraints specified in the x direction (linear) and theta around the z axis (angular) and only considers strafing when no valid trajectories are found.
This is where DWA Local Planner comes in. This local planner implements the same DWA method from the base_local_planner but fully supports velocity/acceleration constraints in x, y directions and around the z axis. This makes it a really good choice for holonomic motion planning. The code itself is quite easy to understand, especially for a non-expert. So I decided to try it out. I created a new config file called dwa_local_planner_params.yaml, reused shared parameters from the base_local_planner_params.yaml and quickly configured the dwa_local_planner specific params. The results were quite spectacular, especially for the first try. In this video, robot is following the same path as the behavior tree example in my last post, but using the dwa_local_planner in a holonomic fashion.
Once the dwa_local_planner was working, I updated the move_base launch file with an argument which now makes it easy to define which local planner to use and to switch between base_local_planner (differential mode) and dwa_local_planner (holonomic mode) at startup accordingly. I also decided to try an alternative local planner called TEB Local Planner. This is a plugin developed at TU Dortmund and implements a method called Timed Elastic Band which “locally optimizes the robot’s trajectory with respect to trajectory execution time, separation from obstacles and compliance with kinodynamic constraints at runtime”. The ROS package is quite well maintained, easy to understand and comes with a tutorials package with examples of everything this plugin has to offer. These tutorials are definitely a great way to get started with this planner.
Unfortunately, and despite being able to successfully do all the tutorials, I was unable to get move_base running. For some reason there was no local plan generated. I still need to investigate this issue, but from first impressions, TEB Local Planner definitely seems to be the way to go. Especially because of its dynamic obstacle avoidance features. The plugin does seem to take up a lot of computational power though, and its possible this is why its not working on my Raspberry Pi 4.
For the time being, I am definitely satisfied with the base_local_planner and dwa_local_planner implementations and my next steps will definitely be to fine tune these plugins, as well as the global planner, in order to optimize the move_base performance. But first, next week is ROS World 2021! I’m quite excited to attend the sessions and also (virtually) meet friends and acquaintances in the ROS/robotics world. I’m also very eager to learn about ROS2 simulations and Unity in the pre-conference workshops. HMU if you’ll also be there!