惯性导航学习过程记录(2d导航+EKF)

本文详细介绍了使用EKF(扩展卡尔曼滤波)在2D导航中的应用,包括运动方程、状态方程和观测模型的构建,以及过程噪声和量测噪声的处理。通过比较不同GPS噪声和过程噪声矩阵Q对导航结果的影响,展示了GPS精度对EKF估计精度的影响。
摘要由CSDN通过智能技术生成

1.一个2d导航的EKF案例:

        (个人理解)例如,有一个小车,我想知道它的位置、速度、航向角的信息,车身上有编码器和陀螺仪,我能从中得到来自于这个传感器的速度和航向速率信息,但是传感器误差大,利用这两个信息根据运动方程计算出的位置信息不准;另一种手段是利用GPS直接获取位置信息,但GPS也不一定准。因此可以利用卡尔曼滤波的方法,综合考虑两种传感器的可信度,得到一个综合的状态估计结果。

        首先,我想获取位置、速度、航向信息,因此把他们设为状态向量X, x =  [ 位置x,位置y,   航向角yaw, 速度v,], 其次把从车身上获取到的编码器和陀螺仪信息设为控制向量u,u =  [ 速度v  ,航向速率yawrate] ,GPS只能观测到位置信息,因此将位置设为观测向量Z


 1.1 列运动方程

例如运动状态为匀速运动但会持续偏航,则下一时刻速度不变,下一时刻航向角受偏航率影响,位置同时受速度和偏航率影响,则运动方程如下:

下一时刻: pos_x  =  pos_x + cos(yaw)*v*dt

                   pos_y  =  pos_y + sin(yaw)*v*dt

                   yaw     =  yaw + yawrate*dt

                    v       =   v       匀速,速度不变


1.2 列状态方程

根据上述运动方程,列出状态方程,即改写成x = F*x + B*u的形式.


1.3  列观测模型

这个很简单,状态向量中就前两个能观测到。

 上面是真实位置,但是GPS会有观测误差,因此在仿真时,制作GPS的观测值需要在真实轨迹的基础上,把GPS的噪声加进去。

% 添加测量噪声
GPS_NOISE = diag([0.7, 0.7]) ^(2);
% 观测模型z = H * x;
z = observation_model(x_gt) + GPS_NOISE* randn(2,1);

 同理,编码器和陀螺仪也有噪声,因此仿真时,利用状态方程进行航迹推算时,输入的u需要额外考虑噪声。

% 添加传感器噪声
global INPUT_NOISE;
u_dr = u + INPUT_NOISE * randn(2,1);

% 生成真实DR轨迹
x_dr = motion_model(x_dr, u_dr, dt);

1.4 EKF滤波环节

EKF 需要用到的输入: 传感器测量值,GPS观测值,过程噪声矩阵,量测噪声矩阵

过程噪声矩阵,量测噪声矩阵的值自己设置,我会在后面比较该值设置对最终导航结果的影响。

%过程噪声
Q = diag([  %预测状态协方差
          0.1  % x轴上的位置方差
          0.1  % y轴上位置方差
         deg2rad(1.0)  % 航向角方差
         1.0 % 速度方差
         ])^(2);

%量测噪声
R = diag([
           3 % GPS X量测噪声
           3 % GPS Y量测噪声
            ])^(2);

EKF就是更新和预测两个环节,循环往复,该部分代码照抄就可以,原理参考博主扩展卡尔曼滤波(EKF)理论讲解与实例(matlab、python和C++代码)_ekf卡尔曼滤波实例_O_MMMM_O的博客-CSDN博客

比较难的地方是里面需要雅克比矩阵J,这个需要根据状态方程去推导,这里记录一下中JA推导过程:

计算原则是下面这样:

 自己的运动方程:

pos_x  =  pos_x + cos(yaw)*v*dt

pos_y  =  pos_y + sin(yaw)*v*dt

yaw     =  yaw + yawrate*dt

 v       =   v 

 把自己的运动方程套进计算原则中:

第一行: pos_x + cos(yaw)*v*dt     逐个对pos_x ,pos_y,yaw, v  求导

得到: [1      0    -dt*v*sin(yaw),     dt*cos(yaw)]

第二行: pos_y + sin(yaw)*v*dt       逐个对pos_x ,pos_y,yaw, v  求导

得到:[ 0      1     dt*v*cos(yaw)     dt*sin(yaw)]   

以此类推,得到所求的J:

J = [1      0    -dt*v*sin(yaw),     dt*cos(yaw); 
       0      1     dt*v*cos(yaw)     dt*sin(yaw); 
       0      0         1                           0; 
       0      0         0                           1];

 EKF 需要计算两个两个雅克比矩阵,另一个计算方法一样。


2. 完整程序

clear;
clc
close all;

%% EKF 2D 定位
% 参考: https://pythonrobotics.readthedocs.io/en/latest/modules/localization.html#histogram-filter-localization

%过程噪声
Q = diag([  %预测状态协方差
         0.1  % x轴上的位置方差
          0.1  % y轴上位置方差
         deg2rad(1.0)  % 航向角方差
         1.0 % 速度方差
         ])^(2);

%量测噪声
R = diag([
           3 % GPS X量测噪声
           3 % GPS Y量测噪声
            ])^(2);

%  输入噪声参数(速度传感器(编码器) 和 角速度传感器(陀螺仪))
global  INPUT_NOISE
INPUT_NOISE  = diag([1.0, deg2rad(30.0)]) ^(2);

%GPS 噪声参数
global GPS_NOISE;
GPS_NOISE = diag([0.7, 0.7]) ^(2);

dt = 0.1;     %积分间隔
N = 400;

