本文为学习自动驾驶决策规划算法第二章第七节速度规划的学习笔记。
1 ST图
如上图假设有一个障碍物横向穿过自车轨迹,则对应的ST图如下图所示
自车可以规划如下图所示的速度,对于绿色轨迹,在 t 1 t_1 t1、 t 2 t_2 t2时刻,在 s s s上自车都未到达障碍物位置,表示的是让行,让障碍物先过;
对于橙色轨迹,在 t 1 t_1 t1、 t 2 t_2 t2时刻,在 s s s上自车都已超过障碍物位置,表示的是先行,自己先过;
这样就对应两个凸空间,橙色表示的是加速通过凸空间,绿色表示的是让行凸空间;
1.1 SL与ST之间的相互影响
初始时刻,自车沿直线匀速行驶
在第 i i i个规划周期自车感知到有动态障碍物:
假设判断会与障碍物发生碰撞,如果自车轨迹不做任何变化,则无法做速度规划来避免碰撞,除非倒车,如下图所示,
可以在碰撞区域生成一个虚拟障碍物,重新做路径规划:
此时的ST图就变为下图所示:
可以看出当前帧的SL会影响当前帧的ST;
同理第 i i i帧的轨迹加 i + 1 i+1 i+1帧的预测会影响 i + 1 i+1 i+1帧的轨迹规划,进而影响 i + 1 i+1 i+1帧的ST:
Apollo在不同的版本中对EMplanner不断地更新,早已取消SL,ST迭代机制,本文中后续内容SL只负责静态障碍物,ST只负责动态障碍物。
2 速度规划详解
2.1 生成ST图
前提是已有路径规划的结果,速度规划以规划的路径作为参考线。
第一步生成路径的index2s;
第二步将动态障碍物投影到以路径规划为坐标轴的frenet坐标系上,得到动态障碍物的 ( s 0 , l 0 , s 0 ˙ , l 0 ˙ ) (s_0,l_0,\dot{s_0},\dot{l_0}) (s0,l0,s0˙,l0˙);
第三步,动态障碍物投影生成ST图:
假设障碍物在上述frenet坐标系下是匀速运动,即 s 0 ˙ \dot{s_0} s0˙和 l 0 ˙ \dot{l_0} l0˙都是常数,那么障碍物到达路径的时间是
t a = l 0 l 0 ˙ \begin{equation} t_a=\frac{l_0}{\dot{l_0}} \end{equation} ta=l0˙l0
障碍物到达路径时的 s s s坐标是:
s a = s 0 + t a ⋅ s 0 ˙ \begin{equation} s_a=s_0+t_a\cdot\dot{s_0} \end{equation} sa=s0+ta⋅s0˙
有些场景还是需要结合路径规划的,比如前方有慢车、对向来车等。
2.2 动态规划
速度规划的起点为路径规划的起点,
s = 0 \begin{equation} s=0 \end{equation} s=0
s ˙ = ∣ v ∣ \begin{equation} \dot{s}=|v| \end{equation} s˙=∣v∣
s ¨ = ∣ a ∣ \begin{equation} \ddot{s}=|a| \end{equation} s¨=∣a∣
如下图所示, s e n d s_{end} send表示路径规划的路径长度, t e n d t_{end} tend表示速度规划的时间最大值,影响 t e n d t_{end} tend的因素可能有很多,会导致不同场景下这个值的变化范围比较大,而 t e n d t_{end} tend很大的时候会导致动态规划的规模很大,实际上可以人为给 t e n d t_{end} tend指定一个值,比如8s,速度规划不一定要规划到路径终点,动态规划的过程与路径规划中的动态规划类似:
如上图所示,速度规划的离散点间距较小,连接离散点的曲线可以直接用直线,动态规划的代价函数包括障碍物代价、加速度代价、推荐速度代价、jerk代价等等:
d p _ c o s t = 障碍物代价 + 加速度代价 + 推荐速度代价 + j e r k 代价 \begin{equation} dp\_cost=障碍物代价+加速度代价+推荐速度代价+jerk代价 \end{equation} dp_cost=障碍物代价+加速度代价+推荐速度代价+jerk代价
2.2.1 障碍物代价
点到线段的最短距离
d 1 = ∣ v 1 ∣ \begin{equation} d_1=|\boldsymbol{v}_1| \end{equation} d1=∣v1∣
d 2 = ∣ v 1 + v 2 ∣ \begin{equation} d_2=|\boldsymbol{v}_1+\boldsymbol{v}_2| \end{equation} d2=∣v1+v2∣
d 3 = h = ∣ v 1 × v 2 ∣ ∣ v 2 ∣ \begin{equation} d_3=h=\frac{|\boldsymbol{v}_1\times\boldsymbol{v}_2|}{|\boldsymbol{v}_2|} \end{equation} d3=h=∣v2∣∣v1×v2∣
点到线段的最短距离为 d 1 d_1 d1或 d 2 d_2 d2或 d 3 d_3 d3,可以通过向量的点积来判断是哪一个:
如上图所示
左侧情况对应
{ v 1 ⋅ v 2 > 0 v 2 ⋅ v 3 > 0 \begin{equation} \begin{cases} \boldsymbol{v_1}\cdot\boldsymbol{v_2}>0 \\ \boldsymbol{v_2}\cdot\boldsymbol{v_3}>0 \end{cases} \end{equation} {v1⋅v2>0v2⋅v3>0
中间情况对应
{ v 1 ⋅ v 2 < 0 v 2 ⋅ v 3 < 0 \begin{equation} \begin{cases} \boldsymbol{v_1}\cdot\boldsymbol{v_2}<0 \\ \boldsymbol{v_2}\cdot\boldsymbol{v_3}<0 \end{cases} \end{equation} {v1⋅v2<0v2⋅v3<0
右侧情况对应
{ v 1 ⋅ v 2 < 0 v 2 ⋅ v 3 > 0 \begin{equation} \begin{cases} \boldsymbol{v_1}\cdot\boldsymbol{v_2}<0 \\ \boldsymbol{v_2}\cdot\boldsymbol{v_3}>0 \end{cases} \end{equation} {v1⋅v2<0v2⋅v3>0
所以,如果 v 1 ⋅ v 2 \boldsymbol{v_1}\cdot\boldsymbol{v_2} v1⋅v2与 v 2 ⋅ v 3 \boldsymbol{v_2}\cdot\boldsymbol{v_3} v2⋅v3同号,则有:
m i n _ d = m i n ( ∣ v 1 ∣ , ∣ v 3 ∣ ) \begin{equation} min\_d=min(|\boldsymbol{v_1}|,|\boldsymbol{v_3}|) \end{equation} min_d=min(∣v1∣,∣v3∣)
如果 v 1 ⋅ v 2 \boldsymbol{v_1}\cdot\boldsymbol{v_2} v1⋅v2与 v 2 ⋅ v 3 \boldsymbol{v_2}\cdot\boldsymbol{v_3} v2⋅v3异号,则有:
m i n _ d = ∣ v 1 × v 2 ∣ ∣ v 2 ∣ \begin{equation} min\_d=\frac{|\boldsymbol{v}_1\times\boldsymbol{v}_2|}{|\boldsymbol{v}_2|} \end{equation} min_d=∣v2∣∣v1×v2∣
那么可以根据点到障碍物的距离,定义代价函数,比如
c o s t _ o b s = { ∞ ∣ m i n _ d ∣ < 2 衰减函数 2 < ∣ m i n _ d ∣ < 3 0 3 < ∣ m i n _ d ∣ \begin{equation} cost\_obs=\begin{cases} \infin&|min\_d|<2 \\ 衰减函数 & 2<|min\_d|<3 \\ 0&3<|min\_d| \end{cases} \end{equation} cost_obs=⎩ ⎨ ⎧∞衰减函数0∣min_d∣<22<∣min_d∣<33<∣min_d∣
2.2.2 加速度、jerk以及参考速度代价
如上图所示,已知起点的运动数据(式3、4、5),可得:
s 1 ˙ = s 1 = 0 t 1 − 0 \begin{equation} \dot{s_1}=\frac{s_1=0}{t_1-0} \end{equation} s1˙=t1−0s1=0
s 1 ¨ = s 1 ˙ − ∣ v ∣ t 1 − 0 \begin{equation} \ddot{s_1}=\frac{\dot{s_1}-|\boldsymbol{v}|}{t_1-0} \end{equation} s1¨=t1−0s1˙−∣v∣
s 1 ′ ′ ′ = s 1 ¨ − ∣ a ∣ t 1 − 0 \begin{equation} {s_1}'''=\frac{\ddot{s_1}-|\boldsymbol{a}|}{t_1-0} \end{equation} s1′′′=t1−0s1¨−∣a∣
那么加速度代价就是:
c o s t _ a c c = w a c c ⋅ s ¨ 2 \begin{equation} cost\_acc=w_{acc}\cdot\ddot{s}^2 \end{equation} cost_acc=wacc⋅s¨2
那么jerk代价就是:
c o s t _ j e r k = w j e r k ⋅ s ′ ′ ′ 2 \begin{equation} cost\_jerk=w_{jerk}\cdot{s}'''^2 \end{equation} cost_jerk=wjerk⋅s′′′2
参考速度代价就是:
c o s t _ r e f _ s p e e d = w r e f ⋅ ( s ˙ − v r ) 2 \begin{equation} cost\_ref\_speed=w_{ref}\cdot(\dot{s}-v_r)^2 \end{equation} cost_ref_speed=wref⋅(s˙−vr)2
确定好代价函数后,利用动态规划计算到达第一行和最后一列离散点的最小代价和对应的路径(如下图中红色虚线区域内),就是动态规划的结果,也即是速度规划的粗解(如下图绿色折线或橙色折线):
2.3 二次规划
如图黑色线段表示障碍物,绿色折线表示动态规划的粗解,那么紫色区域就是二次规划的凸空间:
与路径规划相似,速度规划的凸空间也有 s l b s_{lb} slb、 s u b s_{ub} sub、 s l b ˙ \dot{s_{lb}} slb˙、 s u b ˙ \dot{s_{ub}} sub˙,对于速度的上下界,在有障碍物的区域(如上图橙色虚线的区域),以障碍物的速度为上下界,另外路径本身有曲率,车辆也要满足一些运动约束:
a y m a x = 0.2 g \begin{equation} a_{ymax}=0.2g \end{equation} aymax=0.2g
所以有
v 2 ≤ R ⋅ a y m a x = a y m a x k a p p a \begin{equation} v_2≤R\cdot{a_{ymax}}=\frac{a_{ymax}}{kappa} \end{equation} v2≤R⋅aymax=kappaaymax
0 ≤ s ˙ ≤ ( a y m a x k a p p a ) 1 2 \begin{equation} 0≤\dot{s}≤{(\frac{a_{ymax}}{kappa})}^{\frac{1}{2}} \end{equation} 0≤s˙≤(kappaaymax)21
动力学约束:
− 6 ≤ s ¨ ≤ 4 \begin{equation} -6≤\ddot{s}≤4 \end{equation} −6≤s¨≤4
不允许倒车约束:
s i + 1 ≥ s i \begin{equation} s_{i+1}≥s_i \end{equation} si+1≥si
连续性约束:
s i + 1 = s i + s i ˙ d t + 1 2 s i ¨ d t 2 + 1 6 ( s ¨ i + 1 − s i ¨ d t ) d t 3 \begin{equation} s_{i+1}=s_i+\dot{s_i}dt+\frac{1}{2}\ddot{s_i}dt^2+\frac{1}{6}(\frac{\ddot{s}_{i+1}-\ddot{s_i}}{dt})dt^3 \end{equation} si+1=si+si˙dt+21si¨dt2+61(dts¨i+1−si¨)dt3
s ˙ i + 1 = s i ˙ + s i ¨ d t + 1 2 s ¨ i + 1 − s ¨ i d t d t 3 \begin{equation} \dot{s}_{i+1}=\dot{s_i}+\ddot{s_i}dt+\frac{1}{2}\frac{\ddot{s}_{i+1}-\ddot{s}_i}{dt}dt^3 \end{equation} s˙i+1=si˙+si¨dt+21dts¨i+1−s¨idt3
另外二次规划的代价函数为:
c o s t _ f u n c t i o n = ∑ w 1 ( s ˙ i 2 − v r e f ) 2 + w 2 s ¨ i 2 + w 3 s i ′ ′ ′ 2 \begin{equation} cost\_function=\sum{w_1}(\dot{s}^2_i-v_{ref})^2+w_2\ddot{s}^2_i+w_3{s'''_i}^2 \end{equation} cost_function=∑w1(s˙i2−vref)2+w2s¨i2+w3si′′′2
3 代码实现
代码实现
动态规划采样
s的范围从0开始到路径规划的path总长度,可以采用非均匀采样,s越小的越密,越大越稀疏;
t采用均匀采样,每0.5s采样一个点,最大8s;
s_list = [0:0.5:4.5,...5.5:1:14.5,...16:1.5:29.5,...32:2.5:54.5];t_list = 0.5:0.5:8;
代价计算
对于加速度代价,如果加速度超过动力学约束时,给较大的代价:
% 计算加速度代价,这里注意,加速度不能超过车辆动力学上下限
if cur_s_dot2 < 4 && cur_s_dot2 > -6cost_accel = w_cost_accel * cur_s_dot2^2;
else% 超过车辆动力学限制,代价会增大很多倍cost_accel = 100000 * w_cost_accel * cur_s_dot2^2;
end