龙格库塔法一般用于求解一阶微分方程,是通过迭代的方式求解的,对于比较复杂的一阶微分方程,不方便用数学的方法求解,我们可以通过龙格库塔法进行求解。
拉格朗日中值定理
根据拉格朗日中值定理,设函数
f
(
x
)
f(x)
f(x),满足:
(1)在闭区间
[
x
0
,
x
1
]
[x_0,x_1]
[x0,x1]上连续;
(2)在开区间
(
x
0
,
x
1
)
(x_0,x_1)
(x0,x1)内可导;
那么在开区间
(
x
0
,
x
1
)
(x_0,x_1)
(x0,x1)内至少有一点
ξ
\xi
ξ使:
即:
其中 f ′ ( ξ ) f\prime(\xi) f′(ξ)为函数 f ( x ) f(x) f(x)在点 ξ \xi ξ处的导数。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190711124805896.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Exemhhbw==,size_16,color_FFFFFF,t_70)
从上可知 x 1 x_1 x1时刻的函数值 f ( x 1 ) f(x_1) f(x1)可由 x 0 x_0 x0时刻的函数值 f ( x 0 ) f(x_0) f(x0)和导数值 f ′ ( ξ ) f\prime(\xi) f′(ξ)预测得到。
龙格库塔法
龙格库塔法的核心是求解
f
′
(
ξ
)
f\prime(\xi)
f′(ξ),我们可在
[
x
0
,
x
1
]
[x_0,x_1]
[x0,x1]之间取N个导数值,然后将其进行加权平均,作为
f
′
(
ξ
)
f\prime(\xi)
f′(ξ)的值,如果N=4,即是4阶龙格库塔法RK4。
RK4是通过不断迭代的方式求原函数
f
(
x
)
f(x)
f(x)的值,已知条件如下:
(1)关于原函数的一阶微分方程:
f
′
(
x
)
=
g
(
f
(
x
)
,
x
)
f\prime(x)=g(f(x),x)
f′(x)=g(f(x),x)
(2)在
x
0
x_0
x0时刻函数的初始值
f
(
x
0
)
f(x_0)
f(x0)
求解函数在
x
1
x_1
x1时刻的函数值
f
(
x
1
)
f(x_1)
f(x1),当求解得
f
(
x
1
)
f(x_1)
f(x1)后,我们可将其作为初始条件,根据一阶微分方程求解函数在
x
2
x_2
x2时刻的函数值
f
(
x
2
)
f(x_2)
f(x2),如此不断迭代下去,求得原函数在各个时刻的函数值。
RK4具体过程如下:
由
x
0
x_0
x0时刻的函数值
f
(
x
0
)
f(x_0)
f(x0)预测
x
1
x_1
x1时刻的函数值
f
(
x
1
)
f(x_1)
f(x1),其中
h
=
x
1
−
x
0
h=x_1-x_0
h=x1−x0。
Step1:根据初值
f
(
x
0
)
f(x_0)
f(x0),
x
0
x_0
x0,带入一阶微分方程求的
k
1
k_1
k1:
Step2:根据初值 f ( x 0 ) f(x_0) f(x0), x 0 x_0 x0, k 1 k_1 k1按如下方式求 k 2 k_2 k2:
Step3:根据初值 f ( x 0 ) f(x_0) f(x0), x 0 x_0 x0, k 2 k_2 k2按如下方式求 k 3 k_3 k3:
Step4:根据初值 f ( x 0 ) f(x_0) f(x0), x 0 x_0 x0, k 3 k_3 k3按如下方式求 k 4 k_4 k4:
Step5:对上面的 k 1 , k 2 , k 3 , k 4 k_1,k_2,k_3,k_4 k1,k2,k3,k4进行加权平均,得到函数值的增量,再求 f ( x 1 ) f(x_1) f(x1):
应用1 求解一阶微分方程
使用RK4求解一阶微分方程,设方程为:
采用数学方法求解
为了 验证RK4的正确性,我们可先用数学的方法求解该微分方程的解。
d
f
(
x
)
d
x
=
f
(
x
)
(
x
2
+
1
)
d
f
(
x
)
f
(
x
)
=
(
x
2
+
1
)
d
x
\begin{matrix} \frac{d_f(x)}{d_x}= f(x)(x^2+1) \\ \frac{d_f(x)}{f(x)}= (x^2+1)dx \end{matrix}
dxdf(x)=f(x)(x2+1)f(x)df(x)=(x2+1)dx
两边求积分得:
l
n
(
f
(
x
)
)
+
C
1
=
1
3
∗
x
3
+
x
+
C
2
l
n
(
f
(
x
)
)
=
1
3
∗
x
3
+
x
+
C
3
f
(
x
)
=
C
∗
e
x
p
(
1
3
∗
x
3
+
x
)
\begin{matrix} ln(f(x))+C_1=\frac{1}{3}*x^3+x+C_2\\ ln(f(x))=\frac{1}{3}*x^3+x+C_3\\ f(x)=C*exp(\frac{1}{3}*x^3+x) \end{matrix}
ln(f(x))+C1=31∗x3+x+C2ln(f(x))=31∗x3+x+C3f(x)=C∗exp(31∗x3+x)
因为
x
=
0
,
f
(
0
)
=
1
x=0,f(0)=1
x=0,f(0)=1,故
C
=
1
C=1
C=1,求得:
f
(
x
)
=
e
x
p
(
1
3
∗
x
3
+
x
)
f(x)=exp(\frac{1}{3}*x^3+x)
f(x)=exp(31∗x3+x)
RK4方法求解
具体参考上面Step1–>Step5的实现,下面用Matlab实现RK4求解过程,并将两种方法求得的结果画成曲线,我们发现两条曲线是几乎重合的。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%设一阶微分方程为:y(x)'=y(x)(x^2+1)
%初值:x=0,y(x)=1,y(x)'=1;
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear,close all;
dt=0.01;
x=0:dt:2;
%采用数学方法求解
y=exp(1/3*x.^3+x);
plot(x,y,'-o')
%采用龙格库塔法求解y(x)
h=dt;
N=size(x,2);
init_x = 0.0,init_y = 1;
rkx=[],rkx=[rkx,init_x];
rky=[],rky=[rky,init_y];
for i = 1:N-1
k1=init_y*(init_x*init_x+1);
temp_x = init_x + 0.5*h;
temp_y = init_y + 0.5*h*k1;
k2=temp_y*(temp_x*temp_x+1);
temp_y = init_y + 0.5*h*k2;
k3=temp_y*(temp_x*temp_x+1);
temp_x = init_x + h;
temp_y = init_y + h*k3;
k4=temp_y*(temp_x*temp_x+1);
init_y = init_y + h/6*(k1+2*k2+2*k3+k4);
init_x = init_x + h;
rkx=[rkx,init_x];
rky=[rky,init_y];
end
hold on;
plot(rkx,rky,'-r')
legend('Math method','RK4 method')
set(gca, 'XLim',[0 3]);
曲线如下:
图中蓝色线条为数学方法求得结果,红色曲线为RK4方法求得结果,两条曲线是重合的,证明了RK4方法是有效的。
应用2 求解陀螺仪位姿
设有两个四元数:
a
=
[
a
1
,
a
2
,
a
3
,
a
4
]
,
b
=
[
b
1
,
b
2
,
b
3
,
b
4
]
a=[a_1,a_2,a_3,a_4],b=[b_1,b_2,b_3,b_4]
a=[a1,a2,a3,a4],b=[b1,b2,b3,b4],写成复数形式:
a
=
a
1
+
a
2
i
+
a
3
j
+
a
4
k
,
b
=
b
1
+
b
2
i
+
b
3
j
+
b
4
k
a=a_1+a_2i+a_3j+a_4k,b=b_1+b_2i+b_3j+b_4k
a=a1+a2i+a3j+a4k,b=b1+b2i+b3j+b4k
定义运算:
i
∗
j
=
k
,
j
∗
k
=
i
,
k
∗
i
=
j
,
j
∗
i
=
−
k
,
k
∗
j
=
−
i
,
i
∗
k
=
−
j
i*j=k,j*k=i,k*i=j,j*i=-k,k*j=-i,i*k=-j
i∗j=k,j∗k=i,k∗i=j,j∗i=−k,k∗j=−i,i∗k=−j
i
∗
i
=
j
∗
j
=
k
∗
k
=
−
1
i*i=j*j=k*k=-1
i∗i=j∗j=k∗k=−1
则:
a
∗
b
=
(
a
1
+
a
2
i
+
a
3
j
+
a
4
k
)
∗
(
b
1
+
b
2
i
+
b
3
j
+
b
4
k
)
a*b=(a_1+a_2i+a_3j+a_4k)*(b_1+b_2i+b_3j+b_4k)
a∗b=(a1+a2i+a3j+a4k)∗(b1+b2i+b3j+b4k)
=
(
a
1
∗
b
1
−
a
2
∗
b
2
−
a
3
∗
b
3
−
a
4
∗
b
4
)
+
=(a_1*b_1-a_2*b_2-a_3*b_3-a_4*b_4)+
=(a1∗b1−a2∗b2−a3∗b3−a4∗b4)+
(
a
1
∗
b
2
+
a
2
∗
b
1
+
a
3
∗
b
4
−
a
4
∗
b
3
)
i
+
(a_1*b_2+a_2*b_1+a_3*b_4-a_4*b_3)i+
(a1∗b2+a2∗b1+a3∗b4−a4∗b3)i+
(
a
1
∗
b
3
−
a
2
∗
b
4
+
a
3
∗
b
1
+
a
4
∗
b
2
)
j
+
(a_1*b_3-a_2*b_4+a_3*b_1+a_4*b_2)j+
(a1∗b3−a2∗b4+a3∗b1+a4∗b2)j+
(
a
1
∗
b
4
+
a
2
∗
b
3
−
a
3
∗
b
2
+
a
4
∗
b
1
)
k
(a_1*b_4+a_2*b_3-a_3*b_2+a_4*b_1)k
(a1∗b4+a2∗b3−a3∗b2+a4∗b1)k
再写成矩阵形式:
a
∗
b
=
[
b
1
−
b
2
−
b
3
−
b
4
b
2
b
1
b
4
−
b
3
b
3
−
b
4
b
1
b
2
b
4
b
3
−
b
2
b
1
]
[
a
1
a
2
a
3
a
4
]
a*b= \left[\begin{matrix} b1 & -b_2 & -b_3 & -b_4 \\ b_2 & b_1 & b_4 & -b_3 \\ b_3 & -b_4 & b_1 & b_2 \\ b_4 & b_3 & -b_2 & b_1 \end{matrix} \right] \left[\begin{matrix} a_1\\a_2\\a_3\\a_4 \end{matrix} \right]
a∗b=⎣⎢⎢⎡b1b2b3b4−b2b1−b4b3−b3b4b1−b2−b4−b3b2b1⎦⎥⎥⎤⎣⎢⎢⎡a1a2a3a4⎦⎥⎥⎤
这里陀螺仪的位姿采用四元数表示,对于局部坐标系中一点
(
x
,
y
,
z
)
(x,y,z)
(x,y,z),假设开始时局部坐标系与世界坐标系重合,我们让局部坐标系整体在世界坐标系中绕旋转向量
(
n
x
,
n
y
,
n
z
)
(n_x,n_y,n_z)
(nx,ny,nz)旋转
θ
\theta
θ度,求旋转后该点在世界坐标系中的坐标,该过程可用四元数表示。
定义四元数
q
=
[
c
o
s
(
θ
2
)
,
s
i
n
(
θ
2
)
(
n
x
,
n
y
,
n
z
)
]
,
p
=
[
0
,
x
,
y
,
z
]
q=[cos(\frac{\theta}{2}),sin(\frac{\theta}{2})(n_x,n_y,n_z)],p=[0,x,y,z]
q=[cos(2θ),sin(2θ)(nx,ny,nz)],p=[0,x,y,z],
p
o
p_o
po为旋转后点的坐标,
q
′
q'
q′为四元数
q
q
q的导数,则:
p
o
=
q
p
q
′
p_o=qpq'
po=qpq′
对于运动的陀螺仪来说,位姿
q
q
q是随时间变化的,这里定义成
q
(
t
)
q(t)
q(t),
q
(
t
)
q(t)
q(t)表示
t
t
t时刻陀螺仪坐标系与世界坐标系间的旋转关系,
q
(
t
)
=
[
q
1
,
q
2
,
q
3
,
q
4
]
q(t)=[q_1,q_2,q_3,q_4]
q(t)=[q1,q2,q3,q4]。
设
t
t
t时刻陀螺仪的三轴角速度为
w
x
,
w
y
,
w
z
w_x,w_y,w_z
wx,wy,wz,写成四元数形式为
w
t
=
[
0
,
w
x
,
w
y
,
w
z
]
w_t=[0,w_x,w_y,w_z]
wt=[0,wx,wy,wz],则
t
t
t时刻四元数的导数为:
q
′
(
t
)
=
1
2
q
(
t
)
∗
w
t
=
1
2
[
0
−
w
x
−
w
y
−
w
z
w
x
0
w
z
−
w
y
w
y
−
w
z
0
w
x
w
z
w
y
−
w
x
0
]
[
q
1
q
2
q
3
q
4
]
=
1
2
Ω
[
q
1
q
2
q
3
q
4
]
q'(t)=\frac{1}{2}q(t)*w_t= \frac{1}{2}\left[\begin{matrix} 0 & -w_x & -w_y & -w_z \\ w_x & 0 & w_z & -w_y \\ w_y & -w_z & 0 & w_x \\ w_z & w_y & -w_x & 0 \end{matrix} \right] \left[\begin{matrix} q_1\\q_2\\q_3\\q_4 \end{matrix} \right]=\frac{1}{2}\Omega \left[\begin{matrix} q_1\\q_2\\q_3\\q_4 \end{matrix} \right]
q′(t)=21q(t)∗wt=21⎣⎢⎢⎡0wxwywz−wx0−wzwy−wywz0−wx−wz−wywx0⎦⎥⎥⎤⎣⎢⎢⎡q1q2q3q4⎦⎥⎥⎤=21Ω⎣⎢⎢⎡q1q2q3q4⎦⎥⎥⎤
关于四元数的导数推导,参考这里。
到这里我们有了位姿的一阶微分方程,而位姿的初始值
q
(
0
)
q(0)
q(0)我们可以根据实际情况给定,陀螺仪在每个时刻的三轴角速度都是已知的,故我们可以利用RK4进行求解:
设初始位姿
q
(
0
)
q(0)
q(0)已知,初始三轴角速度为
[
w
x
0
,
w
y
0
,
w
z
0
]
[w_x0,w_y0,w_z0]
[wx0,wy0,wz0],下一时刻三轴角速度为:
[
w
x
1
,
w
y
1
,
w
z
1
]
[w_x1,w_y1,w_z1]
[wx1,wy1,wz1],两时刻时间间隔为:
Δ
t
\Delta t
Δt,且
Δ
x
=
w
x
1
−
w
x
0
,
Δ
y
=
w
y
1
−
w
y
0
,
Δ
z
=
w
z
1
−
w
z
0
\Delta x=w_x1-w_x0,\Delta y=w_y1-w_y0,\Delta z=w_z1-w_z0
Δx=wx1−wx0,Δy=wy1−wy0,Δz=wz1−wz0。
Step1:计算
k
1
k_1
k1,设
Ω
0
=
[
0
−
w
x
−
w
y
−
w
z
w
x
0
w
z
−
w
y
w
y
−
w
z
0
w
x
w
z
w
y
−
w
x
0
]
\Omega_0=\left[\begin{matrix} 0 & -w_x & -w_y & -w_z \\ w_x & 0 & w_z & -w_y \\ w_y & -w_z & 0 & w_x \\ w_z & w_y & -w_x & 0 \end{matrix} \right]
Ω0=⎣⎢⎢⎡0wxwywz−wx0−wzwy−wywz0−wx−wz−wywx0⎦⎥⎥⎤:因为
q
(
0
)
q(0)
q(0)已知,可求出:
k
1
=
1
2
Ω
0
∗
q
(
0
)
∗
Δ
t
k_1=\frac{1}{2}\Omega_0*q(0)*\Delta t
k1=21Ω0∗q(0)∗Δt
Step2:计算
k
2
k_2
k2,令
Ω
m
=
[
0
−
(
w
x
+
0.5
Δ
x
)
−
(
w
y
+
0.5
Δ
y
)
−
(
w
z
+
0.5
Δ
z
)
(
w
x
+
0.5
Δ
x
)
0
(
w
z
+
0.5
Δ
z
)
−
(
w
y
+
0.5
Δ
y
)
(
w
y
+
0.5
Δ
y
)
−
(
w
z
+
0.5
Δ
z
)
0
(
w
x
+
0.5
Δ
x
)
(
w
z
+
0.5
Δ
z
)
(
w
y
+
0.5
Δ
y
)
−
(
w
x
+
0.5
Δ
x
)
0
]
\Omega_m=\left[\begin{matrix} 0 & -(w_x+0.5\Delta x) & -(w_y+0.5\Delta y) & -(w_z+0.5\Delta z) \\ (w_x+0.5\Delta x) & 0 & (w_z+0.5\Delta z) & -(w_y+0.5\Delta y) \\ (w_y+0.5\Delta y) & -(w_z+0.5\Delta z) & 0 & (w_x+0.5\Delta x) \\ (w_z+0.5\Delta z) & (w_y+0.5\Delta y) & -(w_x+0.5\Delta x) & 0 \end{matrix} \right]
Ωm=⎣⎢⎢⎡0(wx+0.5Δx)(wy+0.5Δy)(wz+0.5Δz)−(wx+0.5Δx)0−(wz+0.5Δz)(wy+0.5Δy)−(wy+0.5Δy)(wz+0.5Δz)0−(wx+0.5Δx)−(wz+0.5Δz)−(wy+0.5Δy)(wx+0.5Δx)0⎦⎥⎥⎤,
q
m
=
q
(
0
)
+
0.5
∗
k
1
q_m=q(0)+0.5*k_1
qm=q(0)+0.5∗k1,可求出:
k
2
=
1
2
Ω
m
∗
q
m
∗
Δ
t
k_2=\frac{1}{2}\Omega_m*q_m*\Delta t
k2=21Ωm∗qm∗Δt
Step3:计算
k
3
k_3
k3,令
Ω
m
=
[
0
−
(
w
x
+
0.5
Δ
x
)
−
(
w
y
+
0.5
Δ
y
)
−
(
w
z
+
0.5
Δ
z
)
(
w
x
+
0.5
Δ
x
)
0
(
w
z
+
0.5
Δ
z
)
−
(
w
y
+
0.5
Δ
y
)
(
w
y
+
0.5
Δ
y
)
−
(
w
z
+
0.5
Δ
z
)
0
(
w
x
+
0.5
Δ
x
)
(
w
z
+
0.5
Δ
z
)
(
w
y
+
0.5
Δ
y
)
−
(
w
x
+
0.5
Δ
x
)
0
]
\Omega_m=\left[\begin{matrix} 0 & -(w_x+0.5\Delta x) & -(w_y+0.5\Delta y) & -(w_z+0.5\Delta z) \\ (w_x+0.5\Delta x) & 0 & (w_z+0.5\Delta z) & -(w_y+0.5\Delta y) \\ (w_y+0.5\Delta y) & -(w_z+0.5\Delta z) & 0 & (w_x+0.5\Delta x) \\ (w_z+0.5\Delta z) & (w_y+0.5\Delta y) & -(w_x+0.5\Delta x) & 0 \end{matrix} \right]
Ωm=⎣⎢⎢⎡0(wx+0.5Δx)(wy+0.5Δy)(wz+0.5Δz)−(wx+0.5Δx)0−(wz+0.5Δz)(wy+0.5Δy)−(wy+0.5Δy)(wz+0.5Δz)0−(wx+0.5Δx)−(wz+0.5Δz)−(wy+0.5Δy)(wx+0.5Δx)0⎦⎥⎥⎤,
q
m
=
q
(
0
)
+
0.5
∗
k
2
q_m=q(0)+0.5*k_2
qm=q(0)+0.5∗k2,可求出:
k
3
=
1
2
Ω
m
∗
q
m
∗
Δ
t
k_3=\frac{1}{2}\Omega_m*q_m*\Delta t
k3=21Ωm∗qm∗Δt
Step4:计算
k
4
k_4
k4,令
Ω
m
=
[
0
−
(
w
x
+
Δ
x
)
−
(
w
y
+
Δ
y
)
−
(
w
z
+
Δ
z
)
(
w
x
+
Δ
x
)
0
(
w
z
+
Δ
z
)
−
(
w
y
+
Δ
y
)
(
w
y
+
Δ
y
)
−
(
w
z
+
Δ
z
)
0
(
w
x
+
Δ
x
)
(
w
z
+
Δ
z
)
(
w
y
+
Δ
y
)
−
(
w
x
+
Δ
x
)
0
]
\Omega_m=\left[\begin{matrix} 0 & -(w_x+\Delta x) & -(w_y+\Delta y) & -(w_z+\Delta z) \\ (w_x+\Delta x) & 0 & (w_z+\Delta z) & -(w_y+\Delta y) \\ (w_y+\Delta y) & -(w_z+\Delta z) & 0 & (w_x+\Delta x) \\ (w_z+\Delta z) & (w_y+\Delta y) & -(w_x+\Delta x) & 0 \end{matrix} \right]
Ωm=⎣⎢⎢⎡0(wx+Δx)(wy+Δy)(wz+Δz)−(wx+Δx)0−(wz+Δz)(wy+Δy)−(wy+Δy)(wz+Δz)0−(wx+Δx)−(wz+Δz)−(wy+Δy)(wx+Δx)0⎦⎥⎥⎤,
q
m
=
q
(
0
)
+
k
3
q_m=q(0)+k_3
qm=q(0)+k3,可求出:
k
4
=
1
2
Ω
m
∗
q
m
∗
Δ
t
k_4=\frac{1}{2}\Omega_m*q_m*\Delta t
k4=21Ωm∗qm∗Δt
Step5:对上面的
k
1
,
k
2
,
k
3
,
k
4
k_1,k_2,k_3,k_4
k1,k2,k3,k4进行加权平均,得到位姿的增量,再求
q
(
1
)
q(1)
q(1):
q
(
1
)
=
q
(
0
)
+
1
6
(
k
1
+
2
∗
k
2
+
2
∗
k
3
+
k
4
)
q(1)=q(0)+\frac{1}{6}(k_1+2*k_2+2*k_3+k_4)
q(1)=q(0)+61(k1+2∗k2+2∗k3+k4)
不断重复 S t e p 1 − S t e p 5 Step1-Step5 Step1−Step5,可求出陀螺仪在每一时刻的位姿。