Rosanswers logo

So I recently got stuck with this strange error that timeout in lookupTransform behaves differently in rclcpp and rclpy. Shortly, I want to acquire transformations at time this->get_clock()->now. Surely when I do lookupTransform for transformation at that exact time the transformation was not yet broadcaster by broadcaster, and I get the expected exception:

Lookup would require extrapolation into the future.  Requested time 1630168500.665476 but the latest data is at time 1630168500.657399, when looking up transform from frame [turtle1] to frame [turtle2]

To solve that matter I tried to use the timeout optional parameter, which works properly only in the rclcpp, but not in rclpy. This error does not go away with used timeout parameter but only blocks the node.

The C++ listener node is here: https://github.com/kurshakuz/geometry_tutorials/blob/lookup-tests/turtle_tf2_cpp/src/turtle_tf2_listener.cpp#L76

And the Python (which is failing) is here: https://github.com/kurshakuz/geometry_tutorials/blob/lookup-tests/turtle_tf2_py/turtle_tf2_py/turtle_tf2_listener.py#L70

The node is included in the launch file and is started there. I am launching: ros2 launch turtle_tf2_py turtle_tf2_demo.launch.py which starts the turtlesim, two broadcasters and listener. Link: https://github.com/kurshakuz/geometry_tutorials/blob/lookup-tests/turtle_tf2_py/launch/turtle_tf2_demo.launch.py

I have two frame broadcasters, each one subscribed to their own topic and broadcast according transformations in the callback. Topics publish at rate average rate: 62.502 and the same rate for frame broadcasting. Thus I think there is an issue with my listener node. To be more specific, the only issue is related to the lookup_transform() function. I tried:

  1. using different timeout values starting from 50ms to 10s. For some reason it is not waiting for transform to be available and rather just pauses the spin
  2. to lookup old transformations by calling self.get_clock().now() - Duration(seconds=0.05) which solves the problem and it lets me to acquire transformation.

However, I try to build an example to get the transformation at time now(), without going back in time. This works as expected in rclcpp, but not in the rclpy. May it be the case that Python is just slower and there is no way to avoid it? Or is it possible that timeout works differently in rclcpp and rclpy?

Originally posted by kurshakuz on ROS Answers with karma: 76 on 2021-08-28

Post score: 0

Original comments

Comment by tfoote on 2021-08-30:
Please edit your question to explain exactly what you're doing and how it's failing. I can't help you debug "which is failing". Python and c++ have different performance characteristics as well as threading models. Have you tried increasing the timeout? And have you tried a slightly older timestamp?

Comment by kurshakuz on 2021-08-30:
Yes I tried both. I have updated the question, please have a look. My short question is: how to acquire transformation at time now() in rclpy without having to get older timestamps? I am just wondering if it is the limitation of the Python itself, the code difference in lookupTransform() implementations in rclcpp/rclpy, or is it due to my code.


1 Answer 1


Rosanswers logo

With the extra information that a longer timeout doesn't work, and the fact that your able to transform slightly older data, I believe that you're running into the issue that you are blocking the execution of the python process while waiting. Without another thread running you're blocking the timer thread. But in blocking that thread you are preventing new incoming messages from arriving. Thus the new information that you're waiting on will never arrive. If you were to stop waiting and try again at the same time you'd likely succeed.

The c++ implementation of this does not run into this issue because it explicitly spins a special thread to listen by default.

For your sort of application the simplest thing to do is to query at time "0" which is a special case which will provide you with the transform for the latest common time across the spanning set.

Originally posted by tfoote with karma: 58457 on 2021-08-30

This answer was ACCEPTED on the original site

Post score: 1

Original comments

Comment by kurshakuz on 2021-08-31:
Thank you for explanation! It is clear now. Can you suggest any places to look for separate thread initialization and using? Should I look for general python resources or something tf2 specific?


Your Answer

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