using tf data from bag files

I'm wondering if there is a good way to get transforms (rotation and translation) from tf data recorded in bag files. I'm working in python and I don't want to replay the bag file as part of the solution. Instead I want to be able to get other messages from the bag file and use tf to find the euclidean distance between two frames on the robot at the same time instant as my message of interest. Any thoughts?

I could look at parent-child relationships in a single tf message and string the transforms together, but then I'd be recreating the functionality of tf. Is there a utility or tool for getting a transformation from a single tf message (i.e. not using ROS to wait for transform or having to replay the bag file). Thanks a lot for any ideas.

edit retag close merge delete

Sort by » oldest newest most voted

The main problem is that playing a bag files in conjunction with tf is problematic. Tf messages arent't synchronized with the current rosTime. Several alternatives has been proposed but apparently they don't work (at least not for me in python). See http://answers.ros.org/question/1114/waitfortransform-use_sim_time-python and see also http://ros-users.122217.n3.nabble.com/tf-use-sim-time-clock-and-bag-files-td1305066.html

AFAIK this problem is still not solved for tf in python. I think it would be possible if the TransformListener::subscription_callback were public. Am I right? tf::tfMessage's could be retrieved from bag and pushed manually using this method and the Bag API (see below a pythonic code - pytf.cpp modifications also needed):

bag = rosbag.Bag(bag_file)
listener = tf.TransformListener()
for topic, msg, t in bag.read_messages(topics=['/tf']):
listener.subscription_callback(msg)


To reproduce bags with tf messages are very interesting specially in geometric learning problems where bags files with transform information can be used as training database (this is my case).

Until now I'm using this solution to simulate tf in a bag messages at the current time(though I don't like it so much):

import roslib
import rospy
import tf

rospy.init_node("tf_restamper")
tfpublisher= rospy.Publisher("tf",tf.msg.tfMessage)

def tfcallback(tfmessage):
for transf in tfmessage.transforms:
tfpublisher.publish(tfmessage)

tfproxy = rospy.Subscriber("tf_old",tf.msg.tfMessage,tfcallback)
rospy.spin()

more

1

It seems like some of the timing issues can be dealt with by setting the /use_sim_time parameter to true (use --clock option for rosbag play). However, this doesn't work to play/look at more than one bag file in a single process. When the time starts over for the 2nd bag file, tf freaks out.

( 2012-02-25 03:58:42 -0600 )edit

Any single tf message is only a part of the state of the system. To know the state of the system you need to aggregate tf messages over time. You can do this on a bag file without playing back the messages by using the rosbag code API. But it is likely that you will still want to use the tf libraries which are designed to accumulate the messages and be queryable.

more

1
I figured that was the only solution, but all the tf information should be available from a single tf message. Technically I shouldn't need to aggregate it over time. It's good to know my use case just wasn't in the design of tf. Thanks.
( 2011-10-09 20:58:41 -0600 )edit

I also ran into this problem and this question many times, so I eventually created a python package called tf_bag.

I hope this can be helpful to anybody finds this topic.

more

It looks like the easiest way will be to replay the bag file and use tf libraries to get this transform and record it with a time stamp to a separate file. Then I can at least interpolate between transforms for the time I'm interested in for my other messages. Not as nice as using tf directly or ROS tools directly, but it will allow me to access a transform at a given time without playing a bag file online.

more