这是激光雷达导航在人员密集场景里非常典型的问题。核心原因可以概括为一句话:导航系统通常假设环境的大部分结构是静态的,而大量人员会把激光雷达看到的“静态世界”变成一个持续变化的动态世界。

对于常见的 2D/3D LiDAR + SLAM + ROS Navigation/Nav2 系统,人员增多通常会从以下几个层面同时影响导航。

1. 激光雷达大量点云被人体遮挡

例如机器人原本靠墙、柱子、门框等固定结构进行定位:

正常情况:

墙 |                     | 墙
   |   * robot           |
   |                     |

雷达可以看到大量固定墙面
>>>>>>>>>>>>>>>>>>>>>>>>>

人员增多后:

墙 |   人 人 人 人        | 墙
   | 人  *robot  人       |
   |   人 人 人           |

雷达射线大量打在人身上
>>>>>>>>>>>>>>>>>>>>>>>>>

这时雷达真正测到的是:

人
人
人
人
少量墙
人
人

而地图中保存的是:

墙
柱子
门
固定障碍物

因此实时扫描 LaserScan/PointCloud2 和静态地图之间的匹配程度明显下降。

这会直接影响 AMCL、scan matching、ICP/NDT 或基于 LiDAR 的 SLAM 定位。


2. AMCL 的定位置信度会降低

如果使用 ROS / ROS2 中非常常见的:

map_server
   ↓
AMCL
   ↓
map -> odom

AMCL 会计算:

当前激光扫描在哪一个机器人位姿下,最符合地图?

例如本来有 1000 个激光点,其中:

800 个点来自墙、柱子、门
200 个点来自动态物体

AMCL 很容易判断机器人位置。

人员非常多时可能变成:

200 个点来自墙
800 个点来自人

那么扫描与静态地图不一致。

结果可能表现为:

  • 粒子分布开始变散;
  • 定位置信度下降;
  • map -> odom 出现抖动;
  • 机器人地图位置缓慢漂移;
  • 严重时发生 localization jump;
  • 机器人突然认为自己偏离了路径。

所以很多时候你看到的现象并不只是:

“人挡住了机器人。”

而是:

人群甚至影响了机器人“认为自己在哪里”。

这是更严重的问题。


3. 局部代价地图不断变化

Nav2/Navigation 通常会维护:

Global Costmap
Local Costmap

激光雷达探测到一个人后,这个人会被加入 obstacle layer:

        X X X
      X X X X X
        X 人 X
      X X X X X

X = inflation cost

但人是在移动的。

因此局部代价地图可能不断出现:

t0:
      人
R ----------> goal

t1:
          人
R ----------> goal

t2:
              人
R ----------> goal

规划器会不停重新计算:

原路径
   ↓
发现人
   ↓
重新规划
   ↓
人移动
   ↓
再次重新规划
   ↓
又有人出现
   ↓
再次规划

于是出现所谓的 planner oscillation / trajectory oscillation

实际机器人看起来就是:

走
↓
停
↓
向左
↓
停
↓
向右
↓
重新规划
↓
再停

甚至左右摇摆。


4. Inflation Layer 会让“一个人占据很大的空间”

这也是很多机器人在人群中表现特别差的重要原因。

假设一个人的实际横向宽度只有:

0.5 m

但代价地图配置:

inflation_radius: 0.8
robot_radius: 0.35

一个人最终影响的区域可能达到:

          1.6m+
     -------------
        人
     -------------

如果走廊本身只有:

2.0 m

两个人一站:

墙               墙
|      人   人     |
|                 |

Costmap 可能看到的是:

墙 XXXXXXXXXXXXXXX 墙
| XXXXXXXXXXXXXXX |
| XXXXXXXXXXXXXXX |

于是从规划器角度:

道路已经完全堵死。

即便肉眼看起来机器人其实还有空间可以穿过去。

所以人员一多,会出现:

No valid path
Failed to make progress
Goal failed
Local planner failed

之类的问题。


5. 动态人员很容易造成“幽灵障碍物”

假设人在这里:

t0:

Robot ---- 人

激光加入 Costmap。

随后人走了:

t1:

Robot ------------->

理论上这个障碍物应该被 clearing ray 清掉。

但实际中因为:

  • 激光遮挡;
  • ray tracing 参数;
  • clearing_range 太小;
  • obstacle persistence;
  • observation buffer;
  • 点云更新频率低;

可能导致:

人已经离开

但 Costmap 里:

XXXXXXXX
XXX障碍XXX
XXXXXXXX

仍然保留。

这就是所谓:

ghost obstacle / stale obstacle。

人员越多,残留障碍越明显。

因此机器人可能表现为:

前面明明没人,机器人却不走。


6. 人群会造成大量激光遮挡

这个问题尤其容易被忽略。

例如:

LiDAR ---------- 人 ----------- 墙

LiDAR 只能获得:

LiDAR -> 人

而获取不到:

LiDAR -> 墙

如果周围有很多人:

       人
   人     人
 人   LiDAR   人
   人     人
       人

雷达可能几乎看不到建筑固定结构。

