小例子说明tf关系
底盘到激光的固定转换坐标
激光安装在车尾距离 18cm,角度180
tf参数:前三个为x,y,z平移;后四个为角度x,y,z,w
/base_link为 parnets frame; target frame
/laser 为 child_frame_id;source frame
-0.18 0 0 0 0 1 0
/base_link /laser 50"/>
base_link->laser (表示从地盘到激光的坐标系的位置变换关系;或者说以base_link为基准坐标系(参考系),laser坐标系在base_link坐标系的位姿;
lookupTransform()不论target_frame,source_frame传入
前后顺序如何,都是得到的base_link->laser的相同坐标系转换关系)
source frame\target frame是在进行坐标变换时的概念,source是坐标变换的源坐标系,target是目标坐标系。这个时候,这个变换代表的是坐标变换。source坐标系下的点在target坐标系下的表示
parent、child frame是在描述坐标系变换时的概念,parent是原坐标系,child是变换后的坐标系,这个时候这个变换描述的是坐标系变换,也是child坐标系在parent坐标系下的描述。
空间的变换关系补充(个人总结,便于记忆,可能不太能理解,可忽略):假设有坐标系原点为O,平面上有两个点A,B;这里有个向量类比关系:
AB = AO + OB
现在在空间有一个点O在坐标系A中的位姿(坐标和角度)为A1,在坐标系B中的位姿(坐标和角度)为B1; 有两个坐标的 变换关系为 :
A1B1 = A1 * B1.inverse
A1B1表示B在A系中的位姿(或者以A系为参考系,B的位姿)
A表示se3的位姿,B.inverse表示在B系中的矩阵的逆,可以用转置表示
https://blog.csdn.net/weixin_41995979/article/details/83051757
tf图形:
参见函数
lookupTransform(const std::string& target_frame, const std::string& source_frame,
const ros::Time& time, const ros::Duration timeout) const;
ROS之tf空间坐标变换完全详解_ros tf坐标变换_zhanghm1995的博客-CSDN博客
cartographer中map_link odom_link(里程计) base_link
tracking_frame publish_frame关系
-
来自tf的概念
特点: 树状结构,最顶上为基系(base),两两之间呈现父子关系;
一父可多子,一子不可多父(树);
一个节点维护一对父子关系;
需要不断的有数据发布来维护坐标之间的关系,完整的tf tree不能有任何断层的地方;
publish_frame 指发布给tf树的,不是说发布给我或者你的,为了维持
tf树状结构的关系的,这样可以得到任意两个tf树状结构中的关系(比如我们想要得到定位的导航
数据map->base_link).
carto 内部的tf关系:
参考:
ROS API reference documentation — Cartographer ROS documentation
carto 内部能够得到 map_link->base_link关系
外部可以得到odom_link->base_link
map_link->odom通过tf变换关系来
-
tracking_frame 与publish_frame关系
上面tf关系可以得出carto中的父子关系:
map -> odom -> base_link
Published frame 可以理解为map的子frame,如果有odom,通常将其设置为
Published frame,没有则设置为base_link(与tracking frame同);
Lua configuration reference documentation — Cartographer ROS documentation
carto 官网
Published frame: the child frame of the map frame when publishing the robot location (which is the complete map->tracking frame transform). If your tracking frame has no parents, you specify it directly as the published frame. If it does already have a parent, you specify the topmost frame with no parents (this is usually the case when you already have an odom frame as a parent to the tracking frame. You specify odom as the published frame.)
Perhaps this setting would be more clear if called “map child frame”.
provide_odom_frame 是carto内部发出的位置信息;
use_odometry为外部提供的里程计数据给carto.
Use_odometry: whether to use the odom topic in slam as prior. Completely unrelated to tf.
Provide odometry: if you want smooth odometry-like localization in your tf tree (smooth, but drifting), you can have cartographer provide one for you. “odom_frame” is the frame in which such odometry is published. You also need to adjust the published frame above (the map child frame) as well.
The order should be map -> odom -> base_link. map -> odom is provided by Cartographer. odom -> base_link can be provided either by an external odometry or by Cartographer itself (see the documentation, provide_odom_frame parameter).
map, odom and base_link line up at the very beginning. This is expected behavior.
Confusion about TF frames used · Issue #300 · cartographer-project/cartographer_ros · GitHub
cartographer 内部默认使用 里程计的frame_id为odom
TF参考
ROS中TF(坐标系转换)原理与使用 (这篇我觉得讲得不错,讲得到位)_ros 中map的tf坐标_TYINY的博客-CSDN博客
map_link odom_link base_link