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

How to use transformListener to lookup very early Transform?

asked 2018-08-07 09:43:43 -0500

Miaow gravatar image

updated 2018-08-07 09:44:15 -0500

Now I have a .bag file,which contains some transform. Q:I want use tf.listener.lookupTransform() to get transform,but it throws exception

Requested time 976052877.783882021 but the earliest data is at time 1533652658.077350788,.....

I read the reference of listener.lookupTransform(),ros::Time(0) means use current time. So,what can I do to get the history Transform?

My code:

   try
        {
            _tf_listener.waitForTransform(_base_frame, _map_frame, 
                ros::Time(0), ros::Duration(10.0) );
            _tf_listener.lookupTransform(_base_frame,_map_frame,
                ros::Time(0),_map_to_base);
        }
        catch(tf::TransformException te)
        {
            ROS_ERROR("%s",te.what());
            ros::Duration(1.0).sleep();
            continue;
        }
...
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2018-08-07 10:28:26 -0500

updated 2018-08-08 05:59:48 -0500

The standard transform listener has a finite buffer size after which it 'forgets' earlier transforms so you won't be able to look them up any more.

You can create a transform listener with a very long duration of buffer like this:

ros::Duration tfCacheDuration;
tfCacheDuration = tfCacheDuration.fromSec(600);   // ten minute tf buffer!
tfListener = new tf::TransformListener(tfCacheDuration);

You can then use this to lookup transforms further in the past, as long as your bag file contains transforms for that time. I've never tried to see how long you can make this buffer, you could try hours and see what happens.

Hope this helps.

EDIT :

The TransformListener object contains a buffer of transforms which begins to fill up once the object has been created. Because of this the object needs to have been instantiated for a short period of time before it can lookup any transforms at all and it cannot lookup transforms before the time at which it was created.

In your case you'll want to create a single TransformListener when you're node starts and continue to use that same object the whole time your node is running. This way the largest possible buffer of transforms can be built up.

edit flag offensive delete link more

Comments

Thanks.I followed your way,but it still didn't work.

ros::Duration tfCacheDuration;
tfCacheDuration = tfCacheDuration.fromSec(55759976);
tf::TransformListener tf_listener(tfCacheDuration);
tf_listener.lookupTransform(_base_frame, _map_frame, ros::Time(0),_map_to_base);
Miaow gravatar image Miaow  ( 2018-08-07 21:04:34 -0500 )edit

See my edit above which should clarify how this works.

PeteBlackerThe3rd gravatar image PeteBlackerThe3rd  ( 2018-08-08 06:00:44 -0500 )edit

Plus you've set a buffer duration of two and a half years, which is probably a bit excessive!

PeteBlackerThe3rd gravatar image PeteBlackerThe3rd  ( 2018-08-08 07:04:07 -0500 )edit

Thanks for your answer. Because the 'tf' is from a ".bag",it may be many years old.(You can see it in the console log in my question.).

Miaow gravatar image Miaow  ( 2018-08-11 09:40:19 -0500 )edit

I solved it by another way: 1st. I can get 'scan' message from '.bag', and it has the same timestamp which I just need. 2nd. I use the timestamp to make a transform, then call transformPose() to get the right 'tf'.

Miaow gravatar image Miaow  ( 2018-08-11 09:41:17 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2018-08-07 09:43:43 -0500

Seen: 2,016 times

Last updated: Aug 08 '18