ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

2026.8.07-初入ros+slam+opencv第十二天-学习tf广播器

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相关参数intmain(intargc,char**argv){// ①ROS节点初始化// 参数:命令行参数,节点名字:tf_broadcaster_noderos::init(argc,argv,"tf_broadcaster_node");// ②创建节点句柄nh// 句柄相当于你程序和ROS系统沟通的手柄,发布、订阅、参数、tf都依赖它ros::NodeHandle nh;// ③设置循环频率对象 rate,10Hz,代表每秒循环执行10次,单次周期0.1sros::Raterate(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.1srate.sleep();}// main函数返回,程序结束return0;}
返回列表