%% 初始值
x_est = zeros(4, 1);     %卡尔曼估计值
x_gt = zeros(4, 1);       %真实值
P = eye(4);                 %过程噪声矩阵
x_dr = zeros(4,1);       %航迹推算值

for i = 1:N
    
    % 生成理想传感器数据 u = [v yawrate]' 速度和偏航率
    u = calc_input(); 
    
    %生成真实轨迹 x_gt, 带有噪声的观测值ud,带有噪声的生成轨迹
    [x_gt, z, x_dr, ud] = observation(x_gt, x_dr, u, dt); 
    
    [x_est , P] = ekf_estimation(x_est, P, Q, R, z, ud, dt); %EKF滤波
    
    % 记录历史数据
    hx_gt(i,:) = x_gt;
    hz(i,:) = z;
    hx_dr(i,:) = x_dr;
    hx_est(i,:) = x_est;
    hPtrace(i,:) = trace(P);
end

%% plot结果
figure;
hold on;
plot(hx_gt(:,1), hx_gt(:,2));
plot(hx_dr(:,1), hx_dr(:,2));
plot(hz(:,1), hz(:,2),'.');
plot(hx_est(:,1), hx_est(:,2));
legend("真实值(GT)", "航迹推算(DR)", "观测值(GPS)", "EKF滤波");

figure;
hold on;
plot(1:N, hx_gt(:,3));
plot(1:N, hx_dr(:,3));
plot(1:N, hx_est(:,3));
title("航向角");
legend("真实值(GT)", "航迹推算(DR)" , "EKF滤波");

figure;
hold on;
plot(1:N, hx_gt(:,4));
plot(1:N, hx_dr(:,4),'g');
plot(1:N, hx_est(:,4),'b.');
title("速度");
legend("真实值(GT)", "航迹推算(DR)" , "EKF滤波");


figure;
plot(1:N, hPtrace);
title("P迹(系统稳定度)");


%计算误差
pos_diff = hx_est(:,1:2) - hx_gt(:,1:2);
err = sum( sum(abs(pos_diff).^2,2).^(1/2));
fprintf("滤波位置与真实值误差:%f m\n", err);


%% 子函数

% EKF滤波过程
function  [x_est , P]  = ekf_estimation(x_est, P, Q, R, z, u, dt)

% 预测状态
x_est = motion_model(x_est, u, dt);

%误差矩阵预测
JF = jacob_f(x_est, u, dt);   % 求状态过程,对状态方程求雅克比矩阵
P = JF*P*JF' + Q;              

% 更新
JH = jacob_h();
z_pred = observation_model(x_est);


% 计算卡尔曼增益
S = JH * P * JH' + R;
K = P * JH' * S^(-1);

% 通过测量更新估计
x_est = x_est + K*( z - z_pred);

% 更新误差方差
P = (eye(length(x_est)) - K*JH) * P;
end


%观测模型
function z =  observation_model(x)
H = [1, 0, 0, 0;  0, 1, 0, 0];
z = H * x;
end

%观测过程Jacob
function J= jacob_h()
% 观测模型的Jacobian
J= [1 0 0 0; 0 1 0 0];

end

%求状态过程Jacob
function J = jacob_f(x, u, dt)
yaw = x(3);
v = x(4);
J = [1      0    -dt*v*sin(yaw),     dt*cos(yaw); 
       0      1     dt*v*cos(yaw)     dt*sin(yaw); 
       0      0         1                           0; 
       0      0         0                           1];

end

%生成 真实值,DR值和观测值
function  [x_gt, z, x_dr, u_dr] = observation(x_gt, x_dr, u, dt)

% 运动模型  x = F*x + B*u;
x_gt =  motion_model(x_gt, u, dt);

% 添加测量噪声
global GPS_NOISE;
% 观测模型z = H * x;
z = observation_model(x_gt) + GPS_NOISE* randn(2,1);

% 添加传感器噪声
global INPUT_NOISE;
u_dr = u + INPUT_NOISE * randn(2,1);

% 生成真实DR轨迹
x_dr = motion_model(x_dr, u_dr, dt);

end

% 运动模型
function x =  motion_model(x, u, dt)
F =  [
    1, 0, 0, 0;
    0, 1, 0, 0;
    0, 0, 1, 0;
    0, 0, 0, 0];

yaw = x(3);
B = [dt*cos(yaw) 0; dt*sin(yaw) 0; 0 dt; 1 0];
x = F*x + B*u;
end

%生成传感器输入
function u =  calc_input()

v = 1.0;  % [m/s]
yawrate = 0.1; % [rad/s]

u = [v yawrate]';
end

运行结果:

位置估计:

 航向角估计:

速度估计:

系统稳定度(过程噪声矩阵):


3.一些参数比较

3.1 GPS噪声

gps定位误差0.1米

gps定位误差1米

gps定位误差2米

结论:GPS精度越高,EKF的估计值越准确,相反精度越低,越会误导EKF

3.2  Q阵

3.2.1 修改位置方差

Q = diag([  %预测状态协方差
          0.1  % x轴上的位置方差
          0.1  % y轴上位置方差
         deg2rad(1.0)  % 航向角方差
         1.0 % 速度方差
         ])^(2);

 %过程噪声
Q = diag([  %预测状态协方差
          3  % x轴上的位置方差
          3  % y轴上位置方差
         deg2rad(1.0)  % 航向角方差
         1.0 % 速度方差
         ])^(2);

 结论:修改Q阵的前两项,值越大EKF的预测轨迹越贴近GPS,预测轨迹抖动越大。

其它测试待续,直观看不出来有啥影响,Q阵R阵调节的特别大,也只是抖动,也不太影响准确度,以后有机会再试试。。。。未完待续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值