ROS Resources: Documentation | Support | Discussion Forum | Service Status | Q&A
Ask Your Question

How to broadcast a transform between /map and /odom

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

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

3 Answers

Sort by » oldest newest most voted

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

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 imageGazer ( 2013-06-19 16:40:24 -0500 )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 imagebvbdort ( 2014-02-25 01:11:03 -0500 )edit

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

burf2000 gravatar imageburf2000 ( 2017-02-02 09:52:08 -0500 )edit

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

nico_b gravatar imagenico_b ( 2017-04-25 03:25:40 -0500 )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 imageNAGALLA DEEPAK ( 2018-01-25 09:44:54 -0500 )edit

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

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 imageJadTawil ( 2017-09-25 20:34:08 -0500 )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 imagehpurohit ( 2018-05-16 11:21:17 -0500 )edit

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

Boris gravatar image

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

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 imagemoyashi ( 2012-09-26 21:37:39 -0500 )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 imageBoris ( 2012-09-26 21:49:37 -0500 )edit

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

Lorenz gravatar imageLorenz ( 2012-09-27 00:32:49 -0500 )edit

@Lorenz: Thanks. Seems I misunderstood the subject.

Boris gravatar imageBoris ( 2012-09-27 00:42:39 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


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

Seen: 7,732 times

Last updated: Sep 27 '12