introlab / rtabmap_ros

RTAB-Map's ROS package.
http://wiki.ros.org/rtabmap_ros
BSD 3-Clause "New" or "Revised" License
952 stars 556 forks source link

How to get the current odometry correction tf (map -> odom) #960

Open hatem-darweesh opened 1 year ago

hatem-darweesh commented 1 year ago

Hello, I am using rgbd_odometry node to find initial odometry , and this is published as /odom . also the rgbd_node publish /tf between "odom" and "base_link" frame.

In the documentation, the rtabmap_ros node should output additional /tf which is the corrected odometry from rgbd_odometry node.

But when I visualize the tf_tree there is no "map" frame. only the "odom" -> "base_link".

My question is: How can I get the corrected odometry with respect to the "map" frame.

Thanks.

matlabbe commented 1 year ago

Did you start rtabmap_slam/rtabmap node? Is it outputting warnings that some topics are not received?

shrinivas96 commented 1 year ago

For me rtabmap_slam/rtabmap lauched without any warnings/errors. With view_frames, I can also see that there is a /map ->/odom published by /rtabmap/rtabamp. Does this mean that when I subscribe to /odom in this case, I am getting the corrected poses? Is this basically localisation (i.e. updating poses based on prediction-correction)?

Edit: I can see in this other post that "transform would change only on loop closures". So I guess this /odom is still the one being calculated by Gazebo, and some corrections based on loop closures? (I say Gazebo because rqt_graph shows that gazebo publishes the /odom topic.)

matlabbe commented 1 year ago

Gazebo would publish the topic /odom and the TF odom->base_link, which will change as soon as the robot is moving. rtabmap will publish TF map->odom, which will change only when a loop closure is detected.

farishajdarpasic commented 1 year ago

So, map->odom is only changed when a loop closure is detected, and publishing to the topic /rtabmap/localization_pose is only happening also when loop closure is detected.

So if I want to extract corrected position of the robot, I could use one of these two options:

  1. Use transformations odom->base_link and map->odom and from that get map->base_link
  2. Use data from /rtabmap/localization_pose topic when message is being published to this topic, and in between use data from /odom topic. Just for clarification, is this data from localization_pose like additional pose, or pose after fusing correction and prediction. What I mean is whether the localization_pose is like GPS or it is pose after fusing GPS and odometry?
matlabbe commented 1 year ago

In latest version, the new default is that /rtabmap/localization_pose is always published, unless pub_loc_pose_only_when_localizing is true.

Other option is to lookup transform map->base_link when receiving rtabmap/info message (at time in that message).

localization_pose is map->base_link in PoseWithCovariance topic type.

flabrosse commented 3 months ago

I just spent several days to try to figure out why rviz2 was either not displaying maps from rtabmap or not displaying parts of my robot. If selecting the global fixed frame as "odom", then everything about my robot is displayed, but not the maps. If I select "map" as the global fixed frame, then the maps are displayed but most of the rest is missing.

I then realised that this is because ROS cannot compute a transform from map to base_link because the time of the map to odom transform is always 0.1. I finally arrive here to realise that the transform is only updated upon loop closures.

I understand why this is done, but could the time of the transform be updated every time it is re-published? After all it is still considered as valid. At the moment, transforms from map to anything on the robot cannot be computed without allowing possibly extremely high time differences, and is a pain in rviz.

EDIT: just running an experiment, with the robot following a circular path. After a full rotation, the rtabmap viz tool shows regular loop closures being detected, but the time if the map->odom transform remains the same at 0.1.

flabrosse commented 3 months ago

Isn't the issue that ros::Time::now() (as I see in many places in the rtabmap-ros in ROS2 does not exist (or does not do what would be expected)? My understanding is that this should now be replaced with this->get_clock()->now(), as described here and here.

PS. I am guessing here that the now() I see everywhere in the ros2 branch resolves to ros::Time::now(). The default and most up to date master branch explicitly uses ros::Time::now().

matlabbe commented 3 months ago

For map->odom TF, the timestamp should updated (even in the future) and published at 20 Hz (default), with or without loop closures.

https://github.com/introlab/rtabmap_ros/blob/bfef9eed544ef5605cf22ce727584d4563a2e630/rtabmap_slam/src/CoreWrapper.cpp#L689-L697

We do use now() as suggested in https://answers.ros.org/question/287946/ros-2-time-handling/

If you are in simulation, make sure you start the node with use_sim_time:=true and that a clock is published.

EDIT: just saw you already fixed this issue in https://github.com/introlab/rtabmap_ros/issues/1158