Rosanswers logo

Version: ROS Kinetic (ubuntu 16.04)

I believe that I'm pinched in a narrow use-case crack between TF and TF2 and the differences between lookupTwist (which has duration argument for averaging) and what looks like a bunch of manual calculation to achieve that same result using TF2s lookup_transform, which obviously does not provide such functionality.

I find myself dependent on the averaging functionality, which is really useful generally for robotics. Some code changes in separate but related nodes have exposed TF's apparent inability to see all TF Static Frames that were established prior to (a given) node's initialization. This inability to see previously create static TF is preventing me from resolving what should be a trivial refactor to support the externally driven changes.... looking to find a solution

Tl;DR / I need solution(s) for at least of one of the follwing:

  • For TF to be able to see all static transforms (including those created before the nodes initializes)
  • For TF2 to already have this (very useful) lookuptwist functionality available in RosPy; and i just don't know where it is
  • Pseudo code for what is needed to write a bespoke function to achieve this averaging function with TF2in a 3d space.

I see on the TF2 tutorial page an example for a new publisher to push a new Twist from another frame at the same point in time.

but i were to do this i would need to go get two transforms for the same frame at two points in time and them manually average a new Twist value. the turtlebot example is incomplete for 3d...

Help resolving the issues with either approach appreciated.

Originally posted by constructiverealities on ROS Answers with karma: 31 on 2018-02-12

Post score: 4


1 Answer 1


Rosanswers logo

The semantics of a twist are not clearly defined in the Twist message so we can't generically transform it. And as such the method was not ported to tf2.

If you want to implement your own way to do this. It's just applying discrete differentiation. You have the algorithm right. You take the difference between position 1 and position 2 and divide by the change in time to get the "velocity". This also is not necessary as a core function as it doesn't require any extra core data. Just needs to have buffer available to query.

You can look at the full implementation in tf here: https://github.com/ros/geometry/blob/4421e22243a38ba6a130494698b33117d2995a18/tf/src/tf.cpp#L270

Originally posted by tfoote with karma: 58457 on 2018-02-12

This answer was ACCEPTED on the original site

Post score: 2

Original comments

Comment by constructiverealities on 2018-02-13:
Thanks @ tfoote. If I'm to implement this (as i would like to use tf2). how to I use/access the functions on the transform class from rospy? When I use the lookup_transform. i get a transform message back, but how to cast/use it as proper object with methods from Docs from python?

Comment by tfoote on 2018-02-13:
There are equivalent datatypes in various python libraries.

Comment by SamH on 2021-06-21:
Do you have any example code to implement this solution @tfoote?

Comment by Miramur on 2022-03-24:
@tfoote (1) What exactly is missing from Twist to be able to generically Transform it? (2) Even if a Twist can't be generically transformed, wouldn't it still be possible to implement the limited version of lookupTwist (where the reference frame == the observation frame), where no Twist transform is required?

Comment by tfoote on 2022-03-25:
There's both a reference point, a reference orientaion, and the observation frame. Converging all of those into the same location makes the values very unintuitive. For example consider representing a pitched curveball with a reference frame and reference point of home plate. That's not an actual useful value. Keeping the reference orientation at home plate can make sense, but not the reference point. You would actually want to be able to input these separately to give useful queries. Otherwise you're just going to have to add another layer of queries to transform them into a useful twist. And then you're making assumptions about the origins etc.

And the second issue is that you still have to deal with selecting the appropriate timeperiod to do your discrete differentiation. Too small and it will be too noisy, too large and it will be a low pass filter.


Your Answer

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