# Is there a Node for general data frame transforms?

I am looking for a package which uses tf2 to perform semi-generalized data transforms. Based on its configuration it would subscribe to an input topic and transform the message on that topic to a parameter specified coordinate frame. Such as transforming PointCloud2 from lidar frame to base_link or converting a PoseStamped message from base_link to map etc. Obviously supporting custom messages might be a stretch, but does such a package exist for common messages in either ROS 1 or ROS 2?

edit retag close merge delete

tf2 includes a transform class. You can use their API directly

( 2021-12-18 10:03:54 -0500 )edit

Thanks, I'm aware of that. But, I'm looking for a node which can be placed in the data stream rather than trying to perform the transform at each data end point using the tf2 library.

( 2021-12-18 19:15:59 -0500 )edit

So the question would actually be: "is there a node for general data frame transformations"?

( 2021-12-19 07:38:27 -0500 )edit

I suppose so, I was thinking it would be implied by the subscribe/publish part of the question, but I have gone ahead and edited the title for clarity.

( 2021-12-20 18:08:41 -0500 )edit

Sort by » oldest newest most voted

Since, I didn't get a result in a couple of days, I've gone ahead and implemented this myself to work with any stamped message type currently supported in tf2_geometry_msgs or tf2_sensor_msgs. The implementation uses some utility packages from my team's project, but those could be easily removed by others. The PR is currently here for anyone who comes looking for the same thing. https://github.com/usdot-fhwa-stol/ca...

more

See tfoote's answer and the corresponding comments for more context on the limitations of this approach and when it does or does not make sense.

( 2021-12-28 13:01:28 -0500 )edit

What you're requesting/suggesting is a bit of an anti-pattern. As you can see from your own answer it's relatively simple to implement. There's an issue that you have to precompile it with all datatypes known which doesn't scale well, to be completely generic.

But the question is whether you should be doing this. The design of the tf system is setup such that you communicate data in it's original raw format and transform it prior to use into the coordinate frame of choice for your algorithm. This avoids inherent degredation of the data through multiple floating point transformations. Similarly, you lose potentially valuable semantic information about the sampling process. Such as the origin of a point cloud from a sensor. For example a native point cloud from a sensor can be used to ray trace and clear closer obstacles.

And there's also significant costs to putting an intermediate node in the middle incurring potentially doubling the costs of sending and receiving the data. And in most cases the computational cost to transform the data is much lower than the cost to transmit it, thus having each consumer transform it is more efficient.

The other challenge with trying to "pre-transform" the data is that you have to all agree on the coordinate transform into which it is most useful. A simple example of a navigation system, may want the point clouds to be represented in the odometry frame for the local planner, but the map frame for the global planner. The most efficient way to deal with that is to send it the point cloud from the sensor and let them both transform it into whatever frame they are parameteraized to use. The navigation user can reconfigure it to a potentially application specific frame w/o effecting anything else on the system. It looks nice on a system diagram to avoid a potential "extra transform", but until that's actually diagnosed as your bottle neck I'd strongly recommend against trying to use it generically. The abstraction of not expecting data to arrive in any specific frame is very valuable when doing system integration.

more

1

The abstraction of not expecting data to arrive in any specific frame is very valuable when doing system integration.

Yes. This aspect is quite often misunderstood / ignored by developers.

I've seen systems where all nodes were expected to be aware of a global world frame and to operate on all data in that world frame. Any node not developed by the same group could not be used until it was 'fixed' to comply with this (implicit) rule. At which point it couldn't be used any more outside of that system.

As with almost everything in component-based software engineering / development, we trade computational efficiency for flexibility (in this case) if we require all nodes to pre-process their input and make sure it's represented in a coordinate frame suitable for their processes.

In a way, always transforming incoming data is very similar to "always validate your input", which has ...(more)

( 2021-12-24 02:35:06 -0500 )edit
1

It would appear however that the OP is actually trying to work around the exact same situation I described in my previous comment.

Integration testing of ROS2 object perception stack identified that the Autoware.Auto nodes expect input data to already be transformed prior to arriving at the target node.

and:

Seperate transformer nodes were implemented in Autoware.Auto to achieve this goal. Unfortunately, these nodes do not use the TF2 library meaning that the transform tree is duplicated in multiple parameter files. I believe this approach will be extremely hard for our team to maintain and error prone as transforms get updated in some locations but not others.

with this context (which was missing from the initial question), the approach described (a generic node capable of transforming incoming msgs into another TF frame) seems acceptable.

( 2021-12-24 02:38:09 -0500 )edit

@gvdhoorn is spot on. I definitely agree with @tfoote's assessment on the general merits of the tf2 approach and usually try to implement things in that way. Unfortunately the nodes, I am trying to utilize do not work that way so this was an attempt to work around that limitation.

( 2021-12-28 12:57:21 -0500 )edit

There is a chance this was done like this in Autoware.Auto to improve determinism.

Analysis of control flow will be complicated by potential transformations which also are potentially unbounded in their execution time.

It's rather drastic to not use TF at all though (I could imagine making this configurable per-node, but configuration options complicate certification/analysis again due to higher variability).

Would be interesting to figure out what the motivation was in Autoware.Auto.

( 2021-12-30 03:28:24 -0500 )edit

I did a little bit more investigation of this, and it seems that Autoware.Auto generally does use TF2. But there are a handful of nodes in the data filtering pipeline which do no use TF2 and expect already transformed data. As I mentioned earlier, Autoware.Auto does provide transformer nodes which have separate parameter files for the transforms, what I missed initially (its undocumented) is that the parameters for these nodes are actually optional and the transformer nodes fall back to tf2 if the parameter is not specified.

( 2021-12-30 10:29:02 -0500 )edit