4. 最小化 jerk 轨迹:jerk(加加速度)的定义,最小化 jerk 的优化模型

好,咱们今天聊聊轨迹平滑里的一个核心概念——jerk。你可能会问,加速度还不够吗?为什么还要折腾一个加加速度?

嗯,我刚开始做机器人路径规划时,也这么想。直到有一次,我调试一台AGV小车,明明加速度限制都设好了,车子跑起来却像在跳机械舞——一顿一顿的。后来才发现,问题就出在jerk上。说白了,加速度的变化率没控制好,车体就会产生冲击感。

4.1 什么是jerk?

jerk,中文叫加加速度,是加速度对时间的导数。数学上很简单:

j(t) = da(t)/dt = d³p(t)/dt³

其中 p(t) 是位置,a(t) 是加速度。jerk 描述的是加速度变化的快慢。

举个例子:你开车时,从静止到匀速,如果一脚油门踩到底,加速度瞬间从0跳到某个值,这个瞬间的jerk就非常大。你会感觉被人从背后推了一把。如果慢慢踩油门,加速度平缓上升,jerk就小,体感就舒服。

核心理解:jerk 衡量的是「加速度的平滑程度」。jerk 越小,运动越柔和。

在自动驾驶里,jerk 直接影响乘客的舒适度。我见过一些早期的规划算法,只约束速度和加速度,结果乘客投诉说「像新手司机在开车」。后来加了 jerk 约束,体验立马不一样了。

4.2 为什么要最小化jerk?

你可能会问:我们不是已经有加速度约束了吗?为什么还要单独搞一个jerk?

我举个例子你就明白了。假设两个轨迹:

  • 轨迹A:加速度从0瞬间跳到2 m/s²,保持2秒,再瞬间跳回0。
  • 轨迹B:加速度从0平滑上升到2 m/s²,保持2秒,再平滑下降到0。

两个轨迹的最大加速度都是2 m/s²,但轨迹A的jerk是无穷大(瞬间变化),轨迹B的jerk是有限值。实际执行时,轨迹A会让电机产生冲击,机械结构容易疲劳,乘客也会感到不适。

所以,最小化jerk的好处有三点:

  1. 提升舒适性——乘客不会感到突兀的推背或点头
  2. 保护机械结构——减少冲击载荷,延长寿命
  3. 便于跟踪控制——平滑的轨迹更容易被底层控制器精确跟踪

我的经验:在AGV项目中,我们曾经对比过「仅约束加速度」和「同时约束jerk」的两套轨迹。结果发现,加了jerk约束后,电机电流的波动幅度降低了约40%,定位精度也提升了。所以,别小看这个三阶导数。

4.3 最小化jerk的优化模型

好了,理论说完了,咱们来点实际的。怎么用数学方法找到一条jerk最小的轨迹?

最经典的方法就是构建一个最小化jerk的优化问题。目标函数通常写成:

minimize  ∫ (j(t))² dt

也就是让整个轨迹上的jerk平方和最小。为什么用平方?因为平方可以惩罚大的jerk值,同时让优化问题有良好的数学性质(凸性)。

在实际应用中,我们通常用多项式参数化来表示轨迹。比如,用5次多项式来表示位置:

p(t) = c₀ + c₁t + c₂t² + c₃t³ + c₄t⁴ + c₅t⁵

为什么是5次?因为jerk是位置的三阶导数,5次多项式求三阶导后还剩二次项,这样我们就有足够的自由度来满足边界条件(位置、速度、加速度)并最小化jerk。

优化模型可以写成:

minimize  ∫ (d³p/dt³)² dt
subject to:
  p(0) = p_start,  p(T) = p_end
  v(0) = v_start,  v(T) = v_end
  a(0) = a_start,  a(T) = a_end

其中 T 是轨迹的总时间。这个问题的解其实有闭式表达式,就是所谓的最小jerk轨迹,它是一条5次多项式曲线。

关键结论:在给定起点和终点的位置、速度、加速度条件下,最小化jerk的轨迹是一条5次多项式。这是轨迹规划里的一个经典结果。

4.4 代码实现示例

光说不练假把式。我写一段Python代码,演示怎么计算最小jerk轨迹的系数:

import numpy as np

def minimum_jerk_trajectory(p0, pf, v0, vf, a0, af, T):
    """
    计算最小jerk轨迹的多项式系数
    参数:
        p0, pf: 起始和终止位置
        v0, vf: 起始和终止速度
        a0, af: 起始和终止加速度
        T: 总时间
    返回:
        系数向量 [c0, c1, c2, c3, c4, c5]
    """
    # 构建系数矩阵
    A = np.array([
        [1, 0, 0, 0, 0, 0],
        [0, 1, 0, 0, 0, 0],
        [0, 0, 2, 0, 0, 0],
        [1, T, T**2, T**3, T**4, T**5],
        [0, 1, 2*T, 3*T**2, 4*T**3, 5*T**4],
        [0, 0, 2, 6*T, 12*T**2, 20*T**3]
    ])
    
    # 边界条件向量
    b = np.array([p0, v0, a0, pf, vf, af])
    
    # 求解线性方程组
    coeffs = np.linalg.solve(A, b)
    return coeffs

# 示例:从静止到静止,移动10米,用时5秒
coeffs = minimum_jerk_trajectory(0, 10, 0, 0, 0, 0, 5)
print("多项式系数:", coeffs)

避坑指南:我曾经在项目中直接用这个公式,结果发现轨迹在中间段超调了。后来检查才发现,是因为没有考虑路径上的障碍物。最小jerk轨迹只保证平滑,不保证避障。所以实际使用时,通常要把它作为优化问题的一个项,而不是唯一目标。

4.5 知识体系总览

为了让你更直观地理解本章的知识结构,我画了一张图:

最小化Jerk轨迹知识体系 Jerk定义 j = da/dt = d³p/dt³ 为什么要最小化? 舒适性 · 机械保护 · 跟踪性 优化模型 min ∫ j² dt 多项式参数化 5次多项式:p(t)=Σcᵢtⁱ 边界条件 位置·速度·加速度 求解方法 线性方程组求解 → 闭式解

这张图把本章的知识点串起来了。从左到右是逻辑递进:先理解jerk是什么,再明白为什么要最小化它,最后落到优化模型和求解方法上。

4.6 实际应用中的注意事项

最后,我分享几个实际项目中的经验:

场景 jerk约束建议 说明
乘客运输(自动驾驶汽车) jerk < 2 m/s³ 人体舒适度阈值,超过会有明显不适
工业机器人 jerk < 10 m/s³ 机械臂刚性大,可承受更高jerk
AGV/AMR jerk < 5 m/s³ 兼顾效率和稳定性,我常用的经验值
高精度定位平台 jerk < 1 m/s³ 避免振动影响定位精度

注意:上面的数值只是参考。实际项目中,一定要结合你的硬件特性来调整。我记得有一次在AGV上直接套用汽车行业的jerk限制,结果发现AGV的电机响应太慢,轨迹跟踪误差很大。后来放宽了jerk约束,反而效果更好。

好了,关于最小化jerk轨迹的核心内容就这些。记住一句话:jerk是加速度的加速度,控制好它,你的轨迹才能真正平滑。

可可精品资料库