Rosanswers logo

I am trying to use the robot_pose_ekf package with my system, and am having trouble understanding what my tf tree should look like, and what frame the output of robot_pose_ekf is in. My robot is microcontroller based and is not running ROS on-board. Additionally it does not have any IMU information or visual sensing on-board. It reports its pose estimate (based on odometry) in an /odom frame at a fixed frequency. I have an external vision system tracking the robot as well. The transform from the /sensor_optical frame to the /odom frame is static and known. Every time the sensor transmits an estimate of the robot's position, I use this transform to transform the data into the /odom frame.

Thus, the /odom topic comes from the robot's odometry, and its header.frame_id is /odom, and its child_frame_id is /base_footprint. The /vo topic comes from the external vision system, and its header.frame_id is /odom, and its child_frame_id is /base_footprint. When I run the system the robot_pose_ekf package runs without any errors. If I plot the pose published on the /odom and /vo topic, they are exactly what I expect, but the pose published on /robot_pose_ekf/odom_combined topic is not what I expect. Setting the covariances of the /vo topic to be very high, the pose output of /robot_pose_ekf/odom_combined is then the same "shape" as that of /odom, but it must be in some odd coordinate system.

What am I doing wrong? What frame should this pose be expressed in? When I use tf2_visualization, I see that I have unconnected trees. robot_pose_ekf publishes a transform from /odom_combined -> /base_footprint, but that transform is unconnected from the rest of the tree. I definitely believe this is a problem, but I am unsure how to fix it. Finally, the pose published in /robot_pose_ekf/odom_combined says its frame_id is odom (but it doesn't actually seem to be).


Originally posted by jarvisschultz on ROS Answers with karma: 9031 on 2011-10-25

Post score: 5


2 Answers 2


Rosanswers logo

Let's ignore the vision system for a moment, and focus on wheel odometry and robot_pose_ekf. Your TF tree should look like this (also see this ros-users thread):

map --> odom_combined --> base_footprint --> base_link

... where

  • map --> odom_combined is usually published by amcl (optional)
  • odom_combined --> base_footprint is published by robot_pose_ekf
  • base_footprint --> base_link is a fixed link in your URDF.

The reason for this peculiar choice of frames is that in TF, each frame can only have one parent. Intuitively, one would like to have multiple parents of base_footprint:

  • odom --> base_footprint for pure wheel odometry
  • odom_combined --> base_footprint for EKF estimation
  • map --> base_footprint for AMCL localization

Since this is not possible in TF, the frames are published as a chain (see above). The important part for your problem is that when using robot_pose_ekf, tf publishing from the wheel odometry has to be switched off. Instead, you should only publish nav_msgs/Odometry messages (using odom_combined as the header frame id), which form the input for robot_pose_ekf and can also be visualized in RViz.

In short:

  • use odom_combined instead of odom everywhere (or the other way around, but be consistent about it)
  • don't publish any TF messages, let robot_pose_ekf do that
  • publish nav_msgs/Odometry messages for the wheel odometry and the overhead camera on the /odom and /vo topics, in both cases specifying odom_combined as the header frame id and base_footprint as the child_frame_id.

I hope that helps; otherwise, could you post your TF tree, showing the unconnected frames?

Originally posted by Martin Günther with karma: 11816 on 2011-10-31

This answer was ACCEPTED on the original site

Post score: 19

Original comments

Comment by Alireza on 2012-01-26:
how can i implement base_footprint --> base_link transformation?

Comment by mjcarroll on 2012-01-26:
This is awesome info and should be somewhere in the navigation stack documentation. It took me a long time to put all the pieces together the first time that we tried using move_base, but this is very clear.

Comment by Martin Günther on 2011-11-03:
That's a good question, Jarvis. I think that is because there's a mismatch between REP-105 (which suggests "odom") and the way these frames are actually used on the PR2 and most other robots (which use "odom_combined"). See the mailing list thread linked in my answer.

Comment by jarvisschultz on 2011-11-02:
Thank you so much! That totally got me straightened out, and solved the issues that I was having. Given your explanation, I wonder why the geometry_msgs::PoseWithCovarianceStamped that is published by robot_pose_ekf has a hard-coded header.frame_id of "odom"?

Comment by jxl on 2016-07-07:
@Güntherad @jarvisschultz ,thanks very much .But when i tried according to your answer ,i got a problem when rosrun move_base node .It says "odom" passed to lookuptransform argument target_frame does not exist" . how can i modify move_base to fix this tf problem,thanks very much .


Rosanswers logo

I am having the same problem. I read your answer, but i am not able to totally understand how i can solve the problem. I am attaching my TF tree here. Can you please help me how i can resolve it? maybe post some code snippets.

Screenshot from 2016-08-04 15:46:39.png

Originally posted by krishna43 with karma: 63 on 2016-08-04

This answer was NOT ACCEPTED on the original site

Post score: 1


Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.