% Gravity vector g_t=[0 0 simdata.g]'; % f_t 是旋转矩阵 x acc 向量,得到瞬时加速度量在 navigation coordinat 坐标系下的表示 f_t=q2dcm(q)*u(1:3); % Subtract (add) the gravity, to obtain accelerations in navigation % coordinat system. acc_t=f_t+g_t; % State space model matrices A=eye(6); A(1,4)=Ts; A(2,5)=Ts; A(3,6)=Ts; B=[(Ts^2)/2*eye(3);Ts*eye(3)]; % Update the position and velocity estimates. y(1:6)=A*x(1:6)+B*acc_t;
% Convert quaternion to a rotation matrix Rb2t=q2dcm(q);
% Transform measured force to force in % the navigation coordinate system. f_t=Rb2t*u(1:3);
% Create a ske symmetric matrix of the specific fore vector St=[0 -f_t(3) f_t(2); f_t(3) 0 -f_t(1); -f_t(2) f_t(1) 0];
% Zero matrix O=zeros(3);
% Identity matrix I=eye(3); ... Fc=[O I O; O O St; O O O]; % Noise gain matrix Gc=[O O; Rb2t O; O -Rb2t];
% Approximation of the discret time state transition matrices F=eye(size(Fc))+simdata.Ts*Fc; G=simdata.Ts*Gc;
为了更清楚的看到结果,这里把这个转移矩阵写为公式形式:
F=⎣⎢⎡IOOOIOOSt∗dtI⎦⎥⎤
我们看到这里实现上有一点差异就是这个状态转移矩阵其实是不包括四元数 q 的更新项的,这里这样做其实是很合理的,在我们当前这个系统中四元数的更新是不需要进行卡尔曼滤波的,其实在实现上我们也看到这里并不是通过整个状态转移矩阵直接更新所有状态的而是分拆将每个状态进行更新,我们主要是对位置和速度这两个量进行滤波,实际上也也是只对这两个状态量进行滤波,因此这里状态转移矩阵在跟新前先更新了四元数 q 然后四元数的更新q=qk−1就是上面代码中的形式。
在标准卡尔曼滤波中还有一个是测量转移矩阵,由于我们的系统模型中系统状态量是位置 p 和速度 v 这两个量都是不可测量的,只有速度 v 是间接通过 ZUPT 进行估计的因此测量转移矩阵为:
H=[OIO]
这里其实并不需要进行什么运算在因此在实现上就省略了。
接着是前验状态协方差矩阵的更新:
P^=F∗P^∗F′+G∗Q∗G′(2)
其中 G 为过程噪声转移矩阵,Q 为过程噪声,原始噪声就是加速度跟陀螺仪的噪声,Q 初值的选取是按照加速度和陀螺仪的噪声大小来选取的,系统中选取 0.1 个加速度和 0.1 度每秒作为初始系统误差值。
H 为单位矩阵 R 为测量误差矩阵都是固定矩阵,分子和分母分别代表了对预测和观测的信任度。
现在有了卡尔曼系数 K 就可以按照对预测和观测的信任度来修正误差了,对于速度误差的修正比较好理解,当前通过陀螺仪积分得到的速度是不为 0 的,而我们通过 ZUPT 检测出来的速度却为 0,我们根据卡尔曼系数来衡量两个数据的可信任程度,然后将 K 作用到现在的积分速度上:
K=(P*H')/(H*P*H'+R); z=-x_h(4:6,k); % Estimation of the perturbations in the estimated navigation % states dx=K*z; % Correct the navigation state using the estimated perturbations. % (Subfunction located further down in the file.) % 使用误差估计进行校正姿态,x_h(:,k) 校正后的姿态,quat 校正后四元数,dx 是误差评估 [x_h(:,k) quat]=comp_internal_states(x_h(:,k),dx,quat); { % Correct the state vector x_out=x_in+dx;
% Correct the rotation matrics % dx[7:9] 分量代表了旋转误差估计,OMEGA 则构造了旋转误差转移矩阵,对旋转矩阵 R 进行校正 epsilon=dx(7:9); OMEGA=[0 -epsilon(3) epsilon(2); epsilon(3) 0 -epsilon(1); -epsilon(2) epsilon(1) 0]; R=(eye(3)-OMEGA)*R; } % Update the filter state covariance matrix P. P=(Id-K*H)*P;