路径平滑优化算法–Clothoid 路径平滑
文章目录
- 路径平滑优化算法--Clothoid 路径平滑
- 0 为什么选 Clothoid?
- 1 数学基础:严谨推导(Mathematical Foundation)
- 可视化解释
- 1.1 曲率线性假设
- 1.2 切向角(Heading Angle)
- 1.3 平面位置表达(Fresnel 积分形式)
- 1.4 连续性分析
- 2 单段拼接:Clothoid Pair(Meek & Walton, 1999)
- 2.1 问题定义
- 2.2 归一化
- 2.3 未知量与曲率增长率
- 2.4 三条约束方程
- 2.5 数值求解策略
- 2.6 采样输出与轨迹生成(Trajectory Sampling)
- ✅ 步骤 1:前段 Clothoid 曲线生成(起点 → 拼接点)
- ✅ 步骤 2:后段 Clothoid 曲线生成(拼接点 → 终点)
- ✅ 步骤 3:全局拼接与坐标还原
- 3 多段 Clothoid 全局 G² 拼接(Global G² Clothoid Spline)
- 3.1 步骤总览与解释
- 💡 解耦 vs 联合求解
- 🚘 应用场景
- 4 动态约束嵌入(速度规划)
- 4.1 侧向加速度约束(Lateral Acceleration)
- 4.2 方向盘角速度约束(Steering Rate Limit)
- 4.3 最终速度剖面合成
- 4.4 几何反馈调整(如仍超限)
- 5. Clothoid Pair 手动求解算例(全过程 LaTeX 精编)
- 5.1 题目描述
- 5.2 未知量(目标求解)
- 5.3 方程组(构建约束)
- (1) 方向角差约束
- (2)(3) 位置约束 (采用 1 阶 Fresnel 积分近似)
- 5.4 动态约束嵌入
- 5.5 动态约束嵌入检验
- 6 python实现代码
从数学推导 → 单段拼接 → 多段全局 G² 连贯 → 动态约束与速度规划
0 为什么选 Clothoid?
需求 | Clothoid 值点 |
---|---|
G² 连续(位置 + 切向 + 曲率连续) | 曲率κ(s)=κ0+as\kappa(s)=\kappa_0+asκ(s)=κ0+as天然线性 ⇒ 无突变 |
符合车辆物理 | 方向盘角速度δ˙∝κ˙\dot\delta\propto\dot\kappaδ˙∝κ˙可控,不会突然甩尾 |
解析/数值友好 | Fresnel 积分闭式可算;解方程只需牛顿/LM |
易拼接 | “Clothoid↔圆弧↔Clothoid”或“Clothoid Pair”即可连接任意两态 |
1 数学基础:严谨推导(Mathematical Foundation)
Clothoid(又称 Euler 螺线)是满足曲率随弧长线性变化的平面曲线,是实现路径平滑(尤其是满足 G2G^2G2 连续性)最常用的一类几何曲线。该小节给出 Clothoid 的标准数学定义与推导过程。
可视化解释
- 紫色主曲线 是一条随弧长线性增长曲率的轨迹:从直线开始逐渐变弯。
- 灰色箭头 表示不同位置处的切线方向(即当前的朝向角),可以看到方向角逐渐旋转,体现出“曲率线性增长”的特性。
- 弧长从 s=0s=0s=0 到 s=10s=10s=10,表示“路径前进距离”。
1.1 曲率线性假设
Clothoid 的关键定义是:曲率 κ\kappaκ 是弧长 sss 的线性函数,即:
κ(s)=κ0+as\kappa(s) = \kappa_0 + a\,sκ(s)=κ0+as
其中:
- κ0\kappa_0κ0:起点处的曲率(通常为 0);
- aaa:曲率变化率(curvature derivative),控制曲线弯曲速度。
这个定义表示:物体从起始点开始,以恒定的角加速度逐渐弯曲,符合汽车、轨道车等动力系统的转向特性。
1.2 切向角(Heading Angle)
根据曲率的定义:κ=dθds\kappa = \frac{d\theta}{ds}κ=dsdθ,即曲率是朝向角随弧长的导数。
因此,朝向角 θ(s)\theta(s)θ(s) 可通过积分获得:
θ(s)=θ0+∫0sκ(t)dt=θ0+κ0s+12as2\theta(s) = \theta_0 + \int_0^s \kappa(t)\,dt = \theta_0 + \kappa_0 s + \tfrac12 a s^2θ(s)=θ0+∫0sκ(t)dt=θ0+κ0s+21as2
这个表达式说明,在曲率线性变化的情况下,朝向角是一个关于弧长的二次函数,其一阶导数是曲率,二阶导数是曲率增长率 aaa。
1.3 平面位置表达(Fresnel 积分形式)
有了朝向角 θ(s)\theta(s)θ(s),我们可以进一步求出在路径上任意位置处的平面坐标 (x(s),y(s))(x(s), y(s))(x(s),y(s))。由于:
dxds=cosθ(s),dyds=sinθ(s)\frac{dx}{ds} = \cos\theta(s),\quad \frac{dy}{ds} = \sin\theta(s)dsdx=cosθ(s),dsdy=sinθ(s)
我们将其表示为复数形式:
Δx+iΔy=∫0seiθ(t)dt\Delta x + i \Delta y = \int_0^s e^{i \theta(t)} dtΔx+iΔy=∫0seiθ(t)dt
代入 θ(t)=θ0+κ0t+12at2\theta(t) = \theta_0 + \kappa_0 t + \tfrac12 a t^2θ(t)=θ0+κ0t+21at2,积分结果为复数形式的 Fresnel 积分表达:
Δx+iΔy=πa⋅eiθ0[C(u)+iS(u)]0aπs\Delta x + i \Delta y = \sqrt{\frac{\pi}{a}} \cdot e^{i\theta_0} \left[ C(u) + i S(u) \right]_0^{\sqrt{\frac{a}{\pi}}s}Δx+iΔy=aπ⋅eiθ0[C(u)+iS(u)]0πas
其中:
- C(u)=∫0ucos(π2t2)dtC(u) = \int_0^u \cos\left(\frac{\pi}{2} t^2\right) dtC(u)=∫0ucos(2πt2)dt:Fresnel cosine 积分;
- S(u)=∫0usin(π2t2)dtS(u) = \int_0^u \sin\left(\frac{\pi}{2} t^2\right) dtS(u)=∫0usin(2πt2)dtt:Fresnel sine 积分;
- 变量 u=aπsu = \sqrt{\frac{a}{\pi}} su=πas 是归一化后的弧长。
这一定义说明:Clothoid 曲线的空间位置无法解析表达,只能通过数值积分近似或表格查表。但其结构非常优雅,适用于连续曲率要求的规划与建模任务。
1.4 连续性分析
由上述公式可知,Clothoid 曲线的四个几何量:
- 空间位置:x(s),y(s)x(s), y(s)x(s),y(s)
- 切向角:θ(s)\theta(s)θ(s)
- 曲率:κ(s)\kappa(s)κ(s)
均为弧长 sss 的连续函数,且在拼接点处可通过曲率线性规划确保一阶导数(切向)与二阶导数(曲率)均连续。
因此,Clothoid 曲线天然满足:
G2连续性⇔位置、切向、曲率全部连续G^2\text{ 连续性} \quad \Leftrightarrow \quad \text{位置、切向、曲率全部连续}G2 连续性⇔位置、切向、曲率全部连续
这是其在轨道设计、高速路径生成中的广泛应用基础。
✅ 左图:Clothoid Pair: Path in XY Plane
- 表示路径在平面 xyxyxy 中的几何形状;
- 起点 P0P_0P0:红点标注,具有初始朝向 θ0\theta_0θ0;
- 终点 P1P_1P1:终止姿态,朝向为 θ1\theta_1θ1;
- 中间路径由两段曲率线性变化的 Clothoid 拼接组成:
- 第一段(Clothoid-in):曲率从 k0k_0k0 增加;
- 第二段(Clothoid-out):从峰值 κm\kappa_mκm 降回终点曲率;
- 整条路径在视觉上光滑,没有拐角,体现 G² 连续性。
✅ 右图:Clothoid Pair: Linear Ramp Up & Down
上图:
- 横轴:弧长 sss,表示沿路径前进的距离;
- 纵轴:曲率 κ\kappaκ;
- 曲率从 k0k_0k0 线性增加至峰值 κpm\kappa_{pm}κpm,再线性减少至终点曲率;
- 总弧长为 L=L1+L2L = L_1 + L_2L=L1+L2,其中 L1L_1L1、L2L_2L2 为两段长度;
- 虚线处为拼接点,满足曲率连续(G2G^2G2 连续)。
下图(辅助对比):
- 展示若采用普通直线 + 圆弧拼接,曲率出现“突变”;
- 从而说明 Clothoid 的优势在于避免这种“跳跃”。
上图展示了单段 Clothoid 曲线的几何结构图,用于形象说明本文中提到的数学推导结果:
- 蓝色曲线:由曲率线性增长 κ(s)=as\kappa(s) = a sκ(s)=as 产生的 Clothoid 路径;
- 黑色箭头:切向角 θ(s)\theta(s)θ(s),显示路径的朝向随弧长连续变化;
- 红点:起点与终点位置,展示 Clothoid 曲线从直线逐渐变弯的特性;
- 曲线从直线缓慢弯曲,体现其“转向渐进”的优势。
2 单段拼接:Clothoid Pair(Meek & Walton, 1999)
2.1 问题定义
在路径规划中,连接任意两个状态点 P0=(x0,y0,θ0,κ0)P_0 = (x_0, y_0, \theta_0, \kappa_0)P0=(x0,y0,θ0,κ0)、P1=(x1,y1,θ1,κ1)P_1 = (x_1, y_1, \theta_1, \kappa_1)P1=(x1,y1,θ1,κ1),不仅要求连接后的路径 位置闭合,而且希望保证 朝向角一致(G1G^1G1 连续),更进一步还需 曲率连续(G2G^2G2 连续)。
Meek & Walton (1999) 提出使用两段 Clothoid 曲线(即曲率线性变化曲线)以“背靠背”的方式拼接,前段从 κ0\kappa_0κ0 增加到中间曲率κm\kappa_mκm,后段从 κm\kappa_mκm 减少到 κ1\kappa_1κ1,实现完整的高阶连续路径。
这种结构被称为 Clothoid Pair,是现代工业界与自动驾驶中常用的路径平滑结构之一。
2.2 归一化
为简化推导,通常先将路径转换到局部坐标系:
- 以 P0P_0P0 为原点;
- 将路径旋转使得起始朝向 θ0=0\theta_0 = 0θ0=0;
- 因此,变换后的目标点为 P^1=(x^,y^,θ^,κ1)\hat{P}_1 = (\hat{x}, \hat{y}, \hat{\theta}, \kappa_1)P^1=(x^,y^,θ^,κ1),起点为 (0,0,0,κ0)(0, 0, 0, \kappa_0)(0,0,0,κ0)。
这个归一化操作可以显著简化约束方程和数值求解过程。
2.3 未知量与曲率增长率
设 Clothoid Pair 中的拼接变量为:
x=(L1,L2,κm)\mathbf{x} = (L_1, L_2, \kappa_m)x=(L1,L2,κm)
其中:
- L1L_1L1:第一段 Clothoid 的弧长,从起点增长至中间点;
- L2L_2L2:第二段 Clothoid 的弧长,从中间点下降至终点;
- κm\kappa_mκm:拼接点的中间曲率。
每段 Clothoid 的曲率按弧长线性变化,对应曲率增长率为:
a1=κm−κ0L1,a2=κm−κ1L2a_1 = \frac{\kappa_m - \kappa_0}{L_1},\quad a_2 = \frac{\kappa_m - \kappa_1}{L_2}a1=L1κm−κ0,a2=L2κm−κ1
2.4 三条约束方程
为了确保整条路径从 P0P_0P0 精确到达 P1P_1P1,需要满足以下三条几何约束:
F(x)=[Δx1+ℜ[eiΔθ1(Δx2+iΔy2)]−x^Δy1+ℑ[eiΔθ1(Δx2+iΔy2)]−y^Δθ1+Δθ2−θ^]=0\mathbf{F}(\mathbf{x}) = \begin{bmatrix} \Delta x_1 + \Re\left[ e^{i\Delta\theta_1}(\Delta x_2 + i\Delta y_2) \right] - \hat{x} \\\\ \Delta y_1 + \Im\left[ e^{i\Delta\theta_1}(\Delta x_2 + i\Delta y_2) \right] - \hat{y} \\\\ \Delta\theta_1 + \Delta\theta_2 - \hat{\theta} \end{bmatrix} = \mathbf{0}F(x)=Δx1+ℜ[eiΔθ1(Δx2+iΔy2)]−x^Δy1+ℑ[eiΔθ1(Δx2+iΔy2)]−y^Δθ1+Δθ2−θ^=0
说明:
- (Δx1,Δy1)(\Delta x_1, \Delta y_1)(Δx1,Δy1):第一段 Clothoid 的终点相对位移;
- 第二段的位移(Δx2,Δy2)(\Delta x_2, \Delta y_2)(Δx2,Δy2) 要先旋转 Δθ1\Delta\theta_1Δθ1 后拼接;
- Δθ1,Δθ2\Delta\theta_1, \Delta\theta_2Δθ1,Δθ2:各段的旋转角,曲率积分而得;
- 整体路径的终点坐标、朝向必须与 P^1\hat{P}_1P^1 一致。
2.5 数值求解策略
由于 F(x)=0\mathbf{F}(\mathbf{x}) = \mathbf{0}F(x)=0 是非线性方程组,采用迭代数值解法:
-
初始猜值:
L1=L2=12x^2+y^2L_1 = L_2 = \frac{1}{2} \sqrt{\hat{x}^2 + \hat{y}^2}L1=L2=21x^2+y^2
κm=线性外推值(根据 θ1)\kappa_m = \text{线性外推值} \quad (\text{根据 } \theta_1)κm=线性外推值(根据 θ1)
-
优化算法:
-
牛顿法(Newton)或 Levenberg–Marquardt 阻尼算法;
-
迭代公式:
xk+1=xk−J−1F(xk)\mathbf{x}_{k+1} = \mathbf{x}_k - \mathbf{J}^{-1} \mathbf{F}(\mathbf{x}_k)xk+1=xk−J−1F(xk)其中 J\mathbf{J}J 是雅可比矩阵;
-
迭代终止条件:
F(x)∥<10−10\mathbf{F}(\mathbf{x})\| < 10^{-10}F(x)∥<10−10
-
这些算法能高效地求得可拼接曲率,从而构建 Clothoid Pair 路径。
2.6 采样输出与轨迹生成(Trajectory Sampling)
在数值求解出参数向量 x=(L1,L2,κm)\mathbf{x} = (L_1, L_2, \kappa_m)x=(L1,L2,κm) 后,我们就得到了完整定义这条 Clothoid Pair 曲线所需的全部信息。接下来,需要将这条理论路径“展开”成连续轨迹点,以用于实际导航、控制或绘图。
✅ 步骤 1:前段 Clothoid 曲线生成(起点 → 拼接点)
前段曲线的曲率从起始值 κ0\kappa_0κ0(通常为 0)线性上升至 κm\kappa_mκm。其表达式为:
-
曲率变化:
κ1(s)=κ0+a1s=κ0+κm−κ0L1s,s∈[0,L1]\kappa_1(s) = \kappa_0 + a_1 s = \kappa_0 + \frac{\kappa_m - \kappa_0}{L_1} s,\quad s \in [0, L_1]κ1(s)=κ0+a1s=κ0+L1κm−κ0s,s∈[0,L1]朝向角由曲率积分而得:
θ1(s)=θ0+∫0sκ1(t)dt=θ0+κm−κ02L1s2\theta_1(s) = \theta_0 + \int_0^s \kappa_1(t)\,dt = \theta_0 + \frac{\kappa_m - \kappa_0}{2L_1}s^2θ1(s)=θ0+∫0sκ1(t)dt=θ0+2L1κm−κ0s2
-
平面坐标轨迹:
x1(s)=∫0scos(θ1(t))dt,y1(s)=∫0ssin(θ1(t))dtx_1(s) = \int_0^s \cos(\theta_1(t))\,dt,\quad y_1(s) = \int_0^s \sin(\theta_1(t))\,dtx1(s)=∫0scos(θ1(t))dt,y1(s)=∫0ssin(θ1(t))dt
这些积分表达式可以通过数值方法(如累积梯形积分)进行高精度计算。
✅ 步骤 2:后段 Clothoid 曲线生成(拼接点 → 终点)
后段曲线从中间曲率κm\kappa_mκm 线性下降至终点曲率 κ1\kappa_1κ1,表达式类似,但需要注意起点角度、相对位移和坐标系变化:
-
曲率变化:
κ2(s)=κm−a2s=κm−κm−κ1L2s,s∈[0,L2]\kappa_2(s) = \kappa_m - a_2 s = \kappa_m - \frac{\kappa_m - \kappa_1}{L_2}s,\quad s \in [0, L_2]κ2(s)=κm−a2s=κm−L2κm−κ1s,s∈[0,L2]
-
朝向角(从前段末尾 θ1end\theta_1^{\text{end}}θ1end开始):
θ2(s)=θ1end+κms−(κm−κ1)2L2s2\theta_2(s) = \theta_1^{\text{end}} + \kappa_m s - \frac{(\kappa_m - \kappa_1)}{2L_2}s^2θ2(s)=θ1end+κms−2L2(κm−κ1)s2
-
相对轨迹坐标:
x2(s)=∫0scos(θ2(t))dt,y2(s)=∫0ssin(θ2(t))dtx_2(s) = \int_0^s \cos(\theta_2(t))\,dt,\quad y_2(s) = \int_0^s \sin(\theta_2(t))\,dtx2(s)=∫0scos(θ2(t))dt,y2(s)=∫0ssin(θ2(t))dt
此段轨迹位于以第一段末尾为原点、以 Δθ1\Delta \theta_1Δθ1 为方向的局部坐标系中。
✅ 步骤 3:全局拼接与坐标还原
将后段轨迹旋转回全局坐标系,并平移至前段终点坐标:
[x2(s)y2(s)][x2global(s)y2global(s)]=[x1(L1)y1(L1)]+[cos(Δθ1)−sin(Δθ1)sin(Δθ1)cos(Δθ1)][x2(s)y2(s)][x2(s)y2(s)]\begin{bmatrix} x_2^{\text{global}}(s) \\ y_2^{\text{global}}(s) \end{bmatrix} = \begin{bmatrix} x_1(L_1) \\ y_1(L_1) \end{bmatrix} + \begin{bmatrix} \cos(\Delta\theta_1) & -\sin(\Delta\theta_1) \\ \sin(\Delta\theta_1) & \cos(\Delta\theta_1) \end{bmatrix} \begin{bmatrix} x_2(s) \\ y_2(s) \end{bmatrix}[x2(s)y2(s)][x2global(s)y2global(s)]=[x1(L1)y1(L1)]+[cos(Δθ1)sin(Δθ1)−sin(Δθ1)cos(Δθ1)][x2(s)y2(s)]
拼接后得到完整路径(x(s),y(s),θ(s),κ(s))(x(s), y(s), \theta(s), \kappa(s))(x(s),y(s),θ(s),κ(s)),其中:
- s∈[0,L1+L2]s \in [0, L_1 + L_2]s∈[0,L1+L2]
- 路径连续、光滑;
- 曲率连续,可用于 G2G^2G2 路径要求的应用场景,如自动驾驶、轨迹插值、仿真动画等。
- 上图展示了 Clothoid Pair 拼接的两类示意图,分别对应:
- XY 平面路径图(左图):
- 蓝色曲线为 Clothoid Pair 路径,由两段曲率线性变化的 Clothoid 构成;
- 黑色箭头表示每段路径上的姿态方向 θ(s)\theta(s)θ(s),揭示车辆或机器人在路径上如何平滑转向;
- 红点分别标记起点与终点。
- 曲率随弧长变化图(右图):
- 紫色曲线展示曲率 κ(s)\kappa(s)κ(s) 随路径长度的线性变化过程;
- 虚线为中间拼接点,说明两段曲率在拼接处连续,满足 G2G^2G2 要求;
- 整体曲率轮廓为“上升—下降”结构,典型的 Clothoid Pair 特征。
- XY 平面路径图(左图):
3 多段 Clothoid 全局 G² 拼接(Global G² Clothoid Spline)
在实际路径规划任务中,一条路径往往由多个离散关键节点组成,如:
- A*、Hybrid A*、RRT 等采样-搜索算法的路径输出;
- GPS、SLAM、地图建模系统的粗略路径;
- 手工标注或导航轨迹记录点等。
这类路径通常具有不连续的朝向与曲率,不能直接用于导航控制系统。我们需要通过 多段 Clothoid 拼接 的方式,将离散路径平滑化为整体连续的 G2G^2G2 曲线,从而实现:
- 位置连续;
- 切向角(方向)连续;
- 曲率连续 ⇒ 满足平滑加速度约束,便于后续动态控制器使用。
3.1 步骤总览与解释
步骤 | 内容 | 技术说明 |
---|---|---|
① 分段(Segmentation) | 将原始路径(折线或关键点序列)划分为多个子段,每段连接一对相邻节点 (Pi,Pi+1)(P_i, P_{i+1})(Pi,Pi+1) | 若原始路径已是曲线,也可按弧长等间距采样 |
② 单段拼接(Local Clothoid Pair) | 对每一段(Pi→Pi+1)(P_i \rightarrow P_{i+1})(Pi→Pi+1),使用 Clothoid Pair 算法(参见 §2)进行曲线拟合 | 需给定起终点、起终朝向、起终曲率,可用上一段结果或估算方向角 |
③ 曲率传递(Curvature Propagation) | 对于第 iii 段生成的曲线,其终点曲率κend(i)\kappa_{\text{end}}^{(i)}κend(i) 自动作为第 i+1i+1i+1 段的起始曲率 κ0(i+1)\kappa_0^{(i+1)}κ0(i+1) | 可实现整个路径曲率连续,消除突变,满足 G2G^2G2 要求 |
④ 可选全局优化(Global Refinement, optional) | 若需提升整体性能,可将所有段的参数 {L1(i),L2(i),κm(i)}i=1N−1\{L_1^{(i)}, L_2^{(i)}, \kappa_m^{(i)}\}_{i=1}^{N-1}{L1(i),L2(i),κm(i)}i=1N−1 一起优化,使目标函数(总弧长、加速度变化等)最小 | 可使用稀疏 Jacobian 的 Levenberg–Marquardt(Sparse-LM)方法高效求解;适用于离线或高精度轨迹需求 |
💡 解耦 vs 联合求解
- 顺序解耦算法(Local-only)
每一段独立求解,曲率从前段传递 ⇒ 时间复杂度 O(N)O(N)O(N),可用于实时系统、无人车导航; - 联合全局优化(Global optimization)
建立约束优化问题,统一考虑全部段落曲率与参数,使整体路径更“自然”、“柔和”,但代价更高。
建议策略:
- 实时规划或嵌入式系统 ⇒ 使用顺序解耦拼接;
- 离线优化、高精度路径(如道路建模、动画仿真)⇒ 考虑联合优化。
🚘 应用场景
- 自动驾驶中的车道生成与变道曲线;
- 工业机器人连续轨迹指令;
- 飞行器 / 航迹规划;
- 智能路径设计(游戏动画 / 仿真路径);
上图为 多段 Clothoid 全局 G² 拼接示意图,清晰展示了多段路径如何顺滑连接,每段都由一对 Clothoid 构成:
- 蓝色路径:3 段 Clothoid Pair 组成的全局曲线;
- 黑色箭头:表示每一点处的朝向 θ(s)\theta(s)θ(s),展现切向连续;
- 红点:起点与终点,整体轨迹完成平滑连接;
- 无突变、不折角:各段之间的拼接点不可见,表明已达 G2G^2G2 连续。
4 动态约束嵌入(速度规划)
在实际路径规划中,仅满足几何连续性(如 G2G^2G2)往往还不够,还必须考虑动态约束:
- 车辆在不同曲率下的最大允许速度;
- 转向执行器的限制(如最大转向速率);
- 提前考虑轨迹的可执行性 ⇒ 使轨迹既平滑又可控。
因此,我们需要将这些动态约束显式嵌入到路径规划和速度规划中,以保证轨迹不仅可达,而且可控、可执行。
4.1 侧向加速度约束(Lateral Acceleration)
在车辆以速度 v(s)v(s)v(s) 沿路径行驶时,受到的侧向加速度为:
ay(s)=v(s)2⋅κ(s)a_y(s) = v(s)^2 \cdot \kappa(s)ay(s)=v(s)2⋅κ(s)
为保证安全性与乘坐舒适性,侧向加速度应不超过某一最大值 ay,maxa_{y,\text{max}}ay,max(例如 3 m/s²)。由此得到第一项速度上界:
vmax,1(s)=ay,max∣κ(s)∣v_{\max,1}(s) = \sqrt{\dfrac{a_{y,\max}}{|\kappa(s)|}}vmax,1(s)=∣κ(s)∣ay,max
含义是:曲率越大(转弯越急),允许的速度越低;若曲率趋近于 0(直线段),则vmax,1→∞v_{\max,1} \to \inftyvmax,1→∞。
4.2 方向盘角速度约束(Steering Rate Limit)
在 Ackermann 模型下,转角 δ\deltaδ 与曲率 κ\kappaκ 满足近似:
δ(s)≈L⋅κ(s)\delta(s) \approx L \cdot \kappa(s)δ(s)≈L⋅κ(s)
其中 LLL 为车辆轴距。转向电机的变化速度有限,即:
∣δ˙∣=∣dδdt∣=∣dδds⋅dsdt∣=L⋅v(s)⋅∣dκds∣≤δ˙max|\dot\delta| = \left| \frac{d\delta}{dt} \right| = \left| \frac{d\delta}{ds} \cdot \frac{ds}{dt} \right| = L \cdot v(s) \cdot \left| \frac{d\kappa}{ds} \right| \le \dot\delta_{\max}∣δ˙∣=dtdδ=dsdδ⋅dtds=L⋅v(s)⋅dsdκ≤δ˙max
解得第二项速度上界:
vmax,2(s)=δ˙maxL⋅∣dκ/ds∣v_{\max,2}(s) = \frac{\dot\delta_{\max}}{L \cdot |d\kappa/ds|}vmax,2(s)=L⋅∣dκ/ds∣δ˙max
含义是:当曲率变化很快(方向变化陡),就要减速以免超过方向盘的极限响应速度。
特别注意:
- dκ/dsd\kappa/dsdκ/ds在 Clothoid 上是常数;
- 在拼接点处连续 ⇒ 不存在无限导数(相比样条更稳定);
- 该项约束对机器人和汽车控制器都非常关键。
4.3 最终速度剖面合成
综合各类速度约束,最终速度曲线为:
v(s)=min(vref,vmax,1(s),vmax,2(s))v(s) = \min\bigl(v_{\text{ref}},\;v_{\max,1}(s),\;v_{\max,2}(s)\bigr)v(s)=min(vref,vmax,1(s),vmax,2(s))
- vrefv_{\text{ref}}vref:参考期望速度(如限速、巡航速度等);
- 若任一约束限制速度更低,系统自动减速;
- 该规划结果可直接用于时间参数化,供轨迹跟踪控制器使用。
4.4 几何反馈调整(如仍超限)
若上述规划后仍出现速度过低(如转角太急、响应受限),说明当前路径几何结构对车辆动态过于苛刻,可通过以下方式缓解:
- 调小中间曲率 κm\kappa_mκm:减小曲率峰值;
- 延长 Clothoid 段长度 L1,L2L_1,L_2L1,L2:降低曲率变化率 a=ΔκLa = \frac{\Delta\kappa}{L}a=LΔκ;
- 适当放宽终点约束方向 θ1\theta_1θ1:减少角度跨度;
- 换用曲率缓变模型(如多段 Clothoid、圆弧-螺线过渡)。
这些属于从“速度层”反向影响“几何层”,实现路径-速度联合规划的一种形式。
图中展示了 Clothoid 曲线在**动态约束(侧向加速度与方向盘角速度)**下的速度剖面规划过程:
- 蓝色虚线:由最大侧向加速度 aya_yay 限制得到的速度上限 vmax,1v_{\mathrm{max},1}vmax,1;
- 橙色虚线:由最大方向盘角速度 δ˙\dot{\delta}δ˙ 限制得到的速度上限 vmax,2v_{\mathrm{max},2}vmax,2;
- 灰色水平线:理想参考速度 vrefv_{\text{ref}}vref;
- 黑色实线:最终取三者中最小值构成的速度轨迹 v(s)v(s)v(s)。
结论:
- 在曲率较小时 vmax,1v_{\max,1}vmax,1 非常高,不成为瓶颈;
- 当 dκds\frac{d\kappa}{ds}dsdκ 显著(即变化率高)时,方向盘变化率约束限制了速度;
- 可在速度过低处通过放松 Clothoid 曲率峰值 κm\kappa_mκm 或延长曲线长度来优化。
5. Clothoid Pair 手动求解算例(全过程 LaTeX 精编)
5.1 题目描述
连接两个状态:
已知量:P0=(0,0,0,0),P1=(10,2,θ1=0.3rad,κ1=0)\textbf{已知量:} P_0 = (0, 0, 0, 0), \quad P_1 = (10, 2, \theta_1 = 0.3\ \text{rad}, \kappa_1 = 0)已知量:P0=(0,0,0,0),P1=(10,2,θ1=0.3 rad,κ1=0)
这是一个典型的路径规划拼接问题,我们期望通过两段 Clothoid(曲率线性变化曲线)构造出一条“在中点背靠背拼接”的路径,实现从起点状态平滑过渡至终点状态,满足位置、朝向与曲率的连续。
5.2 未知量(目标求解)
L1,L2:两段 Clothoid 的弧长(长度)κm:中间曲率(两段并接处)L_1,\ L_2: \text{两段 Clothoid 的弧长(长度)} \\ \kappa_m: \text{中间曲率(两段并接处)}L1, L2:两段 Clothoid 的弧长(长度)κm:中间曲率(两段并接处)
这三个变量正是我们要解出的目标。它们将决定整条曲线的几何形态与动态性能。
辅助变量:曲率增长率(由未知量间接决定)
a1=κmL1,a2=κmL2a_1 = \frac{\kappa_m}{L_1}, \quad a_2 = \frac{\kappa_m}{L_2}a1=L1κm,a2=L2κm
5.3 方程组(构建约束)
为了保证轨迹是“严丝合缝”的,我们需要构造三个独立的约束条件,对应位置 (x,y)(x,y)(x,y) 和朝向 θ\thetaθ 的连续性要求。
(1) 方向角差约束
两段曲率线性变化段的角度增量应加总为目标方向变化:
Δθ1=12κmL1,Δθ2=12κmL2\Delta\theta_1 = \tfrac12 \kappa_m L_1,\quad \Delta\theta_2 = \tfrac12 \kappa_m L_2Δθ1=21κmL1,Δθ2=21κmL2
加总后匹配终点方向:
Δθ1+Δθ2=12κm(L1+L2)=0.3\Delta\theta_1 + \Delta\theta_2 = \tfrac12 \kappa_m (L_1 + L_2) = 0.3Δθ1+Δθ2=21κm(L1+L2)=0.3
(2)(3) 位置约束 (采用 1 阶 Fresnel 积分近似)
Clothoid 的几何积分没有解析解,但可以用一阶近似表达端点位移:
Δx≈L−a2L540,Δy≈aL36\Delta x \approx L - \frac{a^2 L^5}{40}, \quad \Delta y \approx \frac{a L^3}{6}Δx≈L−40a2L5,Δy≈6aL3
前段路径位移:
a1=κmL1Δx1=L1−a12L1540,Δy1=a1L136a_1 = \frac{\kappa_m}{L_1} \\ \Delta x_1 = L_1 - \frac{a_1^2 L_1^5}{40},\quad \Delta y_1 = \frac{a_1 L_1^3}{6}a1=L1κmΔx1=L1−40a12L15,Δy1=6a1L13
后段路径位移(逆方向):
a2=κmL2Δx2=L2−a22L2540,Δy2=−a2L236a_2 = \frac{\kappa_m}{L_2} \\ \Delta x_2 = L_2 - \frac{a_2^2 L_2^5}{40},\quad \Delta y_2 = -\frac{a_2 L_2^3}{6}a2=L2κmΔx2=L2−40a22L25,Δy2=−6a2L23
由于后段是“反向”的 Clothoid,我们需将其坐标旋转变换回前段末尾坐标系下。
装入旋转:
Rotate:Rotate:[x2′y2′]=[cosΔθ1−sinΔθ1sinΔθ1cosΔθ1][Δx2Δy2]\text{Rotate:} \quad \begin{bmatrix} x_2' \\ y_2' \end{bmatrix} = \begin{bmatrix} \cos\Delta\theta_1 & -\sin\Delta\theta_1 \\ \sin\Delta\theta_1 & \cos\Delta\theta_1 \end{bmatrix} \begin{bmatrix} \Delta x_2 \\ \Delta y_2 \end{bmatrix}Rotate:[x2′y2′]=[cosΔθ1sinΔθ1−sinΔθ1cosΔθ1][Δx2Δy2]
组合总位移:
Δx=Δx1+x2′,Δy=Δy1+y2′\Delta x = \Delta x_1 + x_2',\quad \Delta y = \Delta y_1 + y_2'Δx=Δx1+x2′,Δy=Δy1+y2′
最终位置约束:
Δx=10,Δy=2\Delta x = 10,\quad \Delta y = 2Δx=10,Δy=2
5.4 动态约束嵌入
我们现在以一个直观数值例子展示 Clothoid Pair 的整个解算过程,同时嵌入动态约束进行速度规划。
设定初值:
L1=L2=5.0,κm=0.06L_1 = L_2 = 5.0, \quad \kappa_m = 0.06L1=L2=5.0,κm=0.06
首先验证方向角约束:
12⋅0.06⋅(5+5)=0.3✓\tfrac12 \cdot 0.06 \cdot (5+5) = 0.3\quad \checkmark21⋅0.06⋅(5+5)=0.3✓
说明该中间曲率设定在角度约束上是有效的。
计算前段偏移量:
a1=0.012,Δx1≈5−(0.012)2⋅312540≈4.9888Δy1≈0.012⋅1256=0.25a_1 = 0.012, \quad \Delta x_1 \approx 5 - \frac{(0.012)^2 \cdot 3125}{40} \approx 4.9888 \\ \Delta y_1 \approx \frac{0.012 \cdot 125}{6} = 0.25a1=0.012,Δx1≈5−40(0.012)2⋅3125≈4.9888Δy1≈60.012⋅125=0.25
计算后段偏移量(方向相反):
a2=0.012,Δx2≈4.9888,Δy2≈−0.25Δθ1=12⋅0.06⋅5=0.15a_2 = 0.012, \quad \Delta x_2 \approx 4.9888, \quad \Delta y_2 \approx -0.25 \\ \Delta\theta_1 = \tfrac12 \cdot 0.06 \cdot 5 = 0.15a2=0.012,Δx2≈4.9888,Δy2≈−0.25Δθ1=21⋅0.06⋅5=0.15
将后段偏移量旋转回全局坐标:
[x2′y2′]=[cos0.15−sin0.15sin0.15cos0.15][4.9888−0.25]≈[4.9290.493]\begin{bmatrix} x_2' \\ y_2' \end{bmatrix} = \begin{bmatrix} \cos 0.15 & -\sin 0.15 \\ \sin 0.15 & \cos 0.15 \end{bmatrix} \begin{bmatrix} 4.9888 \\ -0.25 \end{bmatrix} \approx \begin{bmatrix} 4.929 \\ 0.493 \end{bmatrix}[x2′y2′]=[cos0.15sin0.15−sin0.15cos0.15][4.9888−0.25]≈[4.9290.493]
最终组合:
Δx=4.9888+4.929=9.92,Δy=0.25+0.493=0.743\Delta x = 4.9888 + 4.929 = 9.92,\quad \Delta y = 0.25 + 0.493 = 0.743Δx=4.9888+4.929=9.92,Δy=0.25+0.493=0.743
虽然末端位置未完全匹配目标 (10,2)(10,2)(10,2),但角度约束满足、几何误差可控,后续可作为初值用于数值优化迭代。
5.5 动态约束嵌入检验
车辆实际行驶还需考虑动态限制,为此加入如下限制条件:
aymax=3.0m/s2,δ˙max=0.5rad/s,L=2.5m,vref=15.0m/sa_y^{\max} = 3.0 \ \mathrm{m/s^2}, \quad \dot\delta_{\max} = 0.5 \ \mathrm{rad/s}, \quad L = 2.5\ \mathrm{m}, \quad v_{\text{ref}} = 15.0\ \mathrm{m/s}aymax=3.0 m/s2,δ˙max=0.5 rad/s,L=2.5 m,vref=15.0 m/s
由本例参数:κm=0.06\kappa_m = 0.06κm=0.06、a=0.012a = 0.012a=0.012,推导动态速度限制:
vmax,1=3.00.06≈7.07m/svmax,2=0.52.5⋅0.012=0.50.03≈16.67m/sv_{\max,1} = \sqrt{\frac{3.0}{0.06}} \approx 7.07\ \mathrm{m/s} \\ v_{\max,2} = \frac{0.5}{2.5 \cdot 0.012} = \frac{0.5}{0.03} \approx 16.67\ \mathrm{m/s}vmax,1=0.063.0≈7.07 m/svmax,2=2.5⋅0.0120.5=0.030.5≈16.67 m/s
最终速度剖面:
v(s)=min(15.0,vmax,1,vmax,2)=7.07m/sv(s) = \min(15.0,\ v_{\max,1},\ v_{\max,2}) = 7.07\ \mathrm{m/s}v(s)=min(15.0, vmax,1, vmax,2)=7.07 m/s
✅ 动态验证通过: 虽不满参考速度 15m/s,但满足两种动态限制,说明当前 Clothoid 曲率设定在可控范围内。若要提速,可在几何层进一步优化 κm\kappa_mκm 或延展段长 L1,L2L_1,L_2L1,L2。
6 python实现代码
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import fresneldef clothoid_segment(x0, y0, theta0, kappa0, kappa1, L, ds=0.1):a = (kappa1 - kappa0) / Ls = np.arange(0, L + ds, ds)kappa = kappa0 + a * stheta = theta0 + kappa0 * s + 0.5 * a * s**2A = np.sqrt(np.abs(a) / np.pi)u = np.sqrt(np.abs(a) / np.pi) * sC, S = fresnel(u)dx = C * np.sign(a)dy = S * np.sign(a)X = x0 + (1 / A) * (dx * np.cos(theta0) - dy * np.sin(theta0))Y = y0 + (1 / A) * (dx * np.sin(theta0) + dy * np.cos(theta0))return X, Y, theta, kappadef rotate_and_translate(x, y, theta, dx, dy, dtheta):cos_t = np.cos(dtheta)sin_t = np.sin(dtheta)x_new = cos_t * x - sin_t * y + dxy_new = sin_t * x + cos_t * y + dytheta_new = theta + dthetareturn x_new, y_new, theta_new# === 输入参数(手动设置) ===
x0, y0, theta0, kappa0 = 0.0, 0.0, 0.0, 0.0
x1, y1, theta1, kappa1 = 10.0, 2.0, 0.3, 0.0
L1 = 5.0
L2 = 5.0
kappa_m = 0.06
ds = 0.1# === 前段 Clothoid ===
X1, Y1, TH1, K1 = clothoid_segment(x0, y0, theta0, kappa0, kappa_m, L1, ds)
x_end, y_end, theta_end = X1[-1], Y1[-1], TH1[-1]# === 后段 Clothoid(从末端反向构造,再旋转) ===
X2_, Y2_, TH2_, K2_ = clothoid_segment(0, 0, 0, kappa_m, kappa1, L2, ds)
dtheta = theta_end
X2, Y2, TH2 = rotate_and_translate(X2_, Y2_, TH2_, x_end, y_end, dtheta)# === 合并轨迹 ===
X = np.concatenate([X1, X2])
Y = np.concatenate([Y1, Y2])
TH = np.concatenate([TH1, TH2])
K = np.concatenate([K1, K2_])# === 可视化 ===
plt.figure(figsize=(8, 4))
plt.plot(X, Y, 'b-', linewidth=2, label='Clothoid Pair Path')
plt.scatter([x0, x1], [y0, y1], c='red', zorder=5, label='Endpoints')# 添加方向箭头
for i in range(0, len(X), int(1/ds * 1.0)):plt.arrow(X[i], Y[i], 0.5 * np.cos(TH[i]), 0.5 * np.sin(TH[i]),head_width=0.1, head_length=0.2, fc='k', ec='k')plt.axis('equal')
plt.title("Clothoid Pair Path with Orientation")
plt.xlabel("X")
plt.ylabel("Y")
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()