# Can a ROS 2 TF buffer be queried in time-critical code?

Does anybody know if the ROS2 tf buffer belongs in control loops? What's the latency on calling lookupTransform()?

It would be great if it were realtime safe.

edit retag close merge delete

"should" implies there is some requirement.

Should the question be: "Can a ROS 2 TF buffer be queried in time-critical code?"?

( 2021-04-28 13:51:51 -0500 )edit

Sort by » oldest newest most voted

As @stevenmacenski mentions there's a lot of different requirements. The lookupTransform and canTransform are designed to be very fast. However it definitely doesn't meet hard realtime requirements such as being lock free. An academic view of the complexity is in the paper: http://wiki.ros.org/Papers/TePRA2013_...

The primary costs are walking up the tree to find connectivity. There's a speed test with a relatively deep tree (10 levels) which is available in the unit tests that you can build yourself and modify if you'd like. Running on my laptop and noetic I get the following.

\$ rosrun tf2 speed_test
Info:    9 to 4
Info:    Doing 1000000 10-level 1.000000-interval tests
Info:    lookupTransform at Time(0) took 8.197501 for an average of 0.000008198
Info:    lookupTransform at Time(1) took 5.620309 for an average of 0.000005620
Info:    lookupTransform at Time(1.5) took 8.397436 for an average of 0.000008397
Info:    lookupTransform at Time(2) took 5.281582 for an average of 0.000005282
Info:    canTransform at Time(0) took 5.593769 for an average of 0.000005594
Info:    canTransform at Time(1) took 2.904320 for an average of 0.000002904
Info:    canTransform at Time(1.5) took 4.741364 for an average of 0.000004741
Info:    canTransform at Time(2) took 2.517103 for an average of 0.000002517
Info:    canTransform at Time(3) without error string took 0.985417 for an average of 0.000000985
Info:    canTransform at Time(3) with error string took 2.794714 for an average of 0.000002795


You can reproduce this if you build from source and build the tf2 target tests.

https://github.com/ros/geometry2/blob...

It looks like the speed_test performance test hasn't been ported to ROS 2 however the core algorithm is independent of ROS so I would not expect any significant changes. A contribution to port and reenable that performance test would be appreciated. https://github.com/ros2/geometry2/blo...

more

Everyone has a different definition of what exactly "realtime" means (hard, soft, generally "fast" enough, etc) so its difficult to answer as posed.

However, lookupTransformhas a timeout value (e.g. if can't be found within a period returns failure so it doesn't block to control loop) https://docs.ros2.org/foxy/api/tf2_ro.... So in some definitions of the word, yes, I think it can be called in a realtime control loop since you can set the timeout such that TF queries never block the loop to miss a scheduled update (though obviously if you timeout and don't have a valid transform, then that cycle would not be able to compute its value properly).

Because you're requesting information from an arbitrary frame to an arbitrary frame, I don't think anyone can say for 100% certainty in 100% of cases that you'll receive a response in under N nanoseconds because you could be transforming the data between 1 reference frame (easy) or 1,000,000 reference frames in the transformation tree. But assuming you're working with a "normal" situation, I see no reason why the latency would be insufficient for real-time use (depending on your definition or requirements).

However, if you're instead asking if anyone's certified TF2 as "real-time", the answer is a clear no.

I think it should be pretty trivial for you to come to the conclusion though. If you set up your TF tree + publish TF updates sufficiently fast, you should be able to just make a simple while true loop and query your transform of interest and measure the time to find it. If its under your real-time schedule, then you're probably OK for soft real-time requirements with some proper error handling.

more

Thanks for some practical advice. Maybe a better question would have been, what's the best-case spin rate when lookupTransform is called in a loop. I'm just curious how fast it is (assuming the needed frames are present).

( 2021-04-28 15:25:30 -0500 )edit

It would take me just as much time as you to answer that question (from the while true experiment I proposed above), so I'd recommend just trying it out and see!

( 2021-04-28 21:33:57 -0500 )edit