subscribing to /tf returns only a partial list
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?
Asked by dan on 2021-04-24 18:12:20 UTC
Answers
(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, TFMessage
s 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).
Asked by gvdhoorn on 2021-04-25 01:37:51 UTC
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.
Asked by dan on 2021-04-25 17:27:54 UTC
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.
Asked by gvdhoorn on 2021-04-26 01:30:28 UTC
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.
Asked by dan on 2021-04-24 19:38:57 UTC
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
Buffer
s andTransformListener
s to consume those messages and build up the tree structure for clients.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 some other (your actual) problem. To avoid such an xy-problem, could you describe that problem?
Asked by gvdhoorn on 2021-04-25 01:29:25 UTC