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

tf listener cant look up transform frame

asked 2014-08-08 09:42:02 -0600

Orso gravatar image

updated 2014-09-22 17:25:20 -0600

I run tf tf_echo /Pioneer3AT/map /Pioneer3AT/base_link and compute exact data needed (so, everything is looking good so far):

...
At time 1407419581.729
- Translation: [-8.999, -22.000, 0.000]
- Rotation: in Quaternion [-0.000, 0.000, 0.850. 0.526]
             in RPY [0.000. -0.000, 2.034]
...

Working through the tutorials I come up with the following script for a tf listener:

import roslib
import rospy
import tf
import sys, traceback

if __name__ == '__main__':
    rospy.init_node('tf_P3AT')
    listener = tf.TransformListener()
    rate = rospy.Rate(10.0)

try:
    now = rospy.Time(0)
    (trans, rot) = listener.lookupTransform("/Pioneer3AT/map", "/Pioneer3AT/base_link", now)
except:
    traceback.print_exc(file=sys.stdout)​

The error I receive is as follows:

Traceback (most recent call last): File "/ros/hydro/catkin/src/ros-pioneer3at/scripts/tf_listener.py", Line 15, in <module> (trans, rot) = listener.lookupTransform("/Pioneer3AT/map", "/Pioneer3AT/base_link", now) LookupException: "Pioneer3AT/map" passed to lookupTransform argument target_frame does not exist

Have also tried the following bit of code using the tf and time tutorial:

import roslib
import rospy
import tf
import sys, traceback

