ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

How to broadcast a transform between /map and /odom

asked 2012-09-26 20:04:33 -0600

moyashi gravatar image

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.

edit retag flag offensive close merge delete

4 Answers

Sort by » oldest newest most voted

answered 2012-09-26 21:57:39 -0600

Lorenz gravatar image

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.

edit flag offensive delete link more


very nice answer!!! could you please explain a bit more why the odometry will drift?

Gazer gravatar image Gazer  ( 2013-06-19 16:40:24 -0600 )edit

@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.

bvbdort gravatar image bvbdort  ( 2014-02-25 01:11:03 -0600 )edit

Could you just use the Laser? instead of using the wheel encoders

burf2000 gravatar image burf2000  ( 2017-02-02 09:52:08 -0600 )edit

@burf2000 Sorry, a bit late, but you could use i.e. the laser_scan_matcher.

nico_b gravatar image nico_b  ( 2017-04-25 03:25:40 -0600 )edit

I am using hector_slam. I read that hector_slam does not need any odometry data. Could you help me with this

NAGALLA DEEPAK gravatar image NAGALLA DEEPAK  ( 2018-01-25 09:44:54 -0600 )edit

answered 2012-09-26 21:31:01 -0600

updated 2012-09-27 00:29:36 -0600

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

edit flag offensive delete link more


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?

moyashi gravatar image moyashi  ( 2012-09-26 21:37:39 -0600 )edit

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.

Boris gravatar image Boris  ( 2012-09-26 21:49:37 -0600 )edit

Static transform publishers as well as amcl future date the transforms. Have a look here.

Lorenz gravatar image Lorenz  ( 2012-09-27 00:32:49 -0600 )edit

@Lorenz: Thanks. Seems I misunderstood the subject.

Boris gravatar image Boris  ( 2012-09-27 00:42:39 -0600 )edit

answered 2021-10-06 17:20:21 -0600

shawkontzu gravatar image

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.

edit flag offensive delete link more

answered 2012-09-27 10:24:40 -0600

Pitscho gravatar image


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:

Well is use static_transform_publisher, because in my case odom -> map is static, only two 90° rotations.

I use this in my launch file:

<node pkg="tf" type="static_transform_publisher" name="odom_to_map"
    args="0.1 0  0  -1.570796327 0 -1.570796327  /map /odom 100" />

Search fpr static_transform_publisher in the ROS docu.

edit flag offensive delete link more



i dont understand why someone would publish odom to map static transform. Isnt hte transform between them computed using the reported odometry readings from the encoders (odom) and corrective sensors (map)?

JadTawil gravatar image JadTawil  ( 2017-09-25 20:34:08 -0600 )edit

JadTawil I don' understand either why these answers talk about static transforms as Odometry accumulates error and can not be used for global reference. I always see this answer when ever I look up the map transform

hpurohit gravatar image hpurohit  ( 2018-05-16 11:21:17 -0600 )edit

Question Tools



Asked: 2012-09-26 20:04:33 -0600

Seen: 21,736 times

Last updated: Sep 27 '12