前言
最近学习了深蓝学院的《视觉slam进阶:从零开始手写VIO》,第二章讲IMU传感器,提到了旋转积分的欧拉角形式,正好最近也用到这个公式,所以把该公式的详细推导过程认真推导了一遍。
一些说明
按照习惯,推导过程中使用的导航坐标系为东北天坐标系( E N U ENU ENU),IMU的载体坐标系为载体坐标系为:右、前,上( X X X, Y Y Y, Z Z Z),欧拉角的旋转顺序为: Z Z Z, X X X, Y Y Y (偏航、俯仰,滚转)。待会从下面的推导过程中我们可以看到,基于欧拉角法的推导公式和载体坐标系的定义以及旋转顺序都是有关的,所以在这里我们做一些说明。另外可以用matlab辅助公式推导,很方便,不易出错。
推导过程
R
n
b
=
R
1
b
(
y
)
⋅
R
2
1
(
p
)
⋅
R
n
2
(
r
)
R_{n}^{b}=R_{1}^{b}(y) \cdot R_{2}^{1}(p) \cdot R_{n}^{2}(r)
Rnb=R1b(y)⋅R21(p)⋅Rn2(r)
其中:
R
1
b
(
y
)
=
[
c
y
−
s
y
0
s
y
c
y
0
0
0
1
]
R_{1}^{b}(y)=\left[\begin{array}{ccc} {c y} & {-s y} & {0} \\ {s y} & {c y} & {0} \\ {0} & {0} & {1} \end{array}\right]
R1b(y)=⎣
⎡cysy0−sycy0001⎦
⎤
R
2
1
(
p
)
=
[
1
0
0
0
c
p
−
s
p
0
s
p
c
p
]
R_{2}^{1}(p)=\left[\begin{array}{ccc} {1} & {0} & {0} \\ {0} & {c p} & {-s p} \\ {0} & {s p} & {c p} \end{array}\right]
R21(p)=⎣
⎡1000cpsp0−spcp⎦
⎤
R
n
2
(
r
)
=
[
c
r
0
s
r
0
1
0
−
s
r
0
c
r
]
R_{n}^{2}(r)=\left[\begin{array}{ccc} {c r} & {0} & {s r} \\ {0} & {1} & {0} \\ {-s r} & {0} & {c r} \end{array}\right]
Rn2(r)=⎣
⎡cr0−sr010sr0cr⎦
⎤
R
1
b
(
y
)
R_{1}^{b}(y)
R1b(y)表示绕
Z
Z
Z轴的旋转矩阵,
R
2
1
(
p
)
R_{2}^{1}(p)
R21(p)表示绕
X
X
X轴的旋转矩阵,
R
n
2
(
r
)
R_{n}^{2}(r)
Rn2(r)表示绕
Y
Y
Y轴的旋转矩阵。
R
n
b
R_{n}^{b}
Rnb为导航系到载体坐标系的转换矩阵,
X
b
X^{b}
Xb表示载体坐标系下的坐标,
X
n
X^{n}
Xn表示导航坐标系下的坐标,则有以下公式:
X
n
=
R
n
b
⋅
X
b
X^{n}=R_{n}^{b} \cdot X^{b}
Xn=Rnb⋅Xb
X
b
X^{b}
Xb的求解如下:
X
b
=
R
2
n
(
r
)
⋅
R
1
2
(
p
)
⋅
R
b
1
(
y
)
⋅
X
n
X^{b}=R_{2}^{n}(r) \cdot R_{1}^{2}(p) \cdot R_{b}^{1}(y) \cdot X^{n}
Xb=R2n(r)⋅R12(p)⋅Rb1(y)⋅Xn
第一步:
假设已经完成绕三个轴的旋转,则最后绕
Y
Y
Y轴的角速度在载体坐标系和导航坐标系都是一样的,所以有如下公式:
ω
b
(
r
)
=
[
0
d
r
d
t
0
]
\omega_{b}(r)=\left[\begin{array}{c} {0} \\ {\frac{d r}{d t}} \\ {0} \end{array}\right]
ωb(r)=⎣
⎡0dtdr0⎦
⎤
第二步:
假设已经完成了前两组旋转,最后一组旋转没有完成,如果接着完成最后一步旋转,则和第一步一样,绕
X
X
X轴的角速度在两个坐标系下是一样的,则有如下公式:
ω
b
(
p
)
=
R
2
n
(
r
)
⋅
[
d
p
d
t
0
0
]
\omega_{b}(p)=R_{2}^{n}(r) \cdot\left[\begin{array}{c} {\frac{d p}{d t}} \\ {0} \\ {0} \end{array}\right]
ωb(p)=R2n(r)⋅⎣
⎡dtdp00⎦
⎤
第三步:
分析和第二步类似。假设已经完成了第一组旋转,最后两组旋转没有完成,如果接着完成最后两组旋转,则绕
Z
Z
Z轴的角速度在两个坐标系下是一样的,则有如下公式:
ω
b
(
y
)
=
R
2
n
(
r
)
⋅
R
1
2
(
p
)
⋅
[
0
0
d
y
d
t
]
\omega_{b}(y)=R_{2}^{n}(r) \cdot R_{1}^{2}(p) \cdot\left[\begin{array}{c} {0} \\ {0} \\ {\frac{d y}{d t}} \end{array}\right]
ωb(y)=R2n(r)⋅R12(p)⋅⎣
⎡00dtdy⎦
⎤
最后有:
ω
b
=
ω
b
(
y
)
+
ω
b
(
p
)
+
ω
b
(
r
)
\omega_{b}=\omega_{b}(y)+\omega_{b}(p)+\omega_{b}(r)
ωb=ωb(y)+ωb(p)+ωb(r)
ω
b
=
R
2
n
(
r
)
⋅
R
1
2
(
p
)
⋅
[
0
0
d
y
d
t
]
+
R
2
n
(
r
)
⋅
[
d
p
d
t
0
0
]
+
[
0
d
r
d
t
0
]
=
[
c
r
0
−
s
r
⋅
c
p
0
1
s
p
s
r
0
c
r
⋅
c
p
]
⋅
[
d
p
d
t
d
r
d
t
d
y
d
t
]
\omega_{b}=R_{2}^{n}(r) \cdot R_{1}^{2}(p) \cdot\left[\begin{array}{c} {0} \\ {0} \\ {\frac{d y}{d t}} \end{array}\right]+R_{2}^{n}(r) \cdot\left[\begin{array}{c} {\frac{d p}{d t}} \\ {0} \\ {0} \end{array}\right]+\left[\begin{array}{c} {0} \\ {\frac{d r}{d t}} \\ {0} \end{array}\right]=\left[\begin{array}{ccc} {c r} & {0} & {-s r \cdot c p} \\ {0} & {1} & {s p} \\ {s r} & {0} & {c r \cdot c p} \end{array}\right] \cdot\left[\begin{array}{c} {\frac{d p}{d t}} \\ {\frac{d r}{d t}} \\ {\frac{d y}{d t}} \end{array}\right]
ωb=R2n(r)⋅R12(p)⋅⎣
⎡00dtdy⎦
⎤+R2n(r)⋅⎣
⎡dtdp00⎦
⎤+⎣
⎡0dtdr0⎦
⎤=⎣
⎡cr0sr010−sr⋅cpspcr⋅cp⎦
⎤⋅⎣
⎡dtdpdtdrdtdy⎦
⎤
上式中
ω
b
\omega_{b}
ωb是角速度在载体坐标系下的投影,即陀螺仪数据,
d
p
d
t
\frac{d p}{d t}
dtdp,
d
r
d
t
\frac{d r}{d t}
dtdr,
d
y
d
t
\frac{d y}{d t}
dtdy是角速度在导航坐标系下的投影。
同样可以得到:
[
d
p
d
t
d
r
d
t
d
y
d
t
]
=
[
c
r
0
s
r
s
p
⋅
sr
/
c
p
1
−
s
p
⋅
c
r
/
c
p
−
s
r
/
c
p
0
c
r
/
c
p
]
⋅
ω
b
\left[\begin{array}{l} {\frac{d p}{d t}} \\ {\frac{d r}{d t}} \\ {\frac{d y}{d t}} \end{array}\right]=\left[\begin{array}{ccc} {c r} & {0} & {s r} \\ {s p \cdot \operatorname{sr} / c p} & {1} & {-s p \cdot c r / c p} \\ {-s r / c p} & {0} & {c r / c p} \end{array}\right] \cdot \omega_{b}
⎣
⎡dtdpdtdrdtdy⎦
⎤=⎣
⎡crsp⋅sr/cp−sr/cp010sr−sp⋅cr/cpcr/cp⎦
⎤⋅ωb
从上式可以看出,当俯仰角接近
9
0
∘
90^{\circ}
90∘时,是无解的,所以欧拉角法不能用在全姿态飞行器中,等于与平台惯导的“环架自锁”,这一点在使用该公式的时候要注意。
Matlab辅助推导的代码如下:
% 姿态矩阵更新的欧拉角形式公式推导
% 旋转顺序:Z,X,Y
% 参考: KINEMATICS OF MOVING FRAMES MIT KINEMATICS OF MOVING FRAMES MIT
syms r p y
syms dpdt drdt dydt
x_p = [1, 0, 0;
0, cos(p), -sin(p);
0, sin(p), cos(p)];
y_r = [cos(r), 0, sin(r);
0, 1, 0;
-sin(r), 0, cos(r)];
z_y = [cos(y), -sin(y), 0;
sin(y), cos(y), 0;
0, 0, 1];
x_p_trans = x_p';
y_r_trans = y_r';
z_y_trans = z_y';
dp_t_vector=[dpdt;0;0]; %X轴
dr_t_vector=[0;drdt;0]; %Y轴
dy_t_vector=[0;0;dydt]; %Z轴
% y_r_trans x_p_trans z_y_trans
% 陀螺仪角速度
ang_vel=y_r_trans*x_p_trans*dy_t_vector+y_r_trans*dp_t_vector+dr_t_vector
% 结果如下:
% ang_vel=
% dpdt*cos(r) - dydt*cos(p)*sin(r)
% drdt + dydt*sin(p)
% dpdt*sin(r) + dydt*cos(p)*cos(r)
% 整理可得如下结果: % [dpdt;drdt;dydt]
% 转换矩阵如下:
% [cos(r), 0, -sin(r)*cos(p);
% 0, 1, sin(p);
% sin(r), 0, cos(r)*cos(p)]
% 求矩阵的转置
ang_vel_matrix= [cos(r), 0, -sin(r)*cos(p);
0, 1, sin(p);
sin(r), 0, cos(r)*cos(p)];
ang_vel_inv_matrix = inv(ang_vel_matrix)
% 结果如下:
% ang_vel_inv_matrix =
%
% [ cos(r)/(cos(r)^2 + sin(r)^2), 0, sin(r)/(cos(r)^2 + sin(r)^2)]
% [ (sin(p)*sin(r))/(cos(p)*cos(r)^2 + cos(p)*sin(r)^2), 1, -(cos(r)*sin(p))/(cos(p)*cos(r)^2 + cos(p)*sin(r)^2)]
% [ -sin(r)/(cos(p)*cos(r)^2 + cos(p)*sin(r)^2), 0, cos(r)/(cos(p)*cos(r)^2 + cos(p)*sin(r)^2)]
% 整理可得:
% [ cos(r), 0, sin(r)]
% [ (sin(p)*sin(r))/cos(p), 1, -cos(r)*sin(p)/cos(p)]
% [ -sin(r)/cos(p), 0, cos(r)/cos(p)]
同时我也顺带验证了参考2中的推导公式,参考2中的旋转顺序为 Z Z Z, Y Y Y, X X X,推导结果和2中一致。代码如下:
% 姿态矩阵更新的欧拉角形式公式推导
% 旋转顺序:Z,Y,X
% 参考: KINEMATICS OF MOVING FRAMES MIT KINEMATICS OF MOVING FRAMES MIT
syms r p y
syms dpdt drdt dydt
x_r = [1, 0, 0;
0, cos(r), -sin(r);
0, sin(r), cos(r)];
y_p = [cos(p), 0, sin(p);
0, 1, 0;
-sin(p), 0, cos(p)];
z_y = [cos(y), -sin(y), 0;
sin(y), cos(y), 0;
0, 0, 1];
x_r_trans = x_r';
y_p_trans = y_p';
z_y_trans = z_y';
dr_t_vector = [drdt;0;0]; %x轴
dp_t_vector = [0;dpdt;0]; %y轴
dy_t_vector = [0;0;dydt]; %z轴
% 旋转顺序:x_r_trans y_p_trans z_y_trans
% 陀螺仪角速度
ang_vel = x_r_trans*y_p_trans*dy_t_vector+x_r_trans*dp_t_vector+dr_t_vector
% 结果如下
% ang_vel =
% drdt - dydt*sin(p)
% dpdt*cos(r) + dydt*cos(p)*sin(r)
% dydt*cos(p)*cos(r) - dpdt*sin(r)
% drdt; dpdt; dydt
% 整理得:
% 1 , 0 , -sin(p);
% 0 , cos(r) , sin(r)*cos(p);
% 0 , -sin(r) , cos(p)*cos(r);
% 求矩阵的转置
ang_vel_matrix=[1 , 0 , -sin(p);
0 , cos(r) , sin(r)*cos(p);
0 , -sin(r) , cos(r)*cos(p)];
ang_vel_inv_matrix = inv(ang_vel_matrix)
% 结果如下:
% [ 1, (sin(p)*sin(r))/(cos(p)*cos(r)^2 + cos(p)*sin(r)^2), (cos(r)*sin(p))/(cos(p)*cos(r)^2 + cos(p)*sin(r)^2)]
% [ 0, cos(r)/(cos(r)^2 + sin(r)^2), -sin(r)/(cos(r)^2 + sin(r)^2)]
% [ 0, sin(r)/(cos(p)*cos(r)^2 + cos(p)*sin(r)^2), cos(r)/(cos(p)*cos(r)^2 + cos(p)*sin(r)^2)]
% 化简得:
% [ 1, sin(r)*tan(p), cos(r)*tan(p)]
% [ 0, cos(r), -sin(r)]
% [ 0, sin(r)/cos(p), cos(r)/cos(p)]
参考
1.《惯性导航基本原理》 刘保中
2. KINEMATICS OF MOVING FRAMES MIT
3.深蓝学院《视觉slam进阶:从零开始手写VIO》课程