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

tf2 starts saying frame doesn't exist

asked 2021-12-01 08:54:35 -0600

morten gravatar image

updated 2021-12-02 03:35:27 -0600

I have a problem where whenever I ask for a transform, the very first tf2 message returns with a "frame does not exist error", this is causing problems down the line for my functions. My node is in c++ and using tf_buffer->transform() but I experience the same behavior in terminal.

Test

Set up the transforms in one terminal with

$ ros2 run tf2_ros static_transform_publisher 0 0 0 0 0 0 frame1 frame2
[INFO] [1638370239.897375496] [static_transform_publisher_CmYNZrUxpQX1bhQB]: Spinning until killed publishing transform from 'frame1' to 'frame2'

Then echo the transform in another terminal by

$ ros2 run tf2_ros tf2_echo frame1 frame2
[INFO] [1638370253.913909210] [tf2_echo]: Waiting for transform frame1 ->  frame2: Invalid frame ID "frame1" passed to canTransform argument target_frame - frame does not exist
At time 0.0
- Translation: [0.000, 0.000, 0.000]
- Rotation: in Quaternion [0.000, 0.000, 0.000, 1.000]

Obviously the transform exists, but without fail I am guaranteed that the first attempt throws a tf2::LookupException.

Edit

My original confusion stems from my attmpt to use transform, like

tf_->transform(in_pose, out_pose, target_frame,
                   tf2::Duration(std::chrono::seconds(5)));

Where tf_ is a std::shared_ptr<tf2_ros::Buffer>, this not finding a transform doesn't make sense to me. I've checked, using ros2 run tf2_tools view_frames.py, that the transform from in_pose frame to target_frame exists and is published with 30Hz, therefore 5 seconds should be more than enough to find it. But somehow it asserts that one of the frames doesn't exist?

Note, buffer is initialized in constructor, and this transform happens in an action server, prompted by a client. So there is significant delay between when the server is started and the client is run. Note, also this is wrapped with try and catch statements, this formulations throws a LookupException with the exception saying:

"map" passed to lookupTransform argument target_frame does not exist.
edit retag flag offensive close merge delete

Comments

Hi @morten, have you considered using waitForTransform? http://wiki.ros.org/tf/Tutorials/tf%2...

osilva gravatar image osilva  ( 2021-12-01 09:41:17 -0600 )edit

Re your edit. Do you have a tf2_ros::TransformListener constructed and updating the buffer? Tutorial on writing a c++ listener

tfoote gravatar image tfoote  ( 2021-12-02 03:53:20 -0600 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2021-12-01 11:37:29 -0600

tfoote gravatar image

The tf system is a distributed system. It takes time to initialize the communications and communicate information across the network.

If you look at all the tutorials, they always are written in a way to be robust to a missing transform and just retry on the next cycle: tf2 Listener Tutorial

As @osilva mentioned if you're doing a onetime operation you can consider using waitForTransform tf and time tutorial to wait for data to arrive.

edit flag offensive delete link more

Comments

It's for an action, so I figure waitForTransform is probably the best fit. I'll give that a try.

That being said, the fact that this LookupException happens so consistently the first time every time I echo transform just feels weird. Like there's something wrong. But who knows, maybe that's just how it is.

morten gravatar image morten  ( 2021-12-01 14:10:21 -0600 )edit

Well that suggests that the latency of setting up the connection is longer than the first polling in the local process. Which is actually not unexpected, establishing network connections takes time. The local buffer always starts empty and then needs to receive content.

tfoote gravatar image tfoote  ( 2021-12-01 16:39:45 -0600 )edit

Ye okay I see what you mean, I think I maybe just hadn't considered what was happening under the head with ros2 run tf2_ros tf2_echo frame1 frame2. But thanks!

Edit: I don't know if this is the appropriate place to ask, but is there a big difference between using waitForTransform and lookupTransform with a timeout?

morten gravatar image morten  ( 2021-12-01 16:49:40 -0600 )edit

Sorry old habit, in ROS 2 the lookupTransform now takes a timeout. In ROS 1 it was a separate call to waitForTransform

tfoote gravatar image tfoote  ( 2021-12-02 03:51:19 -0600 )edit

Ah okay, thanks.

morten gravatar image morten  ( 2021-12-02 03:56:26 -0600 )edit

Question Tools

2 followers

Stats

Asked: 2021-12-01 08:54:35 -0600

Seen: 2,165 times

Last updated: Dec 02 '21