4. 动力学约束
好,咱们接着聊。前面几章我们讲了路径规划和速度轮廓的生成,但说实话,那些都还停留在「理想世界」里。真正把算法往车上放的时候,你会发现——嗯,现实很骨感。
为什么?因为车不是数学点,它有物理极限。你规划得再漂亮,执行器跟不上,那就是纸上谈兵。这一章,我们就来聊聊这些绕不开的动力学约束。
4.1 加速度限制:别让乘客晕车
加速度限制,说白了就是车能「推」多快。我习惯把它分成两类:
- 纵向加速度:油门踩到底能加多快,刹车踩死能减多快。
- 横向加速度:转弯时,车能承受多大的侧向力。
你想想看,如果规划出来的速度曲线要求车辆在0.1秒内从60km/h刹停,那刹车盘都得冒烟。更别提乘客的感受了——我坐过那种急加速急减速的测试车,一趟下来胃里翻江倒海。
核心公式:
a_max = min(a_engine_max, a_brake_max, a_comfort_max)
其中 a_comfort_max 通常取 2~3 m/s²,这是人体比较舒服的区间。
我在项目中遇到过一个问题:某次做泊车路径规划,算法算出来的路径很完美,但一执行就发现车在终点前反复「点头」。查了半天,原来是加速度限制设得太宽松,导致速度曲线在终点附近剧烈震荡。后来我把加速度限制从 5 m/s² 降到 2.5 m/s²,问题立刻解决。
小技巧:做速度规划时,建议把加速度限制作为硬约束写在优化目标里,而不是事后裁剪。否则容易出现「规划一时爽,执行火葬场」的情况。
4.2 Jerk限制:舒适度的隐形杀手
Jerk,就是加速度的变化率。很多人只关注加速度,忽略了jerk。但我告诉你,jerk才是决定乘坐体验的关键。
举个例子:同样是加速到 3 m/s²,一个方案是 0.1 秒内达到,另一个是 0.5 秒内平滑过渡。前者jerk高达 30 m/s³,后者只有 6 m/s³。你坐上去,前者感觉像被人踹了一脚,后者就像被温柔地推了一把。
为什么会这样?因为人体对「力的突变」特别敏感。加速度本身不可怕,可怕的是加速度突然变化。
我曾经踩过的坑:有一次做自动驾驶的换道规划,我用了五阶多项式来生成轨迹,理论上jerk是连续的。但实际测试时,乘客还是抱怨「换道时晃了一下」。后来发现,问题出在轨迹的边界条件上——起点和终点的jerk虽然连续,但中间点的jerk跳变了。所以,光看曲线连续还不够,还得检查各阶导数的连续性。
Jerk限制的典型值:
| 场景 | 最大Jerk (m/s³) | 说明 |
|---|---|---|
| 舒适驾驶 | 2~5 | 日常通勤,乘客感受良好 |
| 运动模式 | 5~10 | 可以接受一些顿挫感 |
| 紧急避障 | 10~20 | 安全优先,舒适度靠后 |
4.3 轮胎摩擦力约束:别让车「滑」出去
这个约束,说白了就是「轮胎能抓住地面多少力」。我见过太多新手工程师,规划出来的路径在干燥路面上跑得挺好,一到雨天就各种打滑。
轮胎摩擦力可以用摩擦圆(Friction Circle)来描述。简单说,轮胎能提供的总摩擦力是有限的,纵向和横向的摩擦力不能同时达到最大。
摩擦圆约束公式:
sqrt( (F_long / F_max)^2 + (F_lat / F_max)^2 ) ≤ 1
其中 F_long 是纵向力,F_lat 是横向力,F_max 是最大摩擦力。
你想想看,如果车在高速过弯时还猛踩刹车,那横向和纵向都在抢摩擦力,很容易突破摩擦圆边界——结果就是甩尾或者推头。
我记得有一次做极限工况测试,车辆在湿滑路面上做紧急变道。算法规划的路径要求同时减速和转向,结果车直接滑出去了。后来我们在规划层加入了摩擦圆约束,确保在任何时刻,纵向和横向的合力都不超过摩擦圆半径。从那以后,再没出现过类似问题。
实际工程中的简化:摩擦圆约束是非线性的,求解起来比较慢。我个人的做法是把它线性化——用多边形近似圆,这样既能保证安全,又能提高计算效率。
4.4 三种约束的融合:一个完整的例子
好,理论讲完了,咱们来点实际的。假设我们要规划一段从静止加速到 10 m/s 然后匀速行驶的轨迹,需要同时考虑加速度、jerk和摩擦力约束。
下面是一个简单的速度规划代码示例:
def plan_velocity_with_constraints(v_target, a_max, jerk_max, mu, g):
"""
带动力学约束的速度规划
v_target: 目标速度 (m/s)
a_max: 最大加速度 (m/s²)
jerk_max: 最大jerk (m/s³)
mu: 路面摩擦系数
g: 重力加速度 (m/s²)
"""
# 1. 计算摩擦圆限制下的最大加速度
a_friction_max = mu * g # 假设只有纵向运动
# 2. 取三者最小值
a_effective_max = min(a_max, a_friction_max)
# 3. 用jerk限制生成平滑的加速度曲线
t_accel = v_target / a_effective_max
t_jerk = a_effective_max / jerk_max
# 4. 生成三段式速度曲线:加jerk、恒加速、减jerk
# 这里省略具体实现,只展示核心逻辑
print(f"有效加速度限制: {a_effective_max:.2f} m/s²")
print(f"加速时间: {t_accel:.2f} s")
print(f"Jerk过渡时间: {t_jerk:.2f} s")
return t_accel, t_jerk
这段代码虽然简单,但体现了融合约束的核心思想:取最严格的约束作为实际限制。
4.5 知识体系总览
为了让你更直观地理解这三种约束的关系,我画了一张图:
这张图把三种约束的关系讲得很清楚。你想想看,实际工程中,这三种约束往往是耦合的——比如急转弯时,摩擦力约束会限制你的加速度,而加速度的变化又受jerk限制。所以,做规划时不能孤立地看某一个约束,得把它们放在一起考虑。
好了,这一章的内容就到这里。动力学约束这块,说白了就是「尊重物理规律」。你尊重它,它就让你的车跑得又稳又安全;你不尊重它,它就让你在测试场上出洋相。我个人建议,在做任何规划算法之前,先把这些约束列清楚,写在需求文档的第一页。
可可精品资料库