2. 曲率约束基础:曲率的几何定义、物理意义及其在路径规划中的角色
各位同学,咱们今天聊聊曲率约束。说实话,这玩意儿在路径规划里是个绕不开的坎儿。我刚开始做自动驾驶那会儿,总觉得路径规划就是找条路走,后来发现——嗯,没那么简单。
你想想看,一辆车在高速上跑,突然来个急转弯,乘客会怎么想?肯定骂娘。更别提如果曲率太大,车可能直接侧翻。所以,曲率约束不是锦上添花,而是安全底线。
2.1 曲率的几何定义:从圆说起
曲率这个概念,说白了就是描述曲线弯曲程度的量。怎么定义呢?
想象一条曲线上的某一点。过这一点,我们可以画一个最贴近曲线的圆——这个圆叫密切圆。密切圆的半径越小,说明曲线在这个点弯得越厉害;半径越大,说明越平缓。
曲率 κ 的数学定义就是密切圆半径 R 的倒数:
κ = 1 / R
单位是 1/m。举个例子,半径 10 米的圆,曲率就是 0.1。直线呢?直线可以看作半径无穷大的圆,曲率就是 0。
我个人习惯用这个公式来理解:曲率越大,转弯越急。就这么简单。
核心要点:
- 曲率 κ = 1 / R,R 是密切圆半径
- 直线曲率为 0
- 曲率越大,弯曲越剧烈
2.2 物理意义:车为什么不能无限转弯?
好,几何定义搞清楚了。那物理上呢?
我遇到过不少刚入行的朋友,他们觉得路径规划就是数学游戏。其实不是。车辆有物理极限。
一辆车转弯时,靠的是轮胎与地面的摩擦力。曲率越大,需要的向心力越大。向心力公式还记得吧?
F = m * v² / R = m * v² * κ
其中 m 是质量,v 是速度。你看,曲率 κ 和速度 v 的平方是乘在一起的。这意味着:
- 速度越快,能承受的曲率越小
- 曲率越大,必须降速
我曾经在一个项目中,路径规划器生成了一个曲率 0.2 的弯道,车速 60 km/h。结果仿真一跑,侧向加速度直接超了 0.5g。乘客肯定受不了。后来我加了个曲率-速度耦合约束,才把问题解决。
实战技巧: 在实际系统中,我通常把最大曲率与最大速度绑定。比如:
κ_max(v) = a_lat_max / v²
其中 a_lat_max 是最大允许侧向加速度,一般取 0.3g ~ 0.5g。
2.3 路径规划中的角色:曲率约束到底管什么?
曲率约束在路径规划里,主要干三件事:
- 保证可执行性——规划出的路径,车辆必须能实际开出来
- 保证舒适性——乘客不晕车、不难受
- 保证安全性——不侧翻、不失控
说白了,没有曲率约束的路径,就是一张废纸。
我记得有一次做园区物流小车,规划器输出了一条路径,曲率在某个点突然从 0.05 跳变到 0.15。小车一执行,方向盘猛地一打,差点把货甩出去。这就是曲率不连续的问题。
注意: 曲率不仅要限制大小,还要限制变化率。曲率突变会导致方向盘急转,这在高速场景下极其危险。我一般会加一个曲率变化率约束:
|dκ/ds| ≤ κ_dot_max
其中 s 是路径弧长。
2.4 曲率约束的数学表达
在路径规划中,我们通常把路径参数化为 x(s) 和 y(s),其中 s 是弧长。曲率的计算公式是:
κ(s) = |x'(s) y''(s) - y'(s) x''(s)| / (x'(s)² + y'(s)²)^(3/2)
看着复杂?其实不用怕。实际工程中,我们很少直接算这个。更常用的方法是:
- 用离散点近似曲率
- 或者用参数化曲线(如B样条、贝塞尔曲线)直接控制曲率
我个人偏好用B样条。为什么呢?因为B样条的曲率可以通过控制点来调节,而且天然具有连续性。我在做高速路径规划时,B样条帮了大忙。
2.5 知识体系总览
下面这张图,是我自己总结的曲率约束知识框架。你看一眼,心里就有数了。
2.6 一个简单的曲率计算示例
光说不练假把式。咱们写个简单的 Python 代码,算算离散路径点的曲率。
import numpy as np
def compute_curvature(x, y):
"""
计算离散路径点的曲率
x, y: 路径点坐标数组
返回: 每个点的曲率值
"""
dx = np.gradient(x)
dy = np.gradient(y)
ddx = np.gradient(dx)
ddy = np.gradient(dy)
# 曲率公式
numerator = np.abs(dx * ddy - dy * ddx)
denominator = (dx**2 + dy**2)**1.5
# 避免除零
curvature = np.divide(numerator, denominator,
out=np.zeros_like(numerator),
where=denominator > 1e-6)
return curvature
# 示例:一个半圆路径
theta = np.linspace(0, np.pi, 50)
x = 10 * np.cos(theta)
y = 10 * np.sin(theta)
kappa = compute_curvature(x, y)
print(f"平均曲率: {np.mean(kappa):.4f}") # 应该接近 0.1
这段代码我用了很多年。注意 np.gradient 用的是中心差分,精度还行。如果你需要更高精度,可以用样条插值后再求导。
小提示: 实际工程中,路径点往往有噪声。直接求导会放大噪声,曲率值会剧烈跳动。我一般先做平滑滤波,再算曲率。常用的方法有 Savitzky-Golay 滤波或移动最小二乘法。
2.7 避坑指南
最后,分享几个我踩过的坑:
- 曲率不连续——路径规划器输出了一段直线接圆弧,曲率从 0 跳到 0.1。车辆执行时方向盘猛打,乘客直接晕车。解决办法:用回旋曲线(Clothoid)过渡。
- 忽略曲率变化率——只限制曲率大小,没限制变化率。结果路径曲率变化太快,转向系统跟不上。后来我加了
|dκ/ds|约束,问题解决。 - 曲率与速度解耦——单独规划路径,再单独规划速度。结果路径曲率大的地方速度没降下来,侧向加速度超标。现在我做联合优化,路径和速度一起考虑。
嗯,曲率约束的基础就这些。说白了,它就是连接几何、物理和工程的一座桥。理解了它,后面的轨迹平滑就好办了。
可可精品资料库