3、轨迹表示方法:路径与轨迹的区别、多项式轨迹、样条曲线(B样条、贝塞尔曲线)、时间参数化

做机器人控制这些年,我见过不少新手一上来就急着调PID参数,结果机器人跑得歪歪扭扭。其实啊,问题往往出在轨迹表示上——你连“路”都没定义清楚,怎么指望机器人走得好?

这一节,我们来聊聊轨迹表示的核心问题。说白了,就是回答两个问题:机器人要去哪?什么时候到?

3.1 路径 vs 轨迹:一字之差,天壤之别

先讲个我踩过的坑。几年前做焊接机器人项目,我直接把路径当轨迹用,结果机器人末端在拐角处猛地一抖,焊点全偏了。后来才明白——路径和轨迹,根本是两码事。

概念 定义 包含信息 举例
路径 空间中的几何曲线 位置 (x, y, z) 或关节角度 (q1, q2, ...) 从A点到B点的一条直线
轨迹 路径 + 时间信息 位置、速度、加速度随时间的变化 从A到B,5秒内完成,初末速度为零

你想想看,路径只告诉机器人“走哪条路”,而轨迹还告诉它“什么时候走到哪里、速度多快”。控制机器人,最终要的是轨迹,不是路径。

核心要点:路径是几何的,轨迹是时间的。没有时间参数化的路径,机器人没法执行。

3.2 多项式轨迹:最简单也最常用

多项式轨迹是我个人最常用的起点。为什么?因为它数学简单、物理意义明确。

3.2.1 三次多项式轨迹

假设我们要让机器人关节从角度 q0 运动到 qf,用时 T 秒,且起止速度都为零。一个三次多项式就能搞定:

q(t) = a0 + a1*t + a2*t² + a3*t³

四个未知系数,对应四个边界条件:

  • q(0) = q0
  • q(T) = qf
  • q'(0) = 0
  • q'(T) = 0

解这个方程组,代码实现其实就几行:

import numpy as np

def cubic_trajectory(q0, qf, T, t):
    """三次多项式轨迹计算"""
    a0 = q0
    a1 = 0
    a2 = 3*(qf - q0) / T**2
    a3 = -2*(qf - q0) / T**3
    
    q = a0 + a1*t + a2*t**2 + a3*t**3
    qd = a1 + 2*a2*t + 3*a3*t**2  # 速度
    qdd = 2*a2 + 6*a3*t           # 加速度
    
    return q, qd, qdd
我的经验:三次多项式适合点到点的简单运动。但如果你要求起止加速度也为零,就得用五次多项式了。

3.2.2 五次多项式轨迹

当运动需要更平滑的起止时,五次多项式是更好的选择。它多了两个自由度,可以约束加速度:

q(t) = a0 + a1*t + a2*t² + a3*t³ + a4*t⁴ + a5*t⁵

六个边界条件:位置、速度、加速度在起止时刻都指定。我在做精密装配时,就靠五次多项式避免了末端冲击。

3.3 样条曲线:让轨迹更灵活

多项式轨迹有个局限——它只能描述单段运动。如果机器人要走一条复杂的曲线,比如画个S形,就需要样条曲线了。

3.3.1 贝塞尔曲线

贝塞尔曲线的核心思想是“控制点”。你放几个控制点,曲线就被“拉”过去了。我常用的是三次贝塞尔曲线:

B(t) = (1-t)³P0 + 3(1-t)²t P1 + 3(1-t)t² P2 + t³P3

其中 P0 到 P3 是四个控制点,t 从 0 到 1。

注意:贝塞尔曲线是全局的——移动一个控制点,整条曲线都会变。这在某些场景下不太方便。

3.3.2 B样条曲线

B样条曲线解决了贝塞尔的全局性问题。它的控制点只影响局部区域。我在项目中遇到过需要微调轨迹某一段的情况,B样条就特别顺手——改一个点,只影响附近几段。

B样条的数学稍微复杂些,但核心思想是:用分段多项式拼接成一条光滑曲线。每个分段都是低次多项式,整体却能达到高阶连续性。

特性 贝塞尔曲线 B样条曲线
控制点影响范围 全局 局部
多项式次数 固定(控制点数-1) 可调(阶次决定)
连续性 C∞(内部) C^(k-1)(k为阶次)
适用场景 简单曲线设计 复杂路径、局部调整

3.4 时间参数化:给路径加上“心跳”

有了漂亮的几何路径,怎么让机器人按我们想要的速度跑起来?这就是时间参数化的活。

我曾经犯过一个错误:直接用等时间间隔采样路径点,结果机器人速度忽快忽慢。后来才意识到,时间参数化决定了轨迹的动力学特性

3.4.1 梯形速度规划

最经典的时间参数化方式。加速段、匀速段、减速段三段式:

def trapezoidal_profile(s_total, v_max, a_max, t):
    """梯形速度规划,s_total为总路径长度"""
    # 计算加速段距离
    s_acc = v_max**2 / (2 * a_max)
    
    if s_acc * 2 >= s_total:
        # 三角形速度曲线(达不到最大速度)
        # ... 处理代码
        pass
    else:
        # 标准梯形曲线
        # ... 处理代码
        pass
    
    return s, s_dot, s_ddot  # 位置、速度、加速度
关键点:时间参数化把路径参数 s(t) 映射到时间 t 上。s 从 0 到 1,代表路径的进度。最终轨迹是:q(t) = path(s(t))。

3.4.2 S形速度规划

梯形规划的加速度有突变,会导致机器人抖动。S形规划加了加加速度(jerk)约束,运动更平滑。我做过一个码垛机器人项目,换成S形规划后,末端抖动直接降了60%。

3.5 知识体系总览

下面这张图,是我梳理的本章知识结构。你可以把它当个地图,随时回来对照:

轨迹表示方法知识体系 轨迹表示方法 路径 vs 轨迹 多项式轨迹 样条曲线 时间参数化 三次多项式 五次多项式 贝塞尔曲线 B样条曲线 梯形/S形规划 关键属性对比 连续性 | 局部性 | 计算复杂度 | 物理约束满足能力 选择依据:任务精度要求 × 实时性约束 × 硬件能力 核心原则:路径定几何,轨迹定时间,样条做拼接,参数化给速度

3.6 避坑指南

最后,分享几个我这些年踩过的坑:

  • 我曾经直接用高次多项式拟合复杂路径,结果曲线出现剧烈振荡。后来改用分段低次样条,问题迎刃而解。
  • 我曾经在时间参数化时忽略了加速度约束,导致电机过载烧了驱动器。嗯,那次教训挺深刻的。
  • 我建议新手先从三次多项式+梯形规划开始,跑通了再上样条和S形。别一上来就搞复杂的。
实用技巧:调试时,先把轨迹画出来看看。我习惯用matplotlib可视化位置、速度、加速度曲线,一眼就能看出问题。

轨迹表示是机器人控制的基石。把这块搞扎实了,后面的控制算法才能发挥真正的作用。记住:好的轨迹,是控制成功的一半。


公众号:蓝海资料掘金营,微信deep3321