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

Transform the coordinate frame of a pose from one fixed frame to another

asked 2019-05-13 11:11:23 -0600

singular.river gravatar image

I have a Pose message defined in a user preferred fixed reference frame. For planning, I would like to chance the reference coordinate system to "world" (which again is a fixed reference frame). Since these reference frames are part of robot definition in URDF - is there a simple way to transform pose from one reference frame to another without having to go through broadcasting and listening tf transformations? Even if I have to use the tf, does it require one to calculate the transforms and broadcast it? I tried using tf2_ros.Buffer.transform() method - but this does not seem to work unless, there is an explicit transform being broadcasted between the two frames? Thank you.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
4

answered 2019-05-14 13:06:09 -0600

singular.river gravatar image

Transforming a pose from one fixed coordinate frame to another seemed like a trivial problem. But I ended up spending lot of time researching the solution and came up with the following, I hope it helps others like me. There are couple of things that tripped me up. 1) Ensure that the PoseStamped that you are passing to transform() is from tf2_geometry_msgs and not geometry_msgs. 2) Use rospy.Duration() to wait for the listener to start listening.

# Transform a given input pose from one fixed frame to another
import rospy
from geometry_msgs.msg import Pose

import tf2_ros
import tf2_geometry_msgs  # **Do not use geometry_msgs. Use this instead for PoseStamped


def transform_pose(input_pose, from_frame, to_frame):

    # **Assuming /tf2 topic is being broadcasted
    tf_buffer = tf2_ros.Buffer()
    listener = tf2_ros.TransformListener(tf_buffer)

    pose_stamped = tf2_geometry_msgs.PoseStamped()
    pose_stamped.pose = input_pose
    pose_stamped.header.frame_id = from_frame
    pose_stamped.header.stamp = rospy.Time.now()

    try:
        # ** It is important to wait for the listener to start listening. Hence the rospy.Duration(1)
        output_pose_stamped = tf_buffer.transform(pose_stamped, to_frame, rospy.Duration(1))
        return output_pose_stamped.pose

    except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException):
        raise


# Test Case
rospy.init_node("transform_test")

my_pose = Pose()
my_pose.position.x = -0.25
my_pose.position.y = -0.50
my_pose.position.z = +1.50
my_pose.orientation.x = 0.634277921154
my_pose.orientation.y = 0.597354098852
my_pose.orientation.z = 0.333048372508
my_pose.orientation.w = 0.360469667089

transformed_pose = transform_pose(my_pose, "fixture", "world")

print(transformed_pose)
edit flag offensive delete link more

Comments

Ensure that the PoseStamped that you are passing to transform() is from tf2_geometry_msgs and not geometry_msgs

this should not actually be necessary. As long as you import tf2_geometry_msgs the conversion should be done automatically. tf2_geometry_msgs only provides functions to convert the messages to types and back.

gvdhoorn gravatar image gvdhoorn  ( 2019-05-14 13:52:37 -0600 )edit

for me it says:
tf2.ExtrapolationException: Lookup would require extrapolation into the past. Requested time 1614615266.814265490 but the earliest data is at time 1614615267.795055628, when looking up transform from frame [panda_link0] to frame

azerila gravatar image azerila  ( 2021-03-01 10:24:54 -0600 )edit

@azerila For some reason the TF buffer does not seem to have caught up to rospy.time.now(). You can try either increasing the rospy.Duration(1) from 1 to say 2 seconds - or change the rospy.Time.now() to rospy.Time(0). Please refer to ROS Answer at: https://answers.ros.org/question/2431.... Hope this helps.

singular.river gravatar image singular.river  ( 2021-03-01 20:20:20 -0600 )edit

For me it worked with rospy.Time(0). Thank you

vidaldani gravatar image vidaldani  ( 2022-04-22 14:09:08 -0600 )edit

I tested and confirm gvdhoorn's answer:

Ensure that the PoseStamped that you are passing to transform() is from tf2_geometry_msgs and not geometry_msgs

this should not actually be necessary. As long as you import tf2_geometry_msgs the conversion should be done automatically. tf2_geometry_msgs only provides functions to convert the messages to types and back.

burakaksoy gravatar image burakaksoy  ( 2022-04-25 21:40:59 -0600 )edit

Question Tools

3 followers

Stats

Asked: 2019-05-13 11:09:41 -0600

Seen: 13,590 times

Last updated: May 14 '19