ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

timeout in lookupTransform behaves differently in rclcpp and rclpy

asked 2021-08-28 11:45:10 -0500

kurshakuz gravatar image

updated 2021-08-30 14:53:52 -0500

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...

And the Python (which is failing) is here: https://github.com/kurshakuz/geometry...

The node is included in the launch file and is started there. I am launching: ros2 launch turtle_tf2_py turtle_tf2_demo.launch.pywhich starts the turtlesim, two broadcasters and listener. Link: https://github.com/kurshakuz/geometry...

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?

edit retag flag offensive close merge delete

Comments

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?

tfoote gravatar image tfoote  ( 2021-08-30 14:16:43 -0500 )edit

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.

kurshakuz gravatar image kurshakuz  ( 2021-08-30 14:56:40 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2021-08-30 16:56:25 -0500

tfoote gravatar image

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.

edit flag offensive delete link more

Comments

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?

kurshakuz gravatar image kurshakuz  ( 2021-08-31 00:11:31 -0500 )edit

Question Tools

2 followers

Stats

Asked: 2021-08-28 11:45:10 -0500

Seen: 672 times

Last updated: Aug 30 '21