0
$\begingroup$

Rosanswers logo

I am reading the tutorial on TF and it says:

The TransformListener object should be scoped to persist otherwise it's cache will be unable to fill and almost every query will fail.

could you explain what it means?


Originally posted by Ben222 on ROS Answers with karma: 1 on 2021-09-03

Post score: 0

$\endgroup$

2 Answers 2

1
$\begingroup$

Rosanswers logo

It means that you should make sure that the TransformListener is not deleted and re-created all the time. When you create the object, it starts listening to th /tf topic and fills it cache. It can only answer queries about the time interval that it has cached internally. So if you delete and re-create it all the time, it won't have time to fill its cache, and almost all queries will fail.

Compare the following two snippets of code:

Version 1 (correct)

  tf::TransformListener listener;

  while (node.ok()){
    tf::StampedTransform transform;
    try{
      listener.lookupTransform("/turtle2", "/turtle1", ros::Time(0), transform);
    }
    catch (tf::TransformException &ex) {
        // ...
  }

Version 2 (wrong)

  while (node.ok()){
    tf::TransformListener listener;
    tf::StampedTransform transform;
    try{
      listener.lookupTransform("/turtle2", "/turtle1", ros::Time(0), transform);
    }
    catch (tf::TransformException &ex) {
        // ...
  }

In the first version, the listener object is created only once. In the second version, the listener object is created, deleted and re-created on each iteration of the while loop.

If your lookup code is inside a C++ class, it's best to make the TransformListener a member variable of that class and initialize it only once inside the constructor.


Originally posted by Martin Günther with karma: 11816 on 2021-09-03

This answer was NOT ACCEPTED on the original site

Post score: 3


Original comments

Comment by gvdhoorn on 2021-09-03:
Oh, sorry. Appears we were writing our answers at the same time, and I didn't see yours.

I like how yours explains the implementation side of the quote, while I understood the question from the OP as to be more about the theory behind it.

Comment by Martin Günther on 2021-09-03:
Yep, I liked your answer too!

$\endgroup$
1
$\begingroup$

Rosanswers logo

This is really more of a programming question than something specific to ROS.

But to clarify the comment in the tutorial you refer to:

a scope would be (from wikipedia/Scope):

[..] the part of a program where [a] name [..] is valid, that is where the name can be used to refer to the entity.

So a scope is a section of a program where it's possible for the compiler to figure out what object or variable you refer to when you give it a specific name. In typical program languages, examples of such "sections" would be functions, methods, classes, closures and a root scope (called "global scope" below).

If you try to refer to a variable which is not in "the current scope" (or one of the parent scopes, as they are nested in a parent<-child relationship), the compiler will complain, as it cannot figure out what you are referring to.

More specifically for C++ (from the same page):

All the variables that we intend to use in a program must have been declared with its type specifier in an earlier point in the code, like we did in the previous code at the beginning of the body of the function main when we declared that a, b, and result were of type int. A variable can be either of global or local scope. A global variable is a variable declared in the main body of the source code, outside all functions, while a local variable is one declared within the body of a function or a block.

This also implies that the scope defines the region in a program where a variable "lives", or is "active" (it would be more correct to say when, but that wouldn't be a proper sentence).

Now as to your question:

The TransformListener object should be scoped to persist otherwise it's cache will be unable to fill and almost every query will fail.

So the comment suggests you want to make sure the TransformListener is "active" (or "is alive") in a scope which is around for longer than a single function call, as any object or variable in a function call scope is only alive for the period of time the CPU needs to execute that function (which is typically on the order of a couple hundred milliseconds, but depends on what the function does of course).

The reason this is important for TransformListener, is that objects of that type need time to listen in on the ROS messages on the /tf topic. They gather those messages, process them and then use the information from those messages to allow you to perform "TF lookups" and "TF transformations".

If you don't give a TransformListener that time, it will not have received any messages (so in essence, it's "empty") and when you then ask it to "lookup frame X", it will not have heard anything about "frame X", and hence cannot help you. That's what the quote from the tutorial means when it states:

it's cache will be unable to fill and almost every query will fail.


Originally posted by gvdhoorn with karma: 86574 on 2021-09-03

This answer was NOT ACCEPTED on the original site

Post score: 2

$\endgroup$

Your Answer

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