IFL-CAMP
tf_bag
Python

Utilities to transparently use tf data recorded with rosbag in Python scripts

Last updated Mar 27, 2026
93
Stars
24
Forks
1
Issues
0
Stars/day
Attention Score
25
Language breakdown
No language data available.
โ–ธ Files click to expand
README

tf_bag

Utilities to transparently use tf data recorded with rosbag

Querying tf for an arbitrary transformation is very comfortable at runtime thanks to its tooling (tf_echo from the console and the TransformListener programmatically). The programs included in the tf package implement a background recording of the messages incoming on the /tf topic and assemblying them in a Direct Acyclic Graph, which can then be looked up between two arbitrary nodes.

While it is possible to include the /tf and /tf_static topics to the ones recorded by rosbag, no tool is provided to use this data. So the most common solution is to play the rosbag and let a program poll tf regularly. This is not an ideal solution, especially for scripting.

This package includes a BagTfTransformer which is able to use tf data from a recorded rosbag by feeding a tf TransformerROS. It supports looking up a transform at a given time, waiting for a transform since a specific time, and much more. The API was thought to be as similar as possible as the tf classes. The performance was optimized for scripting purposes (e.g. linear scans over time).

Getting started

# source the installation workspace (replace <ROSDISTRO> with your distro, e.g. noetic)
source /opt/ros/<ROSDISTRO>/setup.bash

create a catkin workspace

mkdir -p ~/ros/catkin_ws/src

check out this package

cd ~/ros/catkin_ws/src git clone https://github.com/IFL-CAMP/tf_bag.git

install the dependencies and compile

cd ~/ros/catkin_ws rosdep install -ryi --from-paths . --ignore-src catkin_make # (or catkin build)
  • profit!
# source the workspace, to make the packages available to your shell
source ~/ros/catkin_ws/devel/setup.bash
rospython
>>> import tf_bag

Common tasks

Recording data into a bag file

# save to a custom location, compress on the fly
rosbag record -O PATHTOMYBAG/data.bag --lz4 /tf /tfstatic MYTOPIC1 MYTOPIC2 <...>

Loading data from a bag file

import rosbag
from tf_bag import BagTfTransformer

bagfilepath = '/path/to/some.bag'

bag = rosbag.Bag(bagfilepath)

bag_transformer = BagTfTransformer(bag)

Or alternatively:

from tf_bag import BagTfTransformer

bag_transformer = BagTfTransformer('/path/to/some.bag')

Displaying the transforms included in a bag

print(bag_transformer.getTransformGraphInfo())

Looking up a transform

translation, quaternion = bagtransformer.lookupTransform(frame1id, frame2_id, time)

The transformer takes care of "waiting" for the transform for up to 0.1 seconds.

Waiting for a transform

firsttransformtime = bagtransformer.waitForTransform(frame1id, frame2id, starttime)

The start_time parameter can be omitted: in that case, the transformer will start waiting from the beginning of the bag data.

Processing a transform

In order to process a transform, it is necessary to specify the times at which it should be sampled. If the two frames are directly connected, the transform will be sampled at every update (that is, at the timestamp of which message on the tf topic having the source frame as the header.stamp.frame_id attribute and the target frame as the childframeid attribute). If the two frames are not directly connected, an alternate "trigger" source or target frame (or both) must be specified.

# the two frames are directly connected in the tf tree
averagetranslation, averagequaternion = bagtransformer.averageTransform(frame1id, frame2_id)

# the transform will be sampled at every update of the transform between frame1 and frame2 averagetranslation, averagequaternion = bag_transformer.averageTransform(frame3, frame6, triggerorigframe=frame1_id, triggerdestframe=frame2_id)

For particular needs, a callback can be provided:

translationzovertime = bagtransformer.processTransform(lambda time, transform: transform[0][2],                                                             frame1id, frame2id, start_time)

Visualization

The translation of a transform can be visualized in a matplotlib graph. If no axis is specified, a 3D plot will be drawn:

bag_transformer.plotTranslation(frame1, frame2)

Otherwise, the value of the translation in one axis will be plotted over time:

bag_transformer.plotTranslation(frame1, frame2, axis='z')

ยฉ 2026 GitRepoTrend ยท IFL-CAMP/tf_bag ยท Updated daily from GitHub