Code Monkey home page Code Monkey logo

tf_bag's Introduction

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 PATH_TO_MY_BAG/data.bag --lz4 /tf /tf_static MY_TOPIC1 MY_TOPIC2 <...>

Loading data from a bag file

import rosbag
from tf_bag import BagTfTransformer

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

bag = rosbag.Bag(bag_file_path)

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 = bag_transformer.lookupTransform(frame1_id, frame2_id, time)

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

Waiting for a transform

first_transform_time = bag_transformer.waitForTransform(frame1_id, frame2_id, start_time)

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 child_frame_id 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
average_translation, average_quaternion = bag_transformer.averageTransform(frame1_id, frame2_id)

 # the transform will be sampled at every update of the transform between frame1 and frame2
average_translation, average_quaternion = bag_transformer.averageTransform(frame3, frame6,
                                                                           trigger_orig_frame=frame1_id,
                                                                           trigger_dest_frame=frame2_id)

For particular needs, a callback can be provided:

translation_z_over_time = bag_transformer.processTransform(lambda time, transform: transform[0][2], 
                                                           frame1_id, frame2_id, 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')

tf_bag's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

tf_bag's Issues

Not able to complete installation

I'm sorry for the simple question, but I am not able to import this package.

I tried to install the package with
pip install -e git+https://github.com/IFL-CAMP/tf_bag#egg=tf_bag

and got this message

Obtaining tf_bag from git+https://github.com/IFL-CAMP/tf_bag#egg=tf_bag
  Cloning https://github.com/IFL-CAMP/tf_bag to ./src/tf-bag
    Complete output from command python setup.py egg_info:
    running egg_info
    creating src/tf_bag.egg-info
    writing src/tf_bag.egg-info/PKG-INFO
    writing top-level names to src/tf_bag.egg-info/top_level.txt
    writing dependency_links to src/tf_bag.egg-info/dependency_links.txt
    writing manifest file 'src/tf_bag.egg-info/SOURCES.txt'
    error: package directory 'src/tf_bag' does not exist
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /home/sarah/practice_ws/src/sim_eval/sim_eval/src/tf-bag/

Am I installing it incorrectly?
Any help would be appreciated.
Thank you in advance.

Lookup Transform not updating correctly

We have been using this tool for some per-processing and I have had a few issues with the TF tree update not getting triggered.

The tree looks something like
world -> gps_frame -> base_link -> point_cloud

world -> gps_frame is 10hz and gps_frame ->base_link is 1hz.

When using lookup transform from (world -> pointcloud) the TF is only updated at 1Hz. By splitting it into (world -> gps_frame) and (gps_frame -> point_cloud) it updates at 10hz.

Have had a look at code and nothing stands out as issue but have also had some difficulty with a lookupTransformWhenTransformUpdates and setting triggers so have resorted to similar solution but now wondering if its the TF tree or some other issue.

bag_tf or tf_bag ?

Hi,

thank you for this package!
Just I would like to point out the misspelling in documentation where you say:
from bag_tf import BagTfTransformer and it should be : from tf_bag import BagTfTransformer

"/tf" vs "tf"

Hello!

First of all, thank you very much for the awesome package; it saved me a ton of headache!

I had some trouble loading up the messages from my bag (recorded in ROS Indigo) due to the line

self.tf_messages = sorted((tm for m in bag if m.topic == '/tf' for tm in m.message.transforms),
key=lambda tfm: tfm.header.stamp.to_nsec())

EDIT: I recorded my bag by running rosbag record odom tf.

(which can be found here in your code)

This only allows for messages under the "/tf" topic. However, for whatever reason, my bag's topic is "tf" and not "/tf". I'm not sure whether I made some mistake when recording it, but the fact is that changing your code to "tf" fixed the issue, and I can read the info I need from the bag effortlessly.

Is this some sort of mismatch in ROS versions? Should this be accounted for in the package? If you think so, I'd be happy to submit a pull request that implements compatibility with both topic names.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.