07 TF、雷达模型与序列化
7.1 坐标系约定
默认(setParams):
1 | map_frame = map |
树:
1 | map ──(toolbox 发)──► odom ──(底盘发)──► base_footprint ──(URDF)──► laser |
GetPoseHelper 查的是 odom ← base_footprint。LaserAssistant::readLaserPose 查的是 base_footprint ← laser(扫描 stamp)。getLaser 失败日志:Failed to compute laser pose —— 静态 TF / URDF 没把 laser 接到 base_frame。
不要两个节点抢发 map→odom。
7.2 雷达模型:LaserAssistant
文件:src/laser_utils.cpp。
第一次见到某个 frame_id:
readLaserPose():tf->transform(laser恒等, base_frame_)isInverted:把 base 的 z 轴变到雷达系,变完后 z≤0 视为倒置,后续距离倒序makeLaser:SetOffsetPose(x, y, mountingYaw)—— 只用平面 x,y 和 yaw,忽略雷达相对底盘的 z/pitch/roll(2D 假设)min_laser_range/ 消息range_min取合理下界max_laser_range同时是匹配用的RangeThreshold(超消息range_max会警告并截断)- 角范围接近 2π 标成 360° 雷达;若多一个点([0,360] 而不是 [0,360))会强制非 360,避免 2021-03 那类坐标系 bug
dataset_->Add(laser) 后,序列化会带上这份雷达模型。换雷达或改外参应重新建图,不要混用旧 .data。
7.3 序列化文件
serialization.hpp:
| 文件 | 内容 |
|---|---|
<stem>.posegraph |
Mapper::SaveToFile:图、节点位姿、约束 |
<stem>.data |
Dataset::SaveToFile:雷达模型 + 扫描读数 |
服务 serialize_map 的 filename 不要带扩展名。save_map 是另一回事:包 map_saver 出 pgm + yaml,给 AMCL / 显示用,不能拿来 deserialize_map。
定位 / 续建必须用 .posegraph + .data。
2021-03 ABI
扫描在优化器里的存储坐标系修过一次。360° 或斜装雷达的旧文件,在新代码里可能炸图或翻转。新项目只用新代码建的图。选项见官方 README。
7.4 反序列化后如何对齐
deserializePoseGraphCallback 读文件 → loadSerializedPoseGraph(节点/边灌进 Ceres 并 Compute)→ updateMap → 按 match_type 设 processor_type_:
| match_type | 下一帧 |
|---|---|
START_AT_FIRST_NODE |
ProcessAtDock,假定还在起点附近 |
START_AT_GIVEN_POSE |
PROCESS_NEAR_REGION + initial_pose(map 系 base) |
LOCALIZE_AT_POSE |
定位模式 + 附近匹配 |
YAML 启动加载:map_file_name + (map_start_pose: [x,y,yaw] 或 map_start_at_dock: true)。两者都给时用 pose。
7.5 续建时的 reprocessing_transform_
新旧会话的轮速 odom 原点不同。dock / near-region 对齐成功后,setTransformFromPoses(..., update_reprocessing_transform=true) 估一个齐,之后 getLocalizedRangeScan 先乘它再进 Karto。没对齐就续建,图会在旧图旁边另起一摊。
正在加载留言…