Rosanswers logo

Could you tell me how to broadcast a transform between map and odom?

I'm trying to use a navigation stack.
I know I need to setup some tf publishers.

First, I made a node to publish a static transform between base_link and base_laser.
Second, a node to publish a transform between odom and base_link was made
with odometry sensor(encoder) data.

Third, I need to publish a transform between map and odom ...
But how?
The transform will be published with ... what?

If possible, could you tell me how to broadcast the transform
when making a map and using the navigation stack respectively.

Thanks in advance.

Originally posted by moyashi on ROS Answers with karma: 721 on 2012-09-26

Post score: 3


3 Answers 3


Rosanswers logo

The transform odom -> base_link represents the pose of the robot calculated from the robot's wheel encoders. Odometry generally will drift, i.e. the longer the robot drives around, the further away will the odometry transform be from the actual pose of the robot. To fix this, you normally run some sensor based self-localization node (normally using laser sensors). In ROS, the most commonly used nodes for localization are gmapping if you want to build a map and amcl if you want to use an existing map. Both publish the map -> odom transform and by requesting the tranform map -> base_link, you can get the position of the robot in the map. This tutorial might be helpful.

Originally posted by Lorenz with karma: 22731 on 2012-09-26

This answer was ACCEPTED on the original site

Post score: 13

Original comments

Comment by Gazer on 2013-06-19:
very nice answer!!! could you please explain a bit more why the odometry will drift?

Comment by bvbdort on 2014-02-25:
@Gazer Many reasons for drift in odometer. ex: if floor is not flat ,slipping of wheels or quantization error from wheel encoder, mismatches in diameters of wheels.

Comment by burf2000 on 2017-02-02:
Could you just use the Laser? instead of using the wheel encoders

Comment by nico_b on 2017-04-25:
@burf2000 Sorry, a bit late, but you could use i.e. the laser_scan_matcher.

Comment by NAGALLA DEEPAK on 2018-01-25:
I am using hector_slam. I read that hector_slam does not need any odometry data. Could you help me with this https://answers.ros.org/question/279764/problem-getting-map-using-hector_slam/


Rosanswers logo

Since static_transform_publisher can be used only to set up transformation between fixed (w.r.t. each other) frames you have to use something like this in your node:

int32_t publish_rate_ = 100;
tf::TransformBroadcaster tf_br_;
tf::StampedTransform tf_map_to_odom_;

// set up parent and child frames
tf_map_to_odom_.frame_id_ = std::string("map");
tf_map_to_odom_.child_frame_id_ = std::string("odom");

// set up publish rate
ros::Rate loop_rate(publish_rate_);

// main loop
while (ros::ok())
  // time stamp
  tf_map_to_odom_.stamp_ = ros::Time::now();

  // specify actual transformation vectors from odometry
  // NOTE: zeros have to be substituted with actual variable data
  tf_map_to_odom_.setOrigin(tf::Vector3(0.0f, 0.0f, 0.0f));
  tf_map_to_odom_.setRotation(tf::Quaternion(0.0f, 0.0f, 0.0f));

  // broadcast transform


Originally posted by Boris with karma: 3060 on 2012-09-26

This answer was NOT ACCEPTED on the original site

Post score: 6

Original comments

Comment by moyashi on 2012-09-26:
Thank you for your kind answer.

I think that it means map frame is equal to odom frame ...

Odom frame represents a robot's initial position doesn't it?

Comment by Boris on 2012-09-26:
That's correct. So you have to specify real values instead of zeros in functions setOrigin() and setRotation(), and update them while robot is moving.

Comment by Lorenz on 2012-09-27:
Static transform publishers as well as amcl future date the transforms. Have a look here.

Comment by Boris on 2012-09-27:
@Lorenz: Thanks. Seems I misunderstood the subject.


Rosanswers logo

I guess your question comes from the confusion why localization algorithm like amcl or gmapping do not publish /map -> /base_link (robot's position and orientation in map) directly instead of publishing the /map -> /odom transform. Some answers use static_transformation for publishing the /map -> /odom transform, which I can't say is incorrect because if the odometry reading never drifts then the /map -> /odom transform can be static. It will always be the displacement between map's origin and the starting position of the robot. Then you wouldn't need the amcl or gmapping algorithms because Tmap->odom * Todom->base_link = Tmap->base_link will always give you an accurate estimate of the robot's location.

But the fact that odometry reading drifts over time so we need extra localization mechanism including those lidar sensing, visual fiducial system, GPS etc. For amcl using lidar we are capable of getting /map -> /base_link transformation, BUT this breaks the rules of tf where 1 child frame can only have 1 parent frame. If we have /odom -> /base_link, then we can NOT have another direct transformation /map -> /base_link in the tf tree. So a typical tf tree would be /world -> /map -> /odom -> /base_link, where you get /map -> /odom from amcl, and /odom -> /base_link from your wheel encoders and imu fusion.

So to answer your question "where can I get /map -> /odom", it can be an output from localization algorithm like amcl. Together with /map -> /odom and /odom -> /base_link, you can get a more accurate /map -> /base_link transform.

Originally posted by shawkontzu with karma: 41 on 2021-10-06

This answer was NOT ACCEPTED on the original site

Post score: 4


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.