2026.8.07-初入ros+slam+opencv第十二天-学习tf广播器
·
一、理论理解
1.TF:维护机器人各个坐标系之间位姿变换关系
举例:base_link 机器人底盘,laser_link 激光雷达,雷达装在底盘上方,需要告诉 ROS 雷达相对于底盘在哪。
2.TF广播器TransformBroadcaster:向外发布「子坐标系相对父坐标系」的位姿(平移 + 旋转)。传感器、底盘都要广播自己的坐标系。
3.TF 监听器 TransformListener:查询两个坐标系之间的变换,把数据从一个坐标系转换到另一个坐标系。导航算法、点云处理都靠监听。
4.父坐标系 / 子坐标系:描述:子坐标系相对于父坐标系的位置姿态
5.旋转不用手写矩阵,使用tf::Quaternion生成四元数。
6.ros::Time(0):获取缓存中最新的 TF 数据,新手固定写这个。
7.监听必须加try‑catch异常捕获,TF 找不到变换直接会让程序崩溃。
二、代码实现
// ROS核心头文件,提供节点初始化、句柄、时间、Rate、spinOnce等全部基础功能
#include <ros/ros.h>
// tf旧版广播器头文件,tf::TransformBroadcaster、tf::Transform、tf::Quaternion都在这里
#include <tf/transform_broadcaster.h>
// 程序入口 main函数
// argc:命令行参数个数;argv:命令行参数数组,ros::init会从这里提取ROS相关参数
int main(int argc, char** argv)
{
// ①ROS节点初始化
// 参数:命令行参数,节点名字:tf_broadcaster_node
ros::init(argc, argv, "tf_broadcaster_node");
// ②创建节点句柄nh
// 句柄相当于你程序和ROS系统沟通的手柄,发布、订阅、参数、tf都依赖它
ros::NodeHandle nh;
// ③设置循环频率对象 rate,10Hz,代表每秒循环执行10次,单次周期0.1s
ros::Rate rate(10);
// ④创建TF广播器对象 br
// TransformBroadcaster专门用来向外发布坐标变换消息,底层会自动订阅/tf话题
tf::TransformBroadcaster br;
// ⑤ROS主循环
// ros::ok() 判断节点是否正常运行;按下Ctrl+C,ros::ok()返回false,退出循环
while(ros::ok())
{
// transform:存储一组坐标变换,包含两部分:平移(origin) + 旋转(rotation)
tf::Transform transform;
// setOrigin() 设置平移部分
// tf::Vector3(x,y,z) 三维向量,单位米
// 含义:子坐标系laser_link,在父坐标系base_link下坐标(0, 0, 0.2),底盘正上方0.2米
transform.setOrigin(tf::Vector3(0.0, 0.0, 0.2));
// tf::Quaternion 四元数,ROS用来存储旋转姿态,避免欧拉角万向锁缺陷
tf::Quaternion q;
// setRPY(roll, pitch, yaw) 单位:弧度!不是角度
// roll:绕X轴旋转;pitch:绕Y轴旋转;yaw:绕Z轴旋转(机器人转向)
// 全部填0:代表没有任何旋转,laser_link和base_link朝向完全一致
q.setRPY(0,0,0);
// 将四元数旋转赋值给transform变换对象
transform.setRotation(q);
// ==========核心:广播TF变换 sendTransform==========
// StampedTransform:带时间戳的变换,TF的每条变换必须绑定时间
br.sendTransform(tf::StampedTransform(
transform, // 平移+旋转的数据
ros::Time::now(), // 时间戳:当前系统时间,标记这个变换生效的时刻
"base_link", // 父坐标系(参考基准)
"laser_link")); // 子坐标系:子相对于父的位置姿态
// 顺序千万不能写反:sendTransform(变换,时间,父,子)
// ros::spinOnce():处理ROS消息回调
// 当前程序只发TF,没有订阅回调,逻辑上可以不写;属于ROS代码规范,建议保留
ros::spinOnce();
// rate.sleep():休眠,保证整体循环维持10Hz。
// 会扣除掉上面代码执行消耗的时间,保证周期稳定0.1s
rate.sleep();
}
// main函数返回,程序结束
return 0;
}
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)