Hi Patrick,
I set the
robot_base_frame: /base_footprint
parameter in local_costmap_params.yaml and global_costmap_params.yaml (and any other nodes that need to use this frame)
to tell the planner etc to use the base_footprint.
The rational for this is as follows:
The frames used in navigation are map->odom->base_...
As I am working in 2D it is simpler to keep everything planar and attached to the ground, so keeping map, odom and base_... with z=0 makes this simple.
Since base_link is supposed to be the main reference point on the robot, I like to think of this as independent of what I am doing with the robot, so the robot model could be used in other ways and this would still be a useful point.
Therefore I set base_link as the center of the axle and at a height at the center of the wheel.
This is then a useful reference for any rotation, around Z or to rotate the robot in roll or pitch if I was going beyond 2D.
However this now means that base_link frame no longer has z=0 when the robot is on the ground, so I add another virtual frame called base_footprint below base_link so that base_footprint does have z=0 when the robot wheels are on the ground.
Then by telling all of the nav nodes to use base_footprint as the robot_base_frame it means all the nav stuff happens with z=0 and then the robot just sits above the base_footprint and follows it around due to the base_footprint -> base_link tf.
A note on Transforms and publishers:
Ok so where do the TFs for all this come from:
First the easy simple version ( yea- like anything is easy and simple in ROS - LOL):
map = global frame (root of TF tree)
map-> odom : this is generated by gmaping or amcl (or what ever nav or mapping nodes you are using).
If you are not doing mapping or nav and just tele-op, ignore map, then odom becomes the root of TF tree.
odom->base_... : This is usually created by the base driver node, for most simple robots this is based on the wheel odometry, the origin=0,0,0 is just the starting position of the robot, the x,y,z, roll,pitch,yaw are then just integrated from the wheel odometry based on dead reckoning.
Generating odom->base_... is simpler if base_... has z=0, then just the x,y cords need to be generated, and the z rotation is around the base_... frame z axis, this is a good reason for using base_footprint if base_link does not have z=0 when the robot is on the ground.
base_footprint->base_link : this can be in the URDF or just a static_transform_publisher in a launch file.
base_link-> <rest of robot> : usually defined in URDF
Note: to publish TFs for the joints in the URDF use the robot_state_publisher node.
Now the more complex version I know some people are starting to try:
To get more complex some robots are now using IMUs and GPS, this changes how things get done.
IMU:
First to use an IMU it is common to use the robot_localization package to integrate it with the odometry, this changes how odom->base_... gets published.
odom->base_... : now gets published by the robot_localization node, so the base_driver must be told to not publish this TF anymore, most drivers have a param that can tell it to stop publishing the odom tf. Base driver still publishes an odom message (but now to odom_raw topic, not odom) and the robot_localization node gets this and the imu messages, integrates them and generates a new filtered odom message and the odom->base_... TF.
All of the nav, tele-op etc nodes need to make sure they are now also listening/publishing to the new correct set of topics and TF frames.
GPS:
using a GPS changes how the map->odom tf gets published, it requires a second instance of the robot_localization node (assuming you are already using one to integrate an IMU).
I will not go into to much detail as I have never done this so don't want to miss lead anyone. I have not looked at how this is used in conjunction with other mapping or nav nodes.
Other Notes on robot_localization:
Using the robot_localization node is really a big step in complexity for your robot. As well as the TF related changes noted above the node really only works properly if the data in the messages and the params set on the robot_localization nodes are properly configured including proper and meaningful sensor data co-variance matrices.
Without this data you will probably get worse results than not using the data at all.
You can try to guess these values - put small values ~ 0.01 etc on the diagonal elements of these matrices - but your results may vary.
It is best to actually perform measurements of the variance of each param (at least the ones you are using) and use these.
I think it is this part that makes this hard for most novices (myself included) and is beyond the scope of this message. Probably best left for another advanced training class from SV-ROS.
I hope this will help some of you that are working on this - most likely I have just confused you more, sorry - thats just the way ROS is 8>), good luck.
Ralph