if __name__ == '__main__':
    rospy.init_node('tf_P3AT')
    listener = tf.TransformListener()
    listener.waitForTransform("/Pioneer3AT/map", "Pioneer3AT/base_link", rospy.Time(), rospy.Duration(4.0)
    rate = rospy.Rate(10.0)

try:
    now = rospy.Time.now()
    listener.waitForTransform("/Pioneer3AT/map", "Pioneer3AT/base_link", now, rospy.Duration(4.0)
    (trans, rot) = listener.lookupTransform("/Pioneer3AT/map", "/Pioneer3AT/base_link", now)
except:
    traceback.print_exc(file=sys.stdout)​

This throws the following error:

Traceback (most recent call last): File "/ros/hydro/catkin/src/ros-pioneer3at/scripts/tf_listener.py", line 16, in <module> lisener.waitForTransform("/Pioneer3AT/map", "/Pioneer3AT/base_link", now, rospy.Duration(4.0)) Exception: lookup would require extrapolation into the past. Requested time 1407508275.045120001 but the earliest data is at time 1407508275.084692717, when looking up transform from frame [Pioneer3AT/base_link] to frame [Pioneer3AT/map]

Anyone have tips on where to start next?

edit 1:

Output from roswtf produces:

Loaded plugin tf.tfwtf

No package or stack in context

Static checks summary:

No errors or warnings

Beginning tests of your ROS graph. These may take awhile... analyzing graph... ... done analyzing graph running graph rules... ... done running graph rules running tf checks, this will take a second... ... tf checks complete

Online checks summary:

Found 1 warning(s). Warnings are things that may be just fine, but are sometimes at fault

WARNING The following node subscriptions are unconnected: * /nodelet_manager: * /Pioneer3AT/ps3joy/cmd_vel * /Pioneer3AT_gmapping: * /Pioneer3AT/laserscan * /tf_static * /Pioneer3AT_move_base: * /Pioneer3AT/move_base_simple/goal * /tf_static

edit 2:

Image result of rosrun rqt_tf_tree rqt_tf_tree

Here is an online link of pic: link text and here link text

edit 3:

Solution

Using the launch/core/urdf.launch listed here: https://github.com/dawonn/ros-pioneer... on git. A user needs to Look at line 6: This puts a prefix on published transforms from this node. Removing it or changing value to "", takes out undesired "Pioneer3AT".

A possible second fix, modify xacro file listed here: https://github.com/dawonn/ros-pioneer... on line 12, chassis link already has Pioneer3AT in its name. Try renaming it just ... (more)

edit retag flag offensive close merge delete

Comments

Not sure if syntax is same for python, but pulled from the tf listener tutorial: "The time at which we want to transform. Providing ros::Time(0) will just get us the latest available transform." Try doing at time 0 so you dont have a delay and just grab the latest transform. Maybe thatll help

l0g1x gravatar image l0g1x  ( 2014-08-08 10:04:29 -0600 )edit

I used now = rospy.Time(0) in my first bit of code above, from the tf listener tutorial, throwing back the first error. Then followed the tf time tutorial, producing the second bit of code. rospy.Time.now() does not accept arguments. Retried rospy.Time(0) in second bit code. Same error.

Orso gravatar image Orso  ( 2014-08-08 10:15:23 -0600 )edit

once everything is running, run roswtf and tell me if it gives you any errors.

l0g1x gravatar image l0g1x  ( 2014-08-08 10:27:39 -0600 )edit

3 Answers

Sort by » oldest newest most voted
3

answered 2014-08-08 11:01:17 -0600

l0g1x gravatar image

updated 2014-08-12 07:16:50 -0600

According to the tf python api docs here for waitForTransform, it tells you "Waits for the given transformation to become available. If the timeout occurs before the transformation becomes available, raises tf.Exception." Common thing alot of people have is that there is a delay in the broadcasted tf messages being sent somewhere in your tf tree. Could that somehow be a possibilty in your case?


EDIT: With the pictures that you have posted, it shows that you have two base_link frame:

  • Pioneer3AT/Pioneer3AT/base_link
  • Pioneer3AT/base_link

'Pioneer3AT_Gazebo' is broadcasting a transform from Pioneer3AT/odom --> Pioneer3AT/base_link (the tf tree on the right side of the image), but all of your wheels, sensors, top plate, axels, etc. are all being transformed into the frame Pioneer3AT/Pioneer3AT/base_link. This is where your problem is.

You can simply fix this by changing your Pioneer3AT_tf_broadcaster node to publish a transform from your sonars, axels, and top plate to frame id Pioneer3AT/base_link instead of Pioneer3AT/Pioneer3AT/base_link.

Should look something like this for the Pioneer3AT/front_sonar --> Pioneer3AT/base_link:

broadcaster.sendTransform(
            tf::StampedTransform(tf::Transform(tf::Quaternion(x, y, z, w), tf::Vector3(x, y, z)),
            ros::Time::now(),"Pioneer3AT/base_link", "Pioneer3AT/front_sonar"));

Hope that fixes it. Take out the Pioneer3AT/Pioneer3AT/base_link frame, switch it with Pioneer3AT/base_link, and your tf tree should be connected and you should be able to lookup the transform.


EDIT2:

As of right now, since you neither you nor I can find the tf broadcaster, the /Pioneer3AT/base_link and /Pioneer3AT/odom frames can be ignored. They will just be frames in our system (for now), so try to make your own broadcaster node that broadcasts just the transform from /Pioneer3AT/Pioneer3AT/base_link --> Pioneer3AT/odom.

Make sure you change the base_link frame in the Pioneer3AT core launch file here to "Pioneer3AT/Pioneer3AT/base_link". Leave all your other sensor frames how you had them originally (if you modified them).

This is just a temporary hack just so we can get this working.

edit flag offensive delete link more

Comments

Sometimes if your node's topic subscriber is receiving to many message, and your que size is fairly large, this can also cause the problem since the que will cause those messages to be delayed.

l0g1x gravatar image l0g1x  ( 2014-08-08 11:03:01 -0600 )edit

I run tf tf_echo /Pioneer3AT/map /Pioneer3AT/base_link and compute exact data needed. Have also tried increasing rospy.Duration() to longer times, still no change.

Orso gravatar image Orso  ( 2014-08-08 11:13:02 -0600 )edit

tf_echo only displays you the information between those two frames, so if there is a lag it wont matter. Its just like rostopic echo. Can you post a picture of your transform tree? rosrun rqt_tf_tree rqt_tf_tree. It will show us alot of detail about all your frames.

l0g1x gravatar image l0g1x  ( 2014-08-08 11:21:18 -0600 )edit

Here is an online link of pic:

link text

and here

link text

Orso gravatar image Orso  ( 2014-08-08 11:52:09 -0600 )edit
1

I have provided a solution below. You helped me work through the problem in knowing where to search, thanks!! I have yet to try your last solution, I will give it a try when I have the chance.

Orso gravatar image Orso  ( 2014-08-08 15:29:09 -0600 )edit

Wait, so you actually want to have two separate tress? And then just lookup the transform between then? If thats the case then sorry i wouldve formulated my answer differently.

l0g1x gravatar image l0g1x  ( 2014-08-08 16:14:27 -0600 )edit

Not at all. This stack is from here: link text i.e. not built by me. The easiest fix for me was my fix. I will try your fix, and update soon. Just need to know where to make the change of Pioneer3AT/Pioneer3AT/base_link frame. Thanks.

Orso gravatar image Orso  ( 2014-08-08 17:04:53 -0600 )edit

Tried locating the Pioneer3AT_tf_broadcaster node for edit, trying to combine the two trees as you have described. Could not find under the gitHub location here: link text

Orso gravatar image Orso  ( 2014-08-11 17:35:26 -0600 )edit
0

answered 2014-08-08 15:27:34 -0600

Orso gravatar image

updated 2014-08-08 15:30:54 -0600

Needed to import Odometry, which is where the /Pioneer3AT/base_link lies, and a few other changes. Code below for fix!!!

import roslib
import rospy
import tf
import sys, traceback
from nav_msgs.msg import Odometry

if __name__ == '__main__':
    rospy.init_node('tf_P3AT')
    listener = tf.TransformListener()
    rate = rospy.Rate(10.0)

while not rospy.is_shutdown():
    try:
        now = rospy.Time(0)
        (trans, rot) = listener.lookupTransform("/Pioneer3AT/map", "/Pioneer3AT/base_link", now)
    except: (tf.LookupException, tf.ConnectivityException):
        continue

    print 'translation: ',trans
    print 'rotation: ', rot

    rate.sleep()
edit flag offensive delete link more
0

answered 2014-08-08 11:19:46 -0600

ahubers gravatar image

updated 2014-08-08 11:25:11 -0600

In the past I've had this same issue (i.e, tf_echo works fine but I get told frame doesn't exist in my Python script) because the listener was not initialized soon enough before I asked for the transform. In my case it was telling me that the Kinect's camera_rgb_optical_frame didn't exist, which was asinine. It might be worthwhile to call rospy.sleep(10.0) right before (trans, rot) = listener.lookupTransform("/Pioneer3AT/map", "/Pioneer3AT/base_link", rospy.Time(0)) , just for debugging purposes.

edit flag offensive delete link more

Comments

Great, thanks for the tip. Good for allowing things like roswtf to run while processes like rosrun work. Any incite on this fix? How did you work through your previous case?

Orso gravatar image Orso  ( 2014-08-08 13:27:31 -0600 )edit

Question Tools

2 followers

Stats

Asked: 2014-08-08 09:42:02 -0600

Seen: 9,350 times

Last updated: Sep 22 '14