3、环境感知基础:坐标系与坐标变换、点云预处理、障碍物检测与栅格地图

各位同学好,我是老张。今天咱们聊点实在的——环境感知。说白了,就是让机器人知道「我在哪,周围有啥」。这是所有避障策略的基石。你想想看,如果连障碍物都检测不准,后面谈什么动态避障都是白搭。

我个人习惯把环境感知拆成四个模块来讲:坐标系变换、点云预处理、障碍物检测、栅格地图构建。咱们一个一个来。

3.1 坐标系与坐标变换

做机器人这么多年,我见过太多新手在坐标变换上栽跟头。其实没那么玄乎,就是几个坐标系之间的换算。

常用的坐标系就这几个:

  • 世界坐标系(map):全局固定,机器人定位用的
  • 机器人坐标系(base_link):以机器人中心为原点
  • 传感器坐标系(laser_frame, camera_frame):雷达或相机自己的坐标系

嗯,这里要注意:所有传感器数据最终都要转换到 base_link 或 map 下,不然你没法用。

核心公式(齐次变换矩阵):

# 假设已知激光雷达相对于机器人底盘的变换 T_laser_to_base
# 激光点 p_laser = (x, y, z, 1)
# 转换到机器人坐标系:
p_base = T_laser_to_base * p_laser

我在项目中遇到过最坑的事:激光雷达装歪了1度,结果建图时墙都是斜的。后来我养成了个习惯——每次装传感器都先做一次手眼标定,用 tf2 工具链验证一下。

我的小技巧:在 ROS 里用 tf2_echo 实时查看两个坐标系之间的变换,比看代码直观多了。

3.2 点云预处理:滤波与降采样

原始点云数据量太大,直接处理会卡死。我刚开始做的时候,16线激光雷达每秒30万点,CPU直接飙到100%。后来学乖了——先预处理。

3.2.1 直通滤波

说白了就是切掉没用的区域。比如机器人高度1米,那2米以上的点云直接扔掉。

# PCL 直通滤波示例
pass.setFilterFieldName("z")
pass.setFilterLimits(0.0, 1.5)  # 只保留0~1.5米高度范围

3.2.2 体素滤波(Voxel Grid)

这是我最常用的降采样方法。把空间切成小立方体,每个立方体只保留一个点。效果立竿见影——点云量能降到原来的十分之一。

注意:体素大小别设太大。我试过设成0.2米,结果细柱子全被滤掉了,机器人直接撞上去。一般设0.05~0.1米比较稳妥。

3.2.3 统计滤波

用来去除离群点。每个点算一下周围邻居的平均距离,离群太远的直接干掉。

我曾经在室外测试时,一阵风吹过来,树叶全被当成障碍物。加上统计滤波后,那些稀疏的噪点就没了。

3.3 障碍物检测基础

预处理完的点云,接下来要找出哪些是障碍物。常用的方法就两种:

  1. 基于高度:地面以上的点就是障碍物。简单粗暴,适合平地场景。
  2. 基于聚类:把空间上靠近的点归为一类,每一类就是一个障碍物。

我个人更推荐聚类方法,尤其是 DBSCAN 算法。它不需要预先知道有多少个障碍物,而且能处理任意形状。

DBSCAN 核心参数:

参数含义我常用的值
eps邻域半径0.3~0.5米
min_points最少点数5~10个

为什么选0.3米?因为一般行人的宽度在0.5米左右,设太小会把一个人拆成两半,设太大又会把两个人合并成一个。嗯,这个值需要根据传感器分辨率调一调。

3.4 栅格地图构建

最后一步,把检测到的障碍物信息映射到栅格地图上。栅格地图说白了就是一个二维数组,每个格子存一个概率值——表示这个格子被占用的可能性。

常用的更新公式是贝叶斯滤波:

# 对数几率形式
odds = p / (1 - p)
log_odds = log(odds)

# 更新
log_odds_new = log_odds_old + log_odds_measurement

这样做的好处是:多次观测同一个格子,置信度会越来越高。我见过有人直接用0/1二值化,结果一次误检测就导致地图崩了。

避坑指南:我曾经在构建栅格地图时,忘了考虑机器人自身的位姿不确定性。结果地图越建越歪。后来加上了EKF(扩展卡尔曼滤波)对位姿进行平滑,地图质量明显提升。

栅格地图的分辨率也是个关键。0.05米/格适合室内精细导航,但计算量大。0.1米/格适合室外,效率高但细节少。我一般先试0.05米,如果CPU扛不住再降。

环境感知核心流程 传感器数据 激光雷达/相机 坐标变换 tf2 / 齐次矩阵 点云预处理 滤波 → 降采样 障碍物检测 DBSCAN聚类 栅格地图构建 贝叶斯更新 避障决策输入

这张图把整个流程串起来了。从传感器原始数据开始,经过坐标变换、点云预处理、障碍物检测,最后生成栅格地图,供避障算法使用。每一步都有坑,但每一步也都有成熟的解决方案。

好了,环境感知基础就讲到这里。记住一句话:感知的质量决定了避障的上限。后面讲动态避障策略时,你会发现所有高级算法都依赖这里的基础。

专注资料整理