0
$\begingroup$

Rosanswers logo

Hi all,

I have a question on how to obtain tf frames in a ros node (preferrably Python). I am aware of the method tf2_ros.Buffer.lookup_transform(), however, one has to specify source and target frame for that.

Lets say I have an array of known markers, but only a subset of them are detected by the camera. I want to know which of these markers are detected by looking at the existing tf frames. Is there a more elegant way to do so instead of looping over all possible markers and try to lookup the transform in a try catch block?

Thanks in advance!

P.S I am using kinetic on Ubuntu 16.04


EDIT:
In the tutorial TfUsingPython I found the method allFramesAsString() but it seems to use tf, not tf2. would there be an equivalence in tf2? Or is it generally a bad practice to mix the use of tf and tf2?


Originally posted by rfn123 on ROS Answers with karma: 146 on 2020-03-30

Post score: 0

$\endgroup$

3 Answers 3

0
$\begingroup$

Rosanswers logo

It seems #q261460 is at least a partial duplicate of your question.

In the tutorial TfUsingPython I found the method allFramesAsString() but it seems to use tf, not tf2. would there be an equivalence in tf2? Or is it generally a bad practice to mix the use of tf and tf2?

TF has been implemented on-top of TF2 for quite some time now, so you cannot really "mix" them: it would all be using TF2 in the end.

As to the method you found: there is tf2::BufferCore::allFramesAsYAML(double current_time) const in TF2 (and allFramesAsStringNoLock() is available as well).

The Python API of TF2 is essentially a mirror of the C++ API, so you should be able to call that from Python as well (I have not verified this).


Originally posted by gvdhoorn with karma: 86574 on 2020-03-30

This answer was ACCEPTED on the original site

Post score: 2


Original comments

Comment by rfn123 on 2020-03-30:
Since the Python API is rather poorly documented, here is sth if someone has the same problem as me: After some further research I found some example usage of the Python API here: examples_tf2_py. Probably this still does not contain all methods of the C++ API, but imo it's a good start.

$\endgroup$
0
$\begingroup$

Rosanswers logo

I ended up searching alternative to native tf library functions to solve my problem. The reason was that after getting allFramesAsYAML() (or in Python tfBuffer_ros.all_frames_as_yaml()) to work i found out that it will return all frames that have been in the tf buffer, regardless of whether the frame is in the current tf topic or not. The output was:

marker1: 
  parent: 'camera'
  broadcaster: '/marker_tracker'
  rate: 30.401
  most_recent_transform: 1585572193.003
  oldest_transform: 1585572190.503
  buffer_length: 2.500
marker2: 
  parent: 'camera'
  broadcaster: '/marker_tracker'
  rate: 30.457
  most_recent_transform: 1585572192.703
  oldest_transform: 1585572190.503
  buffer_length: 2.200
marker3: 
  parent: 'camera'
  broadcaster: '/marker_tracker'
  rate: 27.709
  most_recent_transform: 1585572195.538
  oldest_transform: 1585572191.568
  buffer_length: 3.970

I occluded marker2 after a while, and it still appeared in the output. The only difference is that "most_recent_transform" stopped updating.


Originally posted by rfn123 with karma: 146 on 2020-03-30

This answer was NOT ACCEPTED on the original site

Post score: 2


Original comments

Comment by gvdhoorn on 2020-03-30:\

The only difference is that "most_recent_transform" stopped updating.

doesn't that align with what you were trying to achieve? You wrote:

I want to know which of these markers are detected by looking at the existing tf frames

Thing is: TF frames "don't exist", so seeing whether they "still exist" is not really something you can do.

Even TF itself (ie: the internals of the provided libraries) will look at most_recent_transform to determine whether a transform is still up-to-date and relevant.

In your case you could see how long ago the transform was updated and determine -- based on some threshold -- whether the last detected pose for a marker is "too old".

Comment by rfn123 on 2020-03-30:
You are right, by looking at the update time I can filter the tfs. I was just rather looking for sth. simpler (e.g. boolean) that shows if a certain tf frame is updated or not, i.e. "existing", but I was not aware that the internal libraries use the mechanics of update time. Thanks for clarifying that!

Comment by gvdhoorn on 2020-03-30:\

I was just rather looking for sth. simpler (e.g. boolean) that shows if a certain tf frame is updated or not

well, think about it: what would it mean for a frame to "be updated or not"? How would TF determine this to set that boolean true or false?

Probably be comparing the time at which a frame was last updated to some sort of maximum allowable age .. :)

$\endgroup$
0
$\begingroup$

Rosanswers logo

Building off the other answers, here's a snippet of runnable code that I wound up with:

import rospy
import tf2_ros
import time
import yaml

rospy.init_node('ipython')

tf_buffer = tf2_ros.Buffer()
tf_listener = tf2_ros.TransformListener(tf_buffer)
time.sleep(5.0)

frames_dict = yaml.safe_load(tf_buffer.all_frames_as_yaml())
frames_list = list(frames_dict.keys())

(Tested on Ubuntu 20.04, running noetic)


Originally posted by lindzey with karma: 1780 on 2022-07-06

This answer was NOT ACCEPTED on the original site

Post score: 1


Original comments

Comment by 130s on 2023-05-04:
I tried porting your snippet into ROS2 but haven't had success so far. Spun off a new question Python's all tf frames function in ROS2 only returns some frames FYI.

$\endgroup$

Your Answer

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