第3章 路径规划 vs 轨迹规划:区别与联系

很多刚入行的朋友会问我:「路径规划和轨迹规划,到底是不是一回事?」

嗯,这个问题我当年也困惑过。记得刚做第一个移动机器人项目时,我以为规划出一条无碰撞的路径就完事了。结果机器人走起来一顿一顿的,电机还过热报警。后来才明白——路径规划和轨迹规划,根本是两个层次的事情。

3.1 核心区别:几何 vs 时间

说白了,路径规划只关心「走哪条路」,不关心「怎么走」。它输出的是空间中的一系列点——我们叫它路径点序列。而轨迹规划,是在路径的基础上,给每个点加上时间戳,告诉机器人「什么时候该到哪、速度多快、加速度多大」。

一句话总结:
路径规划 = 空间几何问题(避开障碍物)
轨迹规划 = 时空联合问题(满足运动约束)

我习惯用一个比喻来解释:

  • 路径规划 = 导航地图告诉你「从A到B走哪条路」
  • 轨迹规划 = 老司机告诉你「这段路限速60、前面弯道要减速到30、红灯前平稳刹停」

你看,路径规划的结果是静态的,而轨迹规划的结果是动态的。两者缺一不可。

3.2 路径点生成:从离散到连续

路径规划算法(比如A*、RRT、PRM)输出的是一堆离散的路径点。但这些点直接发给机器人?不行。为什么?

  • 点与点之间可能有尖锐拐角,机器人没法瞬间转向
  • 点间距不均匀,速度控制会忽快忽慢
  • 没有考虑机器人的动力学限制

所以我们需要对路径点做后处理。我在项目中常用的做法是:

  1. 路径简化:去掉冗余点,保留关键转折点
  2. 曲线插值:用样条曲线(B样条、三次样条)把离散点连成光滑曲线
  3. 路径重采样:在曲线上等间距或等弧长取点,保证后续时间参数化时的一致性
我的经验:
路径重采样时,我建议用等弧长采样而不是等参数采样。等参数采样在曲率大的地方点会变稀疏,导致后续轨迹规划时速度波动。这个坑我踩过,后来改用弧长参数化才解决。

3.3 时间参数化:给路径注入灵魂

路径点有了,接下来就是「时间参数化」。这一步把路径从几何空间映射到时域空间。

数学上,路径可以表示为 P(s),其中 s 是路径参数(比如弧长)。时间参数化就是找到 s(t) 的关系,最终得到 P(t) = P(s(t))。

常见的参数化方式有:

方法 原理 适用场景 缺点
匀速参数化 s(t) = v * t 简单演示、低精度任务 起停冲击大,不满足加速度约束
梯形速度曲线 匀加速-匀速-匀减速 工业机器人点对点运动 加速度突变,有冲击
S形速度曲线 加加速度连续变化 高精度、高舒适度场景 计算稍复杂
多项式参数化 用多项式拟合s(t) 连续轨迹跟踪 需要求解边界条件

我个人最常用的是S形速度曲线。虽然计算量比梯形大一点,但胜在运动平滑,电机寿命更长。有一次做协作机器人项目,用梯形曲线时末端抖动明显,换成S形曲线后问题就解决了。

3.4 速度/加速度约束:别让机器人「飞」起来

轨迹规划的核心约束有三个:

  • 速度约束:每个关节或末端执行器的最大速度
  • 加速度约束:最大加速度,防止结构损坏或工件掉落
  • 加加速度约束:最大加加速度(jerk),控制冲击和振动
注意:
很多初学者只考虑速度约束,忽略加速度约束。结果就是——路径规划没问题,但机器人一跑起来就报警「过流」或「跟踪误差过大」。我曾经在一个AGV项目上吃过这个亏,后来老老实实把加速度约束加进去,问题才解决。

