TF 与 /clock
需要:uBotROS 0.1.x(含依赖 uBotCore、uBotSensor)
了解 uBotROS 发布哪些 TF 变换,以及 /clock 怎样让 ROS 2 节点使用仿真时间。
图中的 imu_sensor、lidar_2d 和 rgb_camera 是各传感器 Frame Id 的默认值,基坐标系默认是 base_link,里程计坐标系默认是 odom。
| 变换 | 话题 | 何时发布 |
|---|---|---|
odom → base_link(动态) |
/tf |
第一个里程计传感器的每个有效样本 |
base_link → <传感器 frame>(静态) |
/tf_static |
组件初始化和 Refresh Sensor Publishers 之后,以及每次重连之后 |
<frame> → <frame>_optical(静态) |
/tf_static |
同上,只有相机 |
map → odom |
— | uBotROS 不发布,由 SLAM 或 AMCL 提供 |
base_link → <传感器 frame>是传感器的 frame 组件相对基组件的位置和朝向,去掉缩放,在组件初始化和Refresh Sensor Publishers时算一次。之后传感器相对机体移动,TF 不会更新。- 基组件是
Base Link Component;留空时用uBot Identity的Base Component,默认是根组件。 - 相机另外发布
<frame> → <frame>_optical:平移为零,旋转是四元数(x=-0.5, y=0.5, z=-0.5, w=0.5)。图像和camera_info的frame_id用光学系,约定是 z 向前、x 向右、y 向下。 - 里程计传感器没有静态 TF:它的
Frame Id(默认odom)是基坐标系的父坐标系,再发布base_link → odom会和动态的odom → base_link成环,并且与map → odom冲突。 - 其他传感器的 frame 恰好等于里程计坐标系时,也会被跳过并记一条 Warning;frame 等于基坐标系的传感器不需要静态 TF。
- 所有 Sensor Bridge 登记的静态变换,由子系统合并成一条锁存的
/tf_static消息,QoS 是 reliable / transient_local / 1。变换集合变化时和每次重连后,它会重新发布。 - 同一个 child frame 被多个组件设置时,后注册的生效,内容不同时记 Warning。
- 订阅
/tf_static的节点要用 transient_local,才能拿到锁存的消息。
动态 odom → base_link
Section titled “动态 odom → base_link”- 取所属 Actor 上第一个里程计传感器,每个有效样本发布一条到
/tf(reliable / volatile / 100),时间戳是样本的仿真时间。Publish Invalid Samples开启时,无效样本也发布。 - 前提是这个传感器跟踪的组件就是基组件,并且它的
Odometry Frame Id和Child Frame Id与组件的Odometry Frame和基坐标系一致。否则日志里记 Error,动态 TF 关闭,组件仍然是Ready。 Publish Dynamic TF和Publish Static Sensor TF可以分别关闭两类 TF。
同一个世界里有多个机器人时,/tf、/tf_static 和 /clock 是共享的,frame id 重名会冲突,静态 TF 里后注册的会覆盖先注册的。
- 开启
Prefix Frames with Namespace:所有 frame id 变成<namespace>/<frame>,例如robot1/base_link、robot1/odom和robot1/rgb_camera_optical。已经以命名空间开头的不会重复加,世界参考的位姿所用的world不加前缀。 - 或者给每个机器人设不同的
Base Frame Override和传感器Frame Id。
/clock 与 use_sim_time
Section titled “/clock 与 use_sim_time”- 子系统在
Publish Clock开启(默认)且桥已连接时,每个世界 Tick 向Clock Topic(默认/clock)发布一条rosgraph_msgs/msg/Clock,QoS 是 reliable / volatile / 10。 - 时间是 uBot 仿真时间,基准是世界的游戏时间,遵循暂停和时间膨胀,不是墙上时间。每个新的 PIE 或 Game 会话从 0 开始,见仿真时钟与采样调度。
- 暂停时子系统仍在 Tick,所以
/clock继续以冻结的值发布;暂停时传感器不采样。 Clock Topic在运行中改动会重建发布者;它不是合法的绝对话题时,/clock不发布,日志里记一条 Warning。
ROS 2 节点要使用仿真时间,启动时把 use_sim_time 设为 true:
ros2 run <package> <executable> --ros-args -p use_sim_time:=trueros2 launch <package> <launch file> use_sim_time:=true # 取决于 launch 文件是否暴露该参数新的 PIE 会话把时间重新从 0 开始,对 ROS 2 来说是时间回跳,TF 缓冲等通常会被清空。桥节点本身不使用时间戳。
- 发布传感器数据:传感器消息的
frame_id和时间戳。 - 坐标系与单位:UE 到 ROS 的位置、旋转和角速度换算。
- 标识与命名:命名空间和基坐标系怎么确定。
- uBotROS 设置项:
Publish Clock和Clock Topic。