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

subscribing to /tf returns only a partial list

asked 2021-04-24 18:12:20 -0500

dan gravatar image

updated 2021-04-24 20:39:57 -0500

jayess gravatar image

I am trying to get all of the tf frames and am subscribing to /tf I am using TFMessage which I expect to return an array of TransformStamped messages. It does do that, but the list is incomplete-- it seems to only return one section of transforms. Using rostopic echo /tf I see several transforms sections:

transforms: -

several TransformStamped messages will appear here

transforms: -

several different TransformStamped messages appear here

But when I try to subscribe in code, only one of those transforms sections show up:

from tf2_msgs.msg import TFMessage

msg = rospy.wait_for_message("/tf", TFMessage)

print("number of transforms in tf = ", len(msg.transforms))

for entry in msg.transforms:

     print(entry)

I just get a single section of transforms seen from rostopic echo /tf

What am I doing wrong?

edit retag flag offensive close merge delete

Comments

Some insight-- there are 4 different nodes publishing to tf, so any single tf message will only have the transforms from the node that published it. Now the question becomes how to know when you have received messages from all the nodes, so that you know you have received all the available transforms.

dan gravatar image dan  ( 2021-04-24 19:38:57 -0500 )edit

I believe this is by-design. Every broadcaster only 'knows' about its own transforms. Subscribing directly to the topic itself is not often done, as it's the job of Buffers and TransformListeners to consume those messages and build up the tree structure for clients.

Now the question becomes how to know when you have received messages from all the nodes, so that you know you have received all the available transforms.

as TF is an implementation of an asynchronously distributed tree structure, you can't know this. How would you define "all transforms" anyway, seeing as there is a time-dimension to it: node A could publish transform X at any point in time. Especially with dynamic applications this is not a strange thing to happen.


Could you perhaps tell us what you are trying to achieve? Your question reads as-if you're trying to do this to solve ...(more)

gvdhoorn gravatar image gvdhoorn  ( 2021-04-25 01:29:25 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2021-04-25 01:37:51 -0500

gvdhoorn gravatar image

(ignoring the xy-problem for now, I'll attempt to answer the current version of your question)

But when I try to subscribe in code, only one of those transforms sections show up:

from tf2_msgs.msg import TFMessage
msg = rospy.wait_for_message("/tf", TFMessage)
print("number of transforms in tf = ", len(msg.transforms))
for entry in msg.transforms:
     print(entry)

if this is really the complete program/script, then your observation is what I would expect.

With rospy.wait_for_message(..), you wait for exactly one message on the /tf topic, and then loop over all entries in the msg.transforms array and print(..) them.

As I wrote in my comment: messages on the /tf topic (and /tf_static) each only contain information from a single TF broadcaster (typically there is 1 broadcaster to 1 node).

As a consequence, TFMessages do not contain the "complete TF tree", but only the section(s) the publishing broadcaster knows about.

So if you only print a single message, it's to be expected you'll only see some transforms, as you look at whichever TFMessage rospy.wait_for_message(..) happened to receive just then.

rostopic echo will print all messages it receives on the topic you make it echo and it will only stop doing that after you shut it down. So instead of receiving and printing a single TFMessage, it happens to receive two (in your example). If you would have shut it down quickly enough, you'd also only seen a single one (or none actually).

edit flag offensive delete link more

Comments

Thanks, this explanation is very helpful. The overall objective is to find transforms for newly detected objects. The transforms are published from sensors that broadcast a transform for each of the objects seen by the sensor. Each sensor also publishes a topic containing names for each of the objects seen. With multiple sensors, it can be hard to find the name of a newly detected object's frame. Even if I know the generic name of the object (e.g., "hat"), there might be multiple objects with similar names (e.g., "hat1", "hat2"). An example of a complete frame name would be "sensor1_hat3_frame" I tried using tf_buffer, but found that the return from it was often incomplete. For example, it would return only 10 frame names when there were actually 20. Then a subsequent call would return all 20.

dan gravatar image dan  ( 2021-04-25 17:27:54 -0500 )edit

Pedantic, I know, but "result was incomplete" is not really something which is meaningful in an asynchronous distributed system. You asked for whatever your buffer is aware of at that time. The fact the result is not what you, as an outside observer with more information about the system, would consider "complete" or "correct" is not that important.

Could you edit your original post to include the description of your actual problem / use-case? We can probably suggest better approaches then, as using TF for what you describe is possible, but might not be the most efficient way to go about this.

gvdhoorn gravatar image gvdhoorn  ( 2021-04-26 01:30:28 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2021-04-24 18:12:20 -0500

Seen: 379 times

Last updated: Apr 25 '21