前言
本文基于Apollo的参考线平滑,主要参考以下文章
开发者说丨离散点曲线平滑原理
决策规划算法二:生成参考线
一、问题描述
一般情况下,高精地图给出的道路中心线不够平滑,会导致车辆行驶不够平稳,因此我们希望在进行planning之前能够对参考线进行平滑。
优化对象:离散中心线点坐标
(
x
i
,
y
i
)
(x_i,y_i)
(xi,yi)
优化方法:二次规划
二次规划的一般形式如下:
Minimize
1
2
x
T
Q
x
+
c
T
x
subject to
A
x
≤
b
,
E
x
=
d
,
x
≥
0
,
\begin{align*} \text{Minimize} \quad & \frac{1}{2} \mathbf{x}^T \mathbf{Q} \mathbf{x} + \mathbf{c}^T \mathbf{x} \\ \text{subject to} \quad & \mathbf{A} \mathbf{x} \leq \mathbf{b}, \\ & \mathbf{E} \mathbf{x} = \mathbf{d}, \\ & \mathbf{x} \geq \mathbf{0}, \end{align*}
Minimizesubject to21xTQx+cTxAx≤b,Ex=d,x≥0,
二、优化目标
- 平滑度代价
c
o
s
t
1
cost1
cost1
也就是 ∣ P 1 P 3 → ∣ \left| \overrightarrow{P_1 P_3} \right| P1P3 的模长,从图中可以直观的看出当 ∠ P 0 P 1 P 2 \angle P_0P_1P_2 ∠P0P1P2越大,则 ∣ P 1 P 3 → ∣ \left| \overrightarrow{P_1 P_3} \right| P1P3 越小。
c o s t 1 cost1 cost1的物理意义是 P 1 P 3 → \overrightarrow{P_1 P_3} P1P3的模长, P 1 P 3 → = P 1 P 2 → + P 1 P 0 → \overrightarrow{P_1 P_3} =\overrightarrow{P_1 P_2}+\overrightarrow{P_1 P_0} P1P3=P1P2+P1P0.
因此: c o s t 1 = ( ( x 0 − x 1 ) + ( x 2 − x 1 ) ) 2 + ( ( y 0 − y 1 ) + ( y 2 − y 1 ) ) 2 = ( x 0 + x 2 − 2 x 1 ) 2 + ( y 0 + y 2 − 2 y 1 ) 2 \begin{align} cost1 &= ((x_0-x_1)+(x_2-x_1))^2+((y_0-y_1)+(y_2-y_1))^2 \\ & = (x_0+x_2-2x_1)^2+(y_0+y_2-2y_1)^2 \end{align} cost1=((x0−x1)+(x2−x1))2+((y0−y1)+(y2−y1))2=(x0+x2−2x1)2+(y0+y2−2y1)2
因此 c o s t 1 cost1 cost1推广到一般形式为:
c o s t 1 = ∑ i = 1 n − 1 ( x i − 1 + x i + 1 − 2 x i ) 2 + ( y i − 1 + y i + 1 − 2 y i ) 2 cost1 = \sum_{i=1}^{n-1}(x_{i-1}+x_{i+1}-2x_i)^2+(y_{i-1}+y_{i+1}-2y_i)^2 cost1=i=1∑n−1(xi−1+xi+1−2xi)2+(yi−1+yi+1−2yi)2
为了后续计算 Q Q Q矩阵,将上式写成矩阵形式:
c o s t 1 = [ x 0 + x 2 − 2 x 1 , y 0 + y 2 − 2 y 1 , … , x n − 3 + x n − 1 − 2 x n − 2 , y n − 3 + y n − 1 − 2 y n − 2 ] [ x 0 + x 2 − 2 x 1 y 0 + y 2 − 2 y 1 … x n − 3 + x n − 1 − 2 x n − 2 y n − 3 + y n − 1 − 2 y n − 2 ] cost1 = [x_{0}+x_{2}-2x_1,y_{0}+y_{2}-2y_1,\ldots,x_{n-3}+x_{n-1}-2x_{n-2},y_{n-3}+y_{n-1}-2y_{n-2}] \begin{bmatrix} x_{0}+x_{2}-2x_1 \\ y_{0}+y_{2}-2y_1 \\ \ldots \\ x_{n-3}+x_{n-1}-2x_{n-2} \\ y_{n-3}+y_{n-1}-2y_{n-2} \end{bmatrix} \\ cost1=[x0+x2−2x1,y0+y2−2y1,…,xn−3+xn−1−2xn−2,yn−3+yn−1−2yn−2] x0+x2−2x1y0+y2−2y1…xn−3+xn−1−2xn−2yn−3+yn−1−2yn−2
令 X = [ x 0 , y 0 , x 1 , y 1 , … , x n − 1 , y n − 1 ] X=[x_0,y_0,x_1,y_1,\ldots,x_{n-1},y_{n-1}] X=[x0,y0,x1,y1,…,xn−1,yn−1],系数矩阵为A,那么 c o s t 1 = X ∗ A ∗ ( X ∗ A ) T = X ∗ A ∗ A T ∗ X cost1 = X*A*(X*A)^T = X*A*A^T*X cost1=X∗A∗(X∗A)T=X∗A∗AT∗X
同时A矩阵为 A = [ 1 0 0 0 … 0 0 1 0 0 … 0 − 2 0 0 0 … 0 0 − 2 0 0 … 0 1 0 0 0 … 0 0 1 0 0 … 0 ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ 0 0 0 0 … 1 ] A=\begin{bmatrix} 1&0 &0&0&\ldots&0 \\ 0&1 &0&0&\ldots&0 \\ -2&0 &0&0&\ldots&0 \\ 0&-2 &0&0&\ldots&0 \\ 1&0 &0&0&\ldots&0 \\ 0&1 &0&0&\ldots&0 \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\ 0&0 &0&0&\ldots&1 \end{bmatrix} A= 10−2010⋮0010−201⋮0000000⋮0000000⋮0………………⋮…000000⋮1
其中A矩阵维度为 2 n ∗ 2 ( n − 2 ) 2n*2(n-2) 2n∗2(n−2).
同时因为 c o s t 1 = X ∗ A ∗ ( X ∗ A ) T = X ∗ A ∗ A T ∗ X cost1 = X*A*(X*A)^T = X*A*A^T*X cost1=X∗A∗(X∗A)T=X∗A∗AT∗X,因此系数矩阵 Q 1 = A ∗ A T Q_1 = A*A^T Q1=A∗AT
因此 Q 1 = [ I − 2 I I O ⋯ O O O − 2 I 5 I − 4 I I ⋯ O O O I − 4 I 6 I − 4 I ⋯ O O O O I − 4 I 6 I ⋯ O O O ⋮ ⋮ ⋮ ⋮ ⋱ ⋮ ⋮ ⋮ O O O O ⋯ 6 I − 4 I I O O O O ⋯ − 4 I 5 I − 2 I O O O O ⋯ O − 2 I I ] Q_1 =\begin{bmatrix}I&-2I&I&O&\cdots&O&O&O\\-2I&5I&-4I&I&\cdots&O&O&O\\I&-4I&6I&-4I&\cdots&O&O&O\\O&I&-4I&6I&\cdots&O&O&O\\\vdots&\vdots&\vdots&\vdots&\ddots&\vdots&\vdots&\vdots\\O&O&O&O&\cdots&6I&-4I&I\\O&O&O&O&\cdots&-4I&5I&-2I\\O&O&O&O&\cdots&O&-2I&I\end{bmatrix} Q1= I−2IIO⋮OOO−2I5I−4II⋮OOOI−4I6I−4I⋮OOOOI−4I6I⋮OOO⋯⋯⋯⋯⋱⋯⋯⋯OOOO⋮6I−4IOOOOO⋮−4I5I−2IOOOO⋮I−2II
其中 I = [ 1 0 0 1 ] I= \begin{bmatrix}1&0\\ 0&1 \end{bmatrix} I=[1001]
上面公式可以使用如下matlab代码进行验证:
clc;clear all;
n = 10; #点个数
a=zeros(2*n,(2*n)-4);
for i=1:(2*n)-4
a(i,i)=1;
a(i+2,i)=-2;
a(i+4,i)=1;
end
matrix = a*a';
% 获取矩阵的行数和列数
[n, m] = size(matrix);
% 确定块矩阵的大小
block_size = 2;
block_rows = n / block_size;
block_cols = m / block_size;
% 初始化分块矩阵C
C = cell(block_rows, block_cols);
% 填充分块矩阵C
for i = 1:block_rows
for j = 1:block_cols
C{i, j} = matrix(block_size*(i-1)+1:block_size*i, block_size*(j-1)+1:block_size*j);
end
end
% 输出结果
disp('分块矩阵C:');
for i = 1:block_rows
for j = 1:block_cols
fprintf('C{%d, %d} = \n', i, j);
disp(C{i, j});
end
end
res = zeros(block_rows,block_cols);
for i =1:block_rows
for j=1:block_cols
res(i,j) =C{i,j}(1,1)/1;
end
end
disp(res);
运行结果如下图:
- 均匀性
c
o
s
t
2
cost2
cost2
平滑后的参考线的每两个相邻点之间的长度尽量均匀一致。
因此 c o s t 2 : cost2: cost2:
c o s t 2 = ∣ P 1 P 2 → ∣ 2 + ∣ P 2 P 3 → ∣ 2 = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 + ( x 3 − x 2 ) 2 + ( y 3 − y 2 ) 2 \begin{align} cost2 &=\left| \overrightarrow{P_1 P_2} \right|^2+ \left| \overrightarrow{P_2 P_3}\right|^2 \\ &= (x_2-x_1)^2+(y_2-y_1)^2+(x_3-x_2)^2+(y_3-y_2)^2 \end{align} cost2= P1P2 2+ P2P3 2=(x2−x1)2+(y2−y1)2+(x3−x2)2+(y3−y2)2
因此推广到一般形式:
c o s t 2 = ∑ i = 0 n − 1 ( x i − x i + 1 ) 2 + ( y i − y i + 1 ) 2 cost2 = \sum_{i=0}^{n-1}(x_i-x_{i+1})^2+(y_i-y_{i+1})^2 cost2=i=0∑n−1(xi−xi+1)2+(yi−yi+1)2
将上式推广到矩阵形式:
c o s t 2 = [ ( x i − x i + 1 ) , ( y i − y i + 1 ) ] [ ( x i − x i + 1 ) ( y i − y i + 1 ) ] cost2 = [(x_i-x_{i+1}),(y_i-y_{i+1})] \begin{bmatrix} (x_i-x_{i+1}) \\ (y_i-y_{i+1})\end{bmatrix} cost2=[(xi−xi+1),(yi−yi+1)][(xi−xi+1)(yi−yi+1)],
,那么 c o s t 2 = X ∗ A 1 ∗ ( X ∗ A 1 ) T = X ∗ A 1 ∗ A 1 T ∗ X cost2 = X*A_1*(X*A_1)^T = X*A_1*A_1^T*X cost2=X∗A1∗(X∗A1)T=X∗A1∗A1T∗X,其中 A 1 A_1 A1为:
A 1 = [ 1 0 0 0 … 0 0 1 0 0 … 0 − 1 0 0 0 … 0 0 − 1 0 0 … 0 0 0 0 0 … 0 0 0 0 0 … 0 ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ 0 0 0 0 … − 1 ] A_1 = \begin{bmatrix} 1&0 &0&0&\ldots&0 \\ 0&1 &0&0&\ldots&0 \\ -1&0 &0&0&\ldots&0 \\ 0&-1 &0&0&\ldots&0 \\ 0&0 &0&0&\ldots&0 \\ 0&0 &0&0&\ldots&0 \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\ 0&0 &0&0&\ldots&-1 \end{bmatrix} A1= 10−1000⋮0010−100⋮0000000⋮0000000⋮0………………⋮…000000⋮−1 其中 A 1 A_1 A1矩阵维度为 2 n ∗ 2 ( n − 1 ) 2n*2(n-1) 2n∗2(n−1),那么 Q 2 = A 1 ∗ A 1 T Q_2 = A_1*A_1^T Q2=A1∗A1T,
Q 2 = [ I − I O ⋯ O O − I 2 I − I ⋯ O O O − I 2 I ⋯ O O ⋮ ⋮ ⋮ ⋱ ⋮ ⋮ O O O ⋯ 2 I − I O O O ⋯ − I I ] Q_2 = \begin{bmatrix}I&-I&O&\cdots&O&O\\-I&2I&-I&\cdots&O&O\\O&-I&2I&\cdots&O&O\\\vdots&\vdots&\vdots&\ddots&\vdots&\vdots\\O&O&O&\cdots&2I&-I\\O&O&O&\cdots&-I&I\end{bmatrix} Q2= I−IO⋮OO−I2I−I⋮OOO−I2I⋮OO⋯⋯⋯⋱⋯⋯OOO⋮2I−IOOO⋮−II
其中 I = [ 1 0 0 1 ] I= \begin{bmatrix}1&0\\ 0&1 \end{bmatrix} I=[1001]
上面公式可以使用如下matlab代码进行验证:
clc;clear all;
n = 10;
a=zeros(2*n,(2*(n-1)));
for i=1:(2*(n-1))
a(i,i)=1;
a(i+2,i)=-1;
end
matrix = a*a';
% 获取矩阵的行数和列数
[n, m] = size(matrix);
% 确定块矩阵的大小
block_size = 2;
block_rows = n / block_size;
block_cols = m / block_size;
% 初始化分块矩阵C
C = cell(block_rows, block_cols);
% 填充分块矩阵C
for i = 1:block_rows
for j = 1:block_cols
C{i, j} = matrix(block_size*(i-1)+1:block_size*i, block_size*(j-1)+1:block_size*j);
end
end
% 输出结果
disp('分块矩阵C:');
for i = 1:block_rows
for j = 1:block_cols
fprintf('C{%d, %d} = \n', i, j);
disp(C{i, j});
end
end
res = zeros(block_rows,block_cols);
for i =1:block_rows
for j=1:block_cols
res(i,j) =C{i,j}(1,1)/1;
end
end
disp(res);
运行结果为:
- 参考线偏移程度cost3
平滑后的参考线,希望能够保留原始道路的几何信息,不会把弯道的处的参考线平滑成一条直线。使用平滑后点与原始点的距离来表示
c o s t 3 = ∣ P 1 P 1 r → ∣ 2 + ∣ P 2 P 2 r → ∣ 2 = ( x 1 − x 1 r ) 2 + ( y 1 − y 1 r ) 2 + ( x 2 − x 2 r ) 2 + ( y 2 − y 2 r ) 2 \begin{align} cost3 &=\left| \overrightarrow{P_1 P_1r} \right|^2+ \left| \overrightarrow{P_2 P_2r}\right|^2 \\ &= (x_1-x_{1r})^2+(y_1-y_{1r})^2+(x_2-x_{2r})^2+(y_2-y_{2r})^2 \end{align} cost3= P1P1r 2+ P2P2r 2=(x1−x1r)2+(y1−y1r)2+(x2−x2r)2+(y2−y2r)2
因此推广到一般形式:
c o s t 3 = ∑ i = 0 n − 1 ( x i − x i r ) 2 + ( y i − y i r ) 2 = ∑ i = 0 n − 1 ( x i 2 + x i r 2 − 2 ∗ x i ∗ x i r ) cost3 = \sum_{i=0}^{n-1}(x_i-x_{ir})^2+(y_i-y_{ir})^2 = \sum_{i=0}^{n-1}(x_i^2+x_{ir}^2-2*x_i*x_{ir}) cost3=i=0∑n−1(xi−xir)2+(yi−yir)2=i=0∑n−1(xi2+xir2−2∗xi∗xir),因为常数项不影响优化结果,因此去掉常数项并写成矩阵形式:令 X = [ x 0 , y 0 , x 1 , y 1 , … , x n − 1 , y n − 1 ] X=[x_0,y_0,x_1,y_1,\ldots,x_{n-1},y_{n-1}] X=[x0,y0,x1,y1,…,xn−1,yn−1], c o s t 3 = X ∗ A 3 ∗ X T − 2 ∗ c ∗ X T cost3= X*A_3*X^T-2*c*X^T cost3=X∗A3∗XT−2∗c∗XT,
c o s t 3 = X ∗ [ 1 0 0 0 … 0 0 1 0 0 … 0 0 0 0 0 … 0 0 0 0 0 … 0 0 0 0 0 … 0 0 0 0 0 … 0 ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ 0 0 0 0 … 1 ] ∗ X T − 2 ∗ [ x 0 r , y 0 r , … , x n − 1 r , y n − 1 r ] ∗ X T cost3 = X* \begin{bmatrix} 1&0 &0&0&\ldots&0 \\ 0&1 &0&0&\ldots&0 \\ 0&0 &0&0&\ldots&0 \\ 0&0 &0&0&\ldots&0 \\ 0&0 &0&0&\ldots&0 \\ 0&0 &0&0&\ldots&0 \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\ 0&0 &0&0&\ldots&1 \end{bmatrix}*X^T-2*[x_{0r},y_{0r} ,\ldots,x_{n-1r},y_{n-1r}] *X^T cost3=X∗ 100000⋮0010000⋮0000000⋮0000000⋮0………………⋮…000000⋮1 ∗XT−2∗[x0r,y0r,…,xn−1r,yn−1r]∗XT,其中 A 3 A_3 A3是 2 n ∗ 2 n 2n*2n 2n∗2n的方阵.
因此:
Q 3 = [ I O ⋯ O O I ⋯ O ⋮ ⋮ ⋱ ⋮ O O O I ] Q_3 = \begin{bmatrix}I&O&\cdots&O\\O&I&\cdots&O\\\vdots&\vdots&\ddots&\vdots\\O&O&O&I\end{bmatrix} Q3= IO⋮OOI⋮O⋯⋯⋱OOO⋮I ,
其中 I = [ 1 0 0 1 ] I= \begin{bmatrix}1&0\\ 0&1 \end{bmatrix} I=[1001]
综上所述
Q
=
x
∗
Q
1
+
y
∗
Q
2
+
z
∗
Q
3
Q = x*Q_1+y*Q_2+z*Q_3
Q=x∗Q1+y∗Q2+z∗Q3,其中
x
,
y
,
z
x,y,z
x,y,z分别为,平滑度,均匀性,参考线偏移程度的权重,综上因此
Q
Q
Q矩阵可以写成:
[
X
+
Y
+
Z
−
2
X
−
Y
X
0
0
0
0
5
X
+
2
Y
+
Z
−
4
X
−
Y
X
0
0
0
0
6
X
+
2
Y
+
Z
−
4
X
−
Y
X
0
0
0
0
6
X
+
2
Y
+
Z
−
4
X
−
Y
X
0
0
0
0
5
X
+
2
Y
+
Z
−
2
X
−
Y
0
0
0
0
0
X
+
Y
+
Z
]
\begin{bmatrix} X+Y+Z& -2X-Y& X& 0& 0& 0 \\ 0& 5X+2Y+Z& -4X-Y& X& 0& 0 \\ 0& 0& 6X+2Y+Z& -4X-Y& X& 0 \\ 0& 0& 0& 6X+2Y+Z& -4X-Y& X \\ 0& 0& 0& 0& 5X+2Y+Z& -2X-Y\\ 0& 0& 0& 0& 0& X+Y+Z\\ \end{bmatrix}
X+Y+Z00000−2X−Y5X+2Y+Z0000X−4X−Y6X+2Y+Z0000X−4X−Y6X+2Y+Z0000X−4X−Y5X+2Y+Z0000X−2X−YX+Y+Z
其中
X
=
x
∗
[
1
0
0
1
]
,
Y
=
y
∗
[
1
0
0
1
]
,
,
Z
=
z
∗
[
1
0
0
1
]
X= x*\begin{bmatrix}1&0\\0&1 \end{bmatrix},Y= y*\begin{bmatrix}1&0\\0&1 \end{bmatrix},,Z= z*\begin{bmatrix}1&0\\0&1 \end{bmatrix}
X=x∗[1001],Y=y∗[1001],,Z=z∗[1001]
注意:这个Q矩阵只写了6个点情况,也就是12*12维,更高维只需要写
X
,
−
4
X
−
Y
,
5
X
+
2
Y
+
Z
X,-4X-Y,5X+2Y+Z
X,−4X−Y,5X+2Y+Z这三项
三、添加约束
参考线约束的平滑较为简单,主要只有和原始参考线距离这一部分,具体内容如下,只考虑边界线约束:
x
i
,
l
o
w
e
r
≤
x
i
≤
x
i
,
u
p
p
e
r
y
i
,
l
o
w
e
r
≤
y
i
≤
y
i
,
u
p
p
e
r
x_{i,lower}\leq x_i\leq x_{i,upper}\\y_{i,lower}\leq y_i\leq y_{i,upper}
xi,lower≤xi≤xi,upperyi,lower≤yi≤yi,upper,
可以继续写成:
x
i
,
r
−
b
o
u
n
d
≤
x
i
≤
x
i
,
r
+
b
o
u
n
d
y
i
,
r
−
b
o
u
n
d
≤
y
i
≤
y
i
,
r
+
b
o
u
n
d
x_{i,r}-bound\leq x_i \leq x_{i,r} +bound\\y_{i,r}-bound\leq y_i \leq y_{i,r} +bound
xi,r−bound≤xi≤xi,r+boundyi,r−bound≤yi≤yi,r+bound
同时对于端点,需要特殊处理,使其等于起始点因此:
x
0
,
r
≤
x
0
≤
x
0
,
r
y
0
,
r
≤
y
0
≤
y
0
,
r
x
n
−
1
,
r
≤
x
n
−
1
≤
x
n
−
1
,
r
y
n
−
1
,
r
≤
y
n
−
1
≤
y
n
−
1
,
r
x_{0,r}\leq x_0\leq x_{0,r}\\y_{0,r}\leq y_0\leq y_{0,r}\\ x_{n-1,r}\leq x_{n-1}\leq x_{n-1,r}\\y_{n-1,r}\leq y_{n-1}\leq y_{n-1,r}
x0,r≤x0≤x0,ry0,r≤y0≤y0,rxn−1,r≤xn−1≤xn−1,ryn−1,r≤yn−1≤yn−1,r
四、总结
具体的c++代码实现可以参考apollo参考线平滑部分