7. 传感器与地图消息
本文详述 sensor_msgs、map_msgs 及 PointCloud2 工具链。
7.1 sensor_msgs
头文件:autonomy/commsgs/sensor_msgs.hpp
7.1.1 激光雷达
LaserScan
字段 |
类型 |
说明 |
|---|---|---|
|
|
时间戳 + |
|
|
起始角度 (rad) |
|
|
结束角度 (rad) |
|
|
角度步进 (rad) |
|
|
测量间隔 (s) |
|
|
扫描周期 (s) |
|
|
有效量程 (m) |
|
|
距离读数 |
|
|
反射强度 |
commsgs::sensor_msgs::LaserScan scan;
scan.header.frame_id = "laser";
scan.angle_min = -M_PI;
scan.angle_max = M_PI;
scan.angle_increment = M_PI / 180.0;
scan.range_min = 0.1f;
scan.range_max = 30.0f;
scan.ranges.resize(360, std::numeric_limits<float>::infinity());
7.1.2 IMU
Imu
字段组 |
字段 |
说明 |
|---|---|---|
方向 |
|
融合后姿态 |
角速度 |
|
rad/s |
线加速度 |
|
m/s² |
协方差 |
|
3×3 行主序 |
协方差 |
|
3×3 |
协方差 |
|
3×3 |
协方差
-1表示未知orientation全零表示不提供方向估计
7.1.3 点云
PointCloud2
字段 |
类型 |
说明 |
|---|---|---|
|
|
时间戳 + 坐标系 |
|
|
行数(无序点云为 1) |
|
|
列数(总点数 = height × width) |
|
|
字段描述 |
|
|
字节序 |
|
|
单点字节数 |
|
|
单行字节数 |
|
|
二进制点云数据 |
|
|
是否无 NaN/Inf |
PointField
字段 |
类型 |
说明 |
|---|---|---|
|
|
字段名( |
|
|
在点内的字节偏移 |
|
|
数据类型枚举 |
|
|
元素数量 |
datatype 枚举:
值 |
常量 |
C++ 类型 |
|---|---|---|
1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
PointCloud(旧格式,含ChannelFloat32)已标记 deprecated,推荐使用PointCloud2。
7.1.4 相机
类型 |
关键字段 |
用途 |
|---|---|---|
|
|
原始图像 |
|
|
压缩图像(JPEG/PNG) |
|
|
相机标定 |
|
|
ROI |
CameraInfo 矩阵:
K = [fx 0 cx] 内参(3×3 行主序,9 元素)
[ 0 fy cy]
[ 0 0 1]
P = [fx' 0 cx' Tx] 投影矩阵(3×4 行主序,12 元素)
[ 0 fy' cy' Ty]
[ 0 0 1 0]
7.1.5 其他传感器
类型 |
用途 |
|---|---|
|
超声波/红外测距 |
|
手柄输入 |
|
光照度 |
|
电池状态(proto 别名) |
7.1.6 转换完整度
类型 |
ToProto |
FromProto |
|---|---|---|
|
⏳ 部分 |
⏳ 部分 |
|
⏳ 部分 |
⏳ 部分 |
|
⏳ 部分 |
⏳ 部分 |
|
⏳ 部分 |
⏳ 部分 |
|
⏳ 部分 |
⏳ 部分 |
7.2 PointCloud2 工具链
7.2.1 PointCloud2Modifier
头文件:autonomy/commsgs/point_cloud2_iterator.hpp
便捷设置字段与大小:
commsgs::sensor_msgs::PointCloud2Modifier modifier(cloud);
modifier.setPointCloud2FieldsByString(4, "x", "y", "z", "intensity");
modifier.resize(num_points);
方法 |
说明 |
|---|---|
|
按名称/类型/数量设置字段 |
|
按字符串简写( |
|
设置点数并分配 data |
|
预分配 |
|
清空 |
7.2.2 PointCloud2Iterator
按字段名遍历点云:
commsgs::sensor_msgs::PointCloud2Iterator<float> iter_x(cloud, "x");
commsgs::sensor_msgs::PointCloud2Iterator<float> iter_y(cloud, "y");
commsgs::sensor_msgs::PointCloud2Iterator<float> iter_z(cloud, "z");
for (size_t i = 0; i < cloud.width; ++i, ++iter_x, ++iter_y, ++iter_z) {
*iter_x = points[i].x;
*iter_y = points[i].y;
*iter_z = points[i].z;
}
只读版本:PointCloud2ConstIterator<T>。
使用方:autonomy/map/costmap_2d/layers/obstacle_layer.cpp、voxel_layer.cpp。
7.2.3 point_field_conversion
头文件:autonomy/commsgs/point_field_conversion.hpp
编译期类型映射:
// enum → C++ 类型
using T = commsgs::sensor_msgs::pointFieldTypeAsType<
commsgs::sensor_msgs::PointField::FLOAT32>::type; // float
// C++ 类型 → enum
constexpr auto dt = commsgs::sensor_msgs::typeAsPointFieldType<float>::value;
// 从 buffer 读取
float val = commsgs::sensor_msgs::readPointCloud2BufferValue<float>(data_ptr, datatype);
7.3 map_msgs
头文件:autonomy/commsgs/map_msgs.hpp
7.3.1 静态栅格地图
OccupancyGrid
字段 |
类型 |
说明 |
|---|---|---|
|
|
|
|
|
分辨率、尺寸、原点 |
|
|
行主序栅格值 |
data 值语义:
值 |
含义 |
|---|---|
|
未知 |
|
自由 |
|
概率占据 |
|
完全占据 |
MapMetaData
字段 |
类型 |
说明 |
|---|---|---|
|
|
地图加载时间 |
|
|
m/cell |
|
|
栅格尺寸 (cells) |
|
|
左下角 (0,0) 的世界坐标 |
OccupancyGridUpdate
增量更新:x, y, width, height 定义矩形区域 + vector<int8> data。
7.3.3 GridMap(2.5D 多层栅格)
类型 |
说明 |
|---|---|
|
分辨率、尺寸、中心位姿 |
|
|
|
决定有效性的基础层 |
典型层名:"elevation", "traversability", "cost"。
7.3.4 3D 地图
类型 |
说明 |
|---|---|
|
八叉树二进制序列化 |
|
带位姿的八叉树 |
|
体素栅格 |
7.3.5 辅助类型
类型 |
说明 |
|---|---|
|
2D 栅格单元点集 |
7.3.6 转换完整度
类型 |
ToProto |
FromProto |
|---|---|---|
|
⏳ 部分 |
⏳ 部分 |
|
⏳ 部分 |
⏳ 部分 |
|
⏳ 部分 |
⏳ 部分 |
|
✅ 大部分 |
✅ 大部分 |
7.4 数据流:传感器 → 代价地图
LaserScan / PointCloud2
│
▼
obstacle_layer(PointCloud2Iterator 解析 xyz)
│
▼
Costmap2D(内部 uint8 数组)
│
▼
map_msgs::Costmap(发布/可视化)
7.5 stereo_msgs
头文件:autonomy/commsgs/stereo_msgs.hpp
类型 |
说明 |
|---|---|
|
|
用于双目立体视觉深度估计。
7.6 使用建议
场景 |
推荐消息 |
注意事项 |
|---|---|---|
2D 导航地图 |
|
|
实时避障 |
|
253/254 为障碍 |
3D 地形 |
|
多层 float,注意 |
激光输入 |
|
检查 |
3D 障碍 |
|
使用 Modifier + Iterator 构造 |
相机标定 |
|
K 全零表示未标定 |