这时对于 LiDAR SLAM / localization 来说,是非常糟糕的观测状态,因为:

可观测静态特征数量
        ↓↓↓

动态特征数量
        ↑↑↑

于是 scan matching 变得非常不稳定。


7. 对 SLAM 的影响比“纯导航”更严重

如果机器人还在边运行边建图:

LiDAR
 ↓
SLAM
 ↓
Map

那么 SLAM 有可能直接把人建进地图:

真实:

墙 ─────────────────

人员:

    人 人 人

错误地图可能变成:

墙 ─────────────────
    ██ ██ ██

过一会人走掉以后,地图中仍然存在这些“障碍”。

尤其使用:

  • Cartographer;
  • GMapping;
  • Hector SLAM;
  • Karto;
  • 某些 LIO/LOAM 系统;

如果动态点过滤做得不好,都可能出现类似问题。

因此人多场景最好不要直接把所有点用于建图。


8. 3D LiDAR 也会受到影响

有人会认为:

换 3D 激光雷达就没有这个问题。

其实不是。

3D LiDAR 点云中一个人可能产生几百到几千个点:

      ****
    ********
      ****
      ****
     ** **

如果有几十个人,大量点都是动态点。

对于:

ICP
GICP
NDT
LOAM
LIO-SAM
FAST-LIO

这类依赖点云匹配的算法来说,如果没有 dynamic object filtering,依然会对里程计造成影响。

尤其:

走廊
大厅
展馆
商场
车站

这种场景很明显。


从整个导航架构看,实际上会形成一条“干扰链”

可以把问题理解成:

人员增多
   ↓
LiDAR 动态点比例增加
   ↓
静态结构被遮挡
   ↓
Scan-to-map 匹配质量下降
   ↓
Localization 抖动
   ↓
Costmap 动态障碍大量增加
   ↓
Local Planner 不断重规划
   ↓
路径振荡 / 急停
   ↓
导航失败

所以实际项目里经常同时看到:

AMCL pose 抖动
+
local costmap 很乱
+
cmd_vel 一会正一会负
+
机器人频繁停顿

它们实际上很可能是同一个根因导致的。


怎么解决

如果是你现在做人形/双足机器人导航,我会优先从 定位、动态障碍处理、局部规划器 三方面处理,而不是单纯地调大 max_vel 或调小 inflation_radius

比较有效的一套方案是:

  1. 定位不要完全依赖 LiDAR。 将轮速/腿式里程计、IMU、LiDAR 融合,例如:
Leg/Odom ─┐
          ├─ EKF ── odom
IMU ──────┘

LiDAR localization
        ↓
     map->odom

这样人挡住 LiDAR 几秒钟时,机器人位置不会立刻崩掉。

  1. 做动态物体过滤。 在点云进入定位模块之前:
Raw LiDAR
   ↓
Ground removal
   ↓
Dynamic object detection
   ↓
Remove human points
   ↓
Localization / SLAM

如果有相机,可以使用:

Camera
 ↓
YOLO / segmentation
 ↓
Human mask
 ↓
LiDAR-camera projection
 ↓
去除 person 点云

这种方式通常比单纯依靠 LiDAR 好很多。

  1. 定位和避障使用不同数据。 这是实际工程里非常推荐的设计:
LiDAR
 │
 ├── 静态点 ──> Localization / SLAM
 │
 └── 全部点 ──> Obstacle Detection
                   ↓
                Costmap

注意这个区别:

人应该参与避障

但是:

人最好不要参与定位

这是两件完全不同的事情。

  1. 合理调整 Costmap。 比如 ROS2 Nav2 中至少要重点检查:
local_costmap:
  update_frequency:
  publish_frequency:
  rolling_window:
  width:
  height:
  resolution:

obstacle_layer:
  obstacle_max_range:
  raytrace_max_range:
  observation_persistence:

inflation_layer:
  inflation_radius:
  cost_scaling_factor:

人群环境通常要求:

较快 update_frequency
较合理的 clearing
不要过大的 inflation radius

否则一个人就可能“膨胀”成一堵墙。

  1. 使用更适合动态场景的局部规划器。 如果现在使用普通 DWA/DWB,在人群中比较容易产生:
左右振荡
频繁停车
局部极小值

可以考虑:

MPPI Controller
TEB
MPC

其中 Nav2 的 MPPI 对动态复杂环境通常比简单 DWB 更容易调出平滑效果。


尤其值得注意的是:对于人员密集场景,最有效的系统架构通常不是“让 LiDAR 忽略人”,而是让定位模块忽略动态人员,同时让避障模块继续看到人员。

也就是:

                        ┌── Static points ──> SLAM / Localization
LiDAR ── Dynamic Filter ┤
                        └── Raw/Dynamic ────> Costmap / Avoidance

IMU + Odom ────────────────> State Estimation

这样才能同时满足两个要求:

人不能把定位带偏,但机器人又必须能够避开人。

如果你当前用的是 ROS2 Humble + Nav2 + 2D LiDAR,我可以进一步直接给你画出一套“人员密集环境下 Nav2 激光导航”的完整节点架构,并给出 AMCL + costmap + MPPI 的具体参数调优建议。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