约束的处理方式通常有两种:

  1. 先规划后检查:先生成轨迹,再逐段检查是否超限,超限则重新规划
  2. 约束嵌入规划:在规划过程中直接考虑约束,比如用凸优化或数值积分方法

第二种方法更优雅,但实现难度也更高。我建议初学者先从第一种入手,理解透了再上第二种。

3.5 路径规划与轨迹规划的协同工作流

下面这张图展示了从路径规划到轨迹规划的完整流程:

路径规划 → 轨迹规划 协同工作流 环境建模 地图、障碍物、起点终点 路径规划 A* / RRT / PRM 路径后处理 简化 / 插值 / 重采样 时间参数化 s(t) 映射 约束检查 速度 / 加速度 / 加加速度 轨迹输出 P(t) 时间序列 约束超限 → 重新参数化 💡 关键点: 1. 路径规划输出的是几何路径(离散点序列) 2. 轨迹规划在路径基础上加入时间信息,生成带速度/加速度约束的运动曲线 3. 约束检查不通过时,需要反馈回时间参数化步骤重新调整

3.6 一个完整的例子

假设我们要让机械臂从点A(0,0)运动到点B(1,1),中间经过一个障碍物。

步骤1:路径规划

路径规划算法给出路径点序列:(0,0) → (0.3,0.5) → (0.7,0.5) → (1,1)

步骤2:路径后处理

用三次样条插值,得到光滑曲线。然后等弧长采样,得到100个均匀分布的点。

步骤3:时间参数化

设定最大速度 v_max = 0.5 m/s,最大加速度 a_max = 0.2 m/s²。用S形速度曲线生成 s(t) 关系。

步骤4:约束检查

逐点检查速度和加速度是否超限。如果某段曲率过大导致向心加速度超限,就降低该段的速度。

步骤5:输出轨迹

最终输出 P(t) = (x(t), y(t)),每个时间点都有对应的位置、速度、加速度值。

代码片段:
下面是一个简化的时间参数化伪代码,展示了核心逻辑:
# 输入:路径点序列 path_points, 最大速度 v_max, 最大加速度 a_max
# 输出:轨迹 trajectory (包含时间、位置、速度、加速度)

def time_parameterization(path_points, v_max, a_max):
    # 1. 计算路径总长度
    total_length = compute_path_length(path_points)
    
    # 2. 生成S形速度曲线
    # 先计算加速段、匀速段、减速段的长度
    acc_length = v_max**2 / (2 * a_max)
    dec_length = acc_length
    
    if acc_length + dec_length > total_length:
        # 路径太短,无法达到最大速度
        v_actual = sqrt(a_max * total_length)
        # 重新计算三段长度
    else:
        v_actual = v_max
    
    # 3. 生成s(t)映射
    t = 0
    s = 0
    trajectory = []
    while s < total_length:
        # 根据当前s计算速度
        if s < acc_length:
            v = sqrt(2 * a_max * s)
        elif s < total_length - dec_length:
            v = v_actual
        else:
            v = sqrt(2 * a_max * (total_length - s))
        
        # 更新位置
        s += v * dt
        t += dt
        
        # 插值得到实际位置
        pos = interpolate_path(path_points, s)
        trajectory.append((t, pos, v, a))
    
    return trajectory

3.7 常见误区与避坑指南

我曾经踩过的坑:
1. 忽略路径曲率对速度的影响——路径规划时觉得路径很平滑,但实际曲率大的地方机器人速度太快会甩出去。后来我在约束检查里加入了向心加速度约束。

2. 时间参数化时用等时间间隔采样——这会导致路径上点分布不均匀,曲率大的地方点太少。我后来改用等弧长采样,问题解决。

3. 只考虑关节速度不考虑末端速度——对于机械臂,关节速度约束和末端笛卡尔速度约束是两回事。我建议两个都检查。

嗯,这一章的内容就到这里。路径规划和轨迹规划的区别,说白了就是「走哪条路」和「怎么走」的区别。理解了这一点,后面的内容就好办了。