3、路径表示方法:参数化曲线(B样条、贝塞尔曲线)、路径离散化表示、路径平滑性度量
好,咱们今天聊聊路径怎么表示。这个问题,说白了就是:你规划出来的那条线,怎么描述给机器人或者车辆去执行?
我刚开始做路径规划那会儿,觉得这事儿特简单——不就是一堆点嘛,连起来就行了。结果第一次实车测试就翻车了。车辆在拐弯处剧烈抖动,方向盘像抽风一样来回打。后来我才明白,路径的表示方式,直接决定了控制器的执行效果。
3.1 参数化曲线:让路径有“灵魂”
先说说参数化曲线。为什么需要它?因为离散点连成的折线,说白了就是“硬拐”。你想想看,一个直角弯,用折线表示就是两条直线硬接在一起。但实际车辆有最小转弯半径,根本拐不过去。
参数化曲线的好处是:它用数学公式来描述路径。每个点都有连续的一阶导、二阶导。这样控制器就能提前知道“前面要拐弯了,该减速了”。
3.1.1 贝塞尔曲线
贝塞尔曲线是最直观的参数化曲线。它的核心思想是:用几个控制点来“拉”出一条平滑曲线。
公式长这样:
B(t) = Σᵢ₌₀ⁿ C(n,i) * (1-t)^(n-i) * tⁱ * Pᵢ
其中 t 在 0 到 1 之间变化,Pᵢ 是控制点。
我个人习惯用三阶贝塞尔曲线(4个控制点)。为什么?因为低阶曲线计算快,而且能保证曲率连续。我在项目中遇到过一个问题:用五阶贝塞尔曲线做路径,结果计算量太大,控制器跟不上实时更新。后来换成三阶,效果反而更好。
3.1.2 B样条曲线
B样条曲线是贝塞尔曲线的“升级版”。它解决了贝塞尔曲线的两个痛点:
- 局部控制:移动一个控制点,只影响附近一小段曲线。贝塞尔曲线是全局的,动一个点整条线都变。
- 连续性可控:你可以指定曲线在连接点处的光滑程度(C0、C1、C2连续)。
B样条的数学形式:
C(t) = Σᵢ₌₀ⁿ Nᵢₚ(t) * Pᵢ
其中 Nᵢₚ(t) 是基函数,p 是阶数。
嗯,这里要注意:B样条的阶数越高,曲线越光滑,但计算也越慢。我一般用三次B样条(p=3),它在光滑度和计算效率之间取得了很好的平衡。
3.2 路径离散化表示:把曲线变成“点阵”
参数化曲线虽然好,但控制器最终要执行的是离散的点。为什么?因为控制器的控制周期是固定的(比如50Hz),它只能在每个周期读取一个目标点。
路径离散化,就是把连续曲线变成一系列等间距或等时间间隔的点。
常用的离散化方法:
- 等参数采样:在 t 上均匀取点。简单,但曲线曲率大的地方点会稀疏。
- 等弧长采样:沿着曲线长度均匀取点。效果好,但计算量大。
- 自适应采样:在曲率大的地方加密,曲率小的地方稀疏。我推荐这个。
举个例子,等弧长采样的伪代码:
function sampleByArcLength(curve, numPoints):
totalLength = computeArcLength(curve)
step = totalLength / (numPoints - 1)
points = []
for i in 0 to numPoints-1:
targetLength = i * step
t = findParameterByLength(curve, targetLength)
points.append(curve.eval(t))
return points
我在项目中遇到过一个问题:用等参数采样,结果在急弯处路径点间距太大,车辆直接冲出了路径。后来改成自适应采样,问题就解决了。
3.3 路径平滑性度量:怎么才算“平滑”?
这个问题很有意思。你说一条路径平滑,凭什么?总得有个量化指标吧。
常用的平滑性度量有三个:
| 度量指标 | 含义 | 计算公式 | 我的建议 |
|---|---|---|---|
| 曲率 | 路径弯曲程度 | κ = |x'y'' - x''y'| / (x'² + y'²)^(3/2) | 必须小于车辆最小转弯半径的倒数 |
| 曲率变化率 | 曲率的变化速度 | dκ/ds | 越小越好,避免方向盘急打 |
| 加加速度 | 加速度的变化率 | jerk = da/dt | 影响乘坐舒适性 |
说白了,平滑性就是看路径的“脾气”好不好。曲率突变,就像一个人突然急转弯;曲率变化率大,就像方向盘在抖;加加速度大,就像急刹车急加速。
3.4 知识体系总览
下面这张图,是我自己总结的路径表示方法知识体系。你可以把它当作一个“地图”,随时回来看看。
这张图把三个核心内容串起来了。你从参数化曲线出发,经过离散化得到可执行的点,再用平滑性度量来评价效果。这三者缺一不可。
好了,路径表示方法就聊到这儿。记住一句话:路径是给控制器看的,不是给你看的。它好不好,让控制器说了算。
可可精品资料库