ros / common_msgs

Commonly used messages in ROS. Includes messages for actions (actionlib_msgs), diagnostics (diagnostic_msgs), geometric primitives (geometry_msgs), robot navigation (nav_msgs), and common sensors (sensor_msgs), such as laser range finders, cameras, point clouds.
http://wiki.ros.org/common_msgs
177 stars 191 forks source link

TransformStamped and tf2 Inconsistency #174

Closed amock closed 3 years ago

amock commented 3 years ago

Since I want to transform some points from the robot's base into the map space, I used the tf2 function lookupTransform with a target frame "map" (1st argument) and source frame "base" (2nd argument). Accordinging to the documentation of TransformStamped.msg

# This expresses a transform from coordinate frame header.frame_id
# to the coordinate frame child_frame_id
...

I assumed tf2 would fill the message like

TransformStamped T;
T.header.frame_id = "base";
T.child_frame_id = "map";

but it doesn't. The resulting message contains flipped child_frame_id and header.frame_id. So based on my assumptions, either the tf2 documentation or the TransformStamped documentation must be wrong. Or am I missing something here?

Thanks in advance, Alex

hidmic commented 3 years ago

Normally I'd suggest you make this question in https://answers.ros.org/, but in reflection, the phrasing is confusing.

IIUC, and @tfoote please correct me if I'm wrong, the Transform messages conventionally express the rotation and translation that the base frame axes would undergo to reach the child frame axes. That is the opposite of transforming coordinates defined in the base frame to coordinates in the child frame, which is why you get the flip. In your example, applying some:

TransformStamped T;
T.header.frame_id = "map";
T.child_frame_id = "base";

to a coordinate in the "base" frame will transform it to the "map" frame, which is what you get when calling lookupTransform().

tfoote commented 3 years ago

That is correct @hidmic

It's a common confusion and is why lookupTransform uses target and source frame which is explicity different than parent and child terminology for the transform trees themselves. And if you use the built in functions such as transformPoint you never even see the underlying transform.