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

TransformListener object should be scoped

asked 2021-09-03 01:56:02 -0600

Ben222 gravatar image

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?

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted
3

answered 2021-09-03 03:35:26 -0600

updated 2021-09-03 03:39:00 -0600

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.

edit flag offensive delete link more

Comments

1

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.

gvdhoorn gravatar image gvdhoorn  ( 2021-09-03 03:51:29 -0600 )edit

Yep, I liked your answer too!

Martin Günther gravatar image Martin Günther  ( 2021-09-03 03:56:14 -0600 )edit
2

answered 2021-09-03 03:46:56 -0600

gvdhoorn gravatar image

updated 2021-09-03 03:50:55 -0600

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 ... (more)

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2021-09-03 01:56:02 -0600

Seen: 349 times

Last updated: Sep 03 '21