转载自https://blog.youkuaiyun.com/q597967420/article/details/79031791
如果QP问题只有等式约束没有不等式约束,那么是可以闭式求解(close form)的。闭式求解效率要快很多,而且只需要用到矩阵运算,不需要QPsolver。
这里介绍Nicholas Roy文章中闭式求解的方法。
1.QP等式约束构建
闭式法中的
Q
Q
Q矩阵计算和之前一样,但约束的形式与之前略为不同,在之前的方法中,等式约束只要构造成
[
.
.
.
]
p
=
b
[...]p=b
[...]p=b的形式就可以了,而闭式法中,每段poly都构造成
M
i
p
i
=
d
i
M
i
=
[
M
0
M
t
]
i
T
,
d
i
=
[
d
0
,
d
T
]
i
M_ip_i=d_i \\ M_i=[M_0\quad M_t]^T_i,\\ d_i=[d_0,d_T]_i
Mipi=diMi=[M0Mt]iT,di=[d0,dT]i
其中
d
0
,
d
T
d_0,d_T
d0,dT为第
i
i
i段poly的起点和终点的各阶导数组成的向量,比如只考虑PVA:
d
0
=
[
p
0
,
v
0
,
a
0
]
T
]
d_0=[p_0,v_0,a_0]^T]
d0=[p0,v0,a0]T],当然也可以把jerk,snap等加入到向量。注意:这里是不管每段端点的PVA是否已知,都写进来。
块合并各段轨迹的约束方程得到
M
t
o
t
a
l
⏟
k
(
n
+
1
)
×
6
k
[
p
1
⋮
p
k
]
=
[
d
1
⋮
d
k
]
=
[
p
1
(
t
0
)
v
1
(
t
0
)
a
1
(
t
0
)
p
1
(
t
1
)
v
1
(
t
1
)
a
1
(
t
1
)
⋮
p
k
(
t
k
−
1
)
v
k
(
t
k
−
1
)
a
k
(
t
k
−
1
)
p
k
(
t
k
)
v
k
(
t
k
)
a
k
(
t
k
)
]
6
k
×
1
\begin{aligned} \underbrace{M_{total}}_{k(n+1)\times 6k} \begin{bmatrix}p_1\\\vdots\\ p_k\end{bmatrix} =\begin{bmatrix}d_1\\\vdots \\d_k\end{bmatrix} =\begin{bmatrix}p_1(t_0)\\v_1(t_0)\\a_1(t_0)\\p_1(t_1)\\v_1(t_1)\\a_1(t_1)\\ \vdots \\p_k(t_{k−1})\\v_k(t_{k−1})\\a_k(t_{k−1})\\p_k(t_k)\\v_k(t_k)\\a_k(t_k)\end{bmatrix}_{6k\times 1} \end{aligned}
k(n+1)×6k
Mtotal⎣⎢⎡p1⋮pk⎦⎥⎤=⎣⎢⎡d1⋮dk⎦⎥⎤=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡p1(t0)v1(t0)a1(t0)p1(t1)v1(t1)a1(t1)⋮pk(tk−1)vk(tk−1)ak(tk−1)pk(tk)vk(tk)ak(tk)⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤6k×1
k
k
k为轨迹段数,
n
n
n为轨迹的阶数,设只考虑pva,
M
t
o
t
a
l
M_{total}
Mtotal的size为
(
n
o
r
d
e
r
+
1
)
k
×
6
k
(n_{order}+1)k\times 6k
(norder+1)k×6k。这里为了简化,没有把每段poly的timestamp都改成从0开始,一般,为了避免timestamp太大引起数值问题,每段poly的timestamp都成0开始。
由上式可以看到, M t o t a l M_{total} Mtotal是已知的(怎么构造可参见文章一种的等式约束构造方法),而 d d d中只有少部分(起点、终点的pva等)是已知的,其他大部分是未知的。如果能够求出 d d d,那么轨迹参数可以通过 p = M − 1 d p=M^{−1}d p=M−1d很容易求得。
2. 如何求d?
闭式法的思路是:将
d
d
d向量中的变量分成两部分:”d中所有已知量组成的Fix部分
d
F
d_F
dF”和”所有未知量组成的Free部分
d
P
d_P
dP”。然后通过推导,根据
d
F
d_F
dF求得
d
P
d_P
dP,从而得到
d
d
d,最后求得
p
p
p。
使得
d
=
C
[
d
F
d
P
]
d=C\begin{bmatrix}d_F\\d_P\end{bmatrix}
d=C[dFdP]
下面介绍整个推导过程,
2.1. 消除重复变量(连续性约束)
可以会发现,上面构造等式约束时,并没有加入连续性约束,连续性约束并不是直接加到等式约束中。考虑到连续性(这里假设PVA连续),
d
d
d向量中很多变量其实重复了,即
p
i
(
t
i
)
=
p
i
+
1
(
t
i
)
v
i
(
t
i
)
=
v
i
+
1
(
t
i
)
a
i
(
t
i
)
=
a
i
+
1
(
t
i
)
\begin{aligned} p_i(t_i)&=p_{i+1}(t_i)\\ v_i(t_i)&=v_{i+1}(t_i)\\ a_i(t_i)&=a_{i+1}(t_i) \end{aligned}
pi(ti)vi(ti)ai(ti)=pi+1(ti)=vi+1(ti)=ai+1(ti)
因此需要一个映射矩阵将一个变量映射到两个重复的变量上,怎么映射?
- 如
[
a
a
]
=
[
1
1
]
a
\begin{bmatrix}a\\a\end{bmatrix}=\begin{bmatrix}1\\1\end{bmatrix}a
[aa]=[11]a,将变量
a
a
a映射到左边向量中的两个变量。
所以构造映射矩阵 C 1 ( 6 k × 3 ( k + 1 ) ) C_{1(6k\times 3(k+1))} C1(6k×3(k+1)):
[ d 1 ⋮ d k ] 6 k × 1 = [ 1 1 1 1 1 1 1 1 1 ⋱ ] [ p ( t 0 ) v ( t 0 ) a ( t 0 ) p ( t 1 ) v ( t 1 ) a ( t 1 ) p ( t 2 ) v ( t 2 ) a ( t 2 ) ⋮ p ( t k ) v ( t k ) a ( t k ) ] 3 ( k + 1 ) × 1 \begin{bmatrix} d_1\\ \vdots \\d_k \end{bmatrix}_{6k\times 1} = \begin{bmatrix} 1&&&&&&\\ &1&&&&&\\ &&1&&&&\\ &&&1&&&\\ &&&&1&&\\ &&&&&1&\\ &&&1&&&\\ &&&&1&&\\ &&&&&1&\\ &&&&&&\ddots \end{bmatrix} \begin{bmatrix} p(t_0)\\v(t_0)\\a(t_0)\\p(t_1)\\v(t_1)\\a(t_1)\\p(t_2)\\v(t_2)\\a(t_2)\\\vdots \\p(t_k)\\v(t_k)\\a(t_k) \end{bmatrix}_{3(k+1)\times1} ⎣⎢⎡d1⋮dk⎦⎥⎤6k×1=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡111111111⋱⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡p(t0)v(t0)a(t0)p(t1)v(t1)a(t1)p(t2)v(t2)a(t2)⋮p(tk)v(tk)a(tk)⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤3(k+1)×1
即 d = C 1 d ′ d=C_1d^\prime d=C1d′。
2.2 向量元素置换
消除掉重复变量之后,需要调整
d
′
d^\prime
d′中的变量,把fix部分和free部分分开排列,可以左成一个置换矩阵
C
2
C_2
C2,使得
d
′
=
C
2
[
d
F
d
P
]
d^\prime=C_2\begin{bmatrix}d_F\\d_P\end{bmatrix}
d′=C2[dFdP]
C
2
C_2
C2矩阵怎么构造?
- 举个例子,设
d
′
=
[
a
b
c
d
]
d^\prime=\begin{bmatrix}a\\b\\c\\d\end{bmatrix}
d′=⎣⎢⎢⎡abcd⎦⎥⎥⎤,其中
a
,
c
,
d
a,c,d
a,c,d是已知(
d
F
d_F
dF),
b
b
b未知(
d
P
d_P
dP),构造一个
4
×
4
4\times4
4×4的单位阵,取
d
F
d_F
dF所在的(1,3,4)列放到左边,再取
d
P
d_P
dP所在的(2)列放到右边,就构造出置换矩阵
C
2
C_2
C2:
[ a b c d ] = [ 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 ] = [ a c d b ] \begin{bmatrix}a\\b\\c\\d\end{bmatrix}= \begin{bmatrix}1&0&0&0\\0&0&0&1\\ 0&1&0&0\\0&0&1&0\end{bmatrix} = \begin{bmatrix}a\\c\\d\\b\end{bmatrix} ⎣⎢⎢⎡abcd⎦⎥⎥⎤=⎣⎢⎢⎡1000001000010100⎦⎥⎥⎤=⎣⎢⎢⎡acdb⎦⎥⎥⎤
2.3 转成无约束优化问题
由上面两步可得
d
=
C
1
C
2
[
d
F
d
P
]
=
C
[
d
F
d
P
]
p
=
M
−
1
d
=
M
−
1
C
[
d
F
d
P
]
\begin{aligned} d&=C_1C_2\begin{bmatrix}d_F\\d_P\end{bmatrix}=C\begin{bmatrix}d_F\\d_P\end{bmatrix}\\ p&=M^{-1}d=M^{-1}C\begin{bmatrix}d_F\\d_P\end{bmatrix} \end{aligned}
dp=C1C2[dFdP]=C[dFdP]=M−1d=M−1C[dFdP]
代入优化函数
J
=
p
T
Q
p
=
[
d
F
d
P
]
T
C
T
M
−
T
Q
M
−
1
C
[
d
F
d
P
]
=
[
d
F
d
P
]
T
R
[
d
F
d
P
]
=
[
d
F
d
P
]
T
[
R
F
F
R
F
P
R
P
F
R
P
P
]
[
d
F
d
P
]
=
d
F
T
R
F
F
d
F
+
d
F
T
R
F
P
d
P
+
d
P
T
R
P
F
d
F
+
d
P
T
R
P
P
d
P
\begin{aligned} J&=p^TQp = \begin{bmatrix}d_F\\d_P\end{bmatrix}^TC^TM^{-T}QM^{-1}C\begin{bmatrix}d_F\\d_P\end{bmatrix} \\ &= \begin{bmatrix}d_F\\d_P\end{bmatrix}^TR\begin{bmatrix}d_F\\d_P\end{bmatrix} =\begin{bmatrix}d_F\\d_P\end{bmatrix}^T \begin{bmatrix}R_{FF} & R_{FP} \\R_{PF} & R_{PP} \end{bmatrix} \begin{bmatrix}d_F\\d_P\end{bmatrix}\\ &=d^T_FR_{FF} d_F + d^T_FR_{FP} d_P+d^T_PR_{PF} d_F+d^T_PR_{PP} d_P \end{aligned}
J=pTQp=[dFdP]TCTM−TQM−1C[dFdP]=[dFdP]TR[dFdP]=[dFdP]T[RFFRPFRFPRPP][dFdP]=dFTRFFdF+dFTRFPdP+dPTRPFdF+dPTRPPdP
令
J
J
J对
d
P
d_P
dP的导数
∂
J
∂
d
P
=
0
\frac{\partial J}{\partial d_P}=0
∂dP∂J=0求极值点:
2
d
F
T
R
F
P
+
2
d
P
T
R
P
P
=
0
d
P
=
−
R
P
P
−
1
R
F
P
T
d
F
\begin{aligned} 2d_F^TR_{FP} + 2d^T_PR_{PP} =0\\ d_P = -R^{-1}_{PP}R^T_{FP}d_F \end{aligned}
2dFTRFP+2dPTRPP=0dP=−RPP−1RFPTdF
至此求得 d P d_P dP,从而求出 p p p。
3. 闭式法步骤
总结一下整个闭式法的步骤:
- 先确定轨迹阶数(比如5阶),再确定 d d d向量中的约束量(pva),进而根据各段的时间分配求得 M t o t a l M_{total} Mtotal。
- 根据连续性约束构造映射矩阵 C 1 C_1 C1,并确定 d d d向量中哪些量是Fix(比如起点终点pva,中间点的p等),哪些量是Free,进而构造置换矩阵 C 2 C_2 C2,并求得 C = C 1 C 2 C=C_1C_2 C=C1C2。
- 计算QP目标函数中的Q( min J e r k / S n a p \min Jerk/Snap minJerk/Snap)并计算 R = C T M − T Q M − 1 C R=C^TM^{-T}QM^{-1}C R=CTM−TQM−1C,根据fix变量的长度将R拆分成 R F F , R F P , R P F , R P P R_{FF},R_{FP},R_{PF},R_{PP} RFF,RFP,RPF,RPP四块。
- 填入已知变量得到 d F d_F dF,并根据 d p = − R P P − 1 R F P T d F d_p=−R^{−1}_{PP}R^T_{FP}d_F dp=−RPP−1RFPTdF计算得到 d P d_P dP。
- 根据公式 p = M − 1 C [ d F d P ] p=M^{-1}C\begin{bmatrix}d_F\\d_P\end{bmatrix} p=M−1C[dFdP]计算得到轨迹参数p。
- 闭式法主要计算量就在A矩阵的求逆,其他计算基本上是矩阵构造,所以效率比较高,但由于没有不等式约束,所以在中间点只能加强约束,corridor不能直接加到QP问题中,只能是通过压点来实现corridor。
在对计算效率要求比较高或者不想用QPsolver时,可以使用闭式法求解。
代码见这里,由于效果和文章一中的效果一样,这里就不再贴图。
参考文献
Richter C, Bry A, Roy N. Polynomial trajectory planning for aggressive quadrotor flight in dense indoor environments[M]//Robotics Research. Springer International Publishing, 2016: 649-666.