高阶容积卡尔曼滤波——非线性HCKF-Matlab

血红的双手。 提交于 2020-03-06 05:37:59
%HCKF高阶容积卡尔曼滤波在自动驾驶车辆定位中的应用
%参考文献:
%        The High-Degree Cubature Kalman Filter (Bin Jia, Ming Xin, and Yang Cheng)
%        Unscented Kalman Filter Tutorial (Gabriel A. Terejanu )
%        基于正交变换的五阶容积卡尔曼滤波导航算法 (何康辉,董朝阳 )
%        EKF、UKF和CKF的滤波性能对比研究 (常宇健,赵辰)
%        组合导航原理与应用 (西北工业大学出版社)
%        卡尔曼滤波与Matlab仿真 (北京航空航天大学出版社)
% 本例子使用线性状态模型,因此加速度变成了干扰项
% Lidar传感器测量模型为线性模型,Radar传感器测模型为非线性模型
% 在Radar传感器中使用滤波算然为 HCKF,在Lidar传感器中使用滤波算然为 KF
clear;
clc;
tic;      %计时
dt = 0.1; %步长

%分配空间
Radar_measurement = [];
Radar_measurement_p = [];
Lidar_measurement = [];
HCKF_estimation = [];
hckf = [];  % 结构体

%读取Radar_Lidar_Data2.csv文件保存到矩阵Data
Data = csvread('Radar_Lidar_Data1.csv',1,1);%起点为第2行第2612组数据
%将Data矩阵数据保存到data.csv文件中
csvwrite('Data.csv',Data);

%初始化状态,x是4维向量
if (Data(1,1) == 1)  
    x = [Data(1,2); Data(1,3); 0; 0];          
else
    x = [   
            Data(1,2)*cos(Data(1,3)); 
            Data(1,2)*sin(Data(1,3)); 
            Data(1,4)*cos(Data(1,3)); 
            Data(1,4)*sin(Data(1,3))
         ];  
end

%初始化状态协方差矩阵
P = diag([1,1,1000,1000]);
 
%状态转移矩阵,线性
F = [[1, 0, dt, 0];
     [0, 1, 0, dt];
     [0, 0, 1, 0];
     [0, 0, 0, 1]];

 %系统误差协方差矩阵
Q = [[(dt^2)/4,0,(dt^3)/2,0];
     [0,(dt^2)/4,0,(dt^3)/2];
     [(dt^3/2),0,(dt^2),0];
     [0,(dt^3)/2,0,(dt^2)]];
 
%Lidar传感器观测矩阵,线性
H_L = [[1, 0, 0, 0];
       [0, 1, 0, 0]];

%雷达传感器测量误差协方差矩阵
R_r = diag([0.09,0.005,0.09]);

%激光雷达传感器测量误差协方差矩阵
R_L = diag([0.0025, 0.0025]);

%4阶单位矩阵
I = eye(4);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% HCKF参数设置 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
L = numel(x);                                                                %状态维数  4x1 
W = [2/(2+L),1/(L+2)^2 * ones(1,2*L*(L-1)),(4-L)/(2*(L+2)^2) * ones(1,2*L)]; %容积点权重 1x33
lamda = sqrt(L + 2);
S1 = 1/sqrt(2) * [
                    [1,1,1,0,0,0];
                    [1,0,0,1,1,0];
                    [0,1,0,1,0,1];
                    [0,0,1,0,1,1];
                  ];
S2 = 1/sqrt(2) * [
                    [1,1,1,0,0,0];
                    [-1,0,0,1,1,0];
                    [0,-1,0,-1,0,1];
                    [0,0,-1,0,-1,-1];
                 ];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 开始迭代 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for n = 1:length(Data) 
    
    %Radar传感器
    %非线性
    if (Data(n,1) == 2)
        
        %Radar测量数据
        z = transpose(Data(n,2:4));
        z_p = [ z(1) * cos(z(2));z(1) * sin(z(2));z(3) * cos(z(2));z(3) * sin(z(2))];
        
        %HCKF 算法核心部分
        %======================================================================%        
        %1.采样:由x0,P0产生容积点
        gama1 = lamda * S1;              % 4x6
        gama2 = lamda * S2;              % 4x6
        A11 = chol(P) * gama1;           % 4x6
        A12 = chol(P) * gama2;           % 4x6
        Y1 = x(:,ones(1,L+2));           % 4x6
        X11_cuba = [Y1 + A11,Y1 - A11];  % 4x12
        X12_cuba = [Y1 + A12,Y1 - A12];  % 4x12
        X13_cuba = [];
        for i = 1:4  
            gama3 = lamda * I(:,i);                         % 4x1 
            A13 = chol(P) * gama3;                          % 4x1                                                    
            X13_cuba = [X13_cuba,x + A13,x - A13];          % 4x8
        end
        X1_cuba = [x,X11_cuba,X12_cuba,X13_cuba];           % 4x33
          
        %2.容积点经过线性映射
        cols = size(X1_cuba,2);               % 返回矩阵列数
        x1_mean = zeros(L,1);                 % 加权均值:经过线性映射后均值
        X1_ckf = zeros(L,cols);               % 容积点经过线性映射
        for k = 1 : cols  
            X1_ckf(:,k) = F * X1_cuba(:,k);           % 容积点经过线性映射
            x1_mean = x1_mean + W(k) * X1_ckf(:,k);   % 加权均值:经过线性映射后均值 
        end  
        error1 = X1_ckf - x1_mean(:,ones(1,cols));             % 经过线性映射后偏差 4x33
        P1_cov = error1 * diag(W) * transpose(error1) + Q;     % 加权方差:经过线性映射后方差 4x4
        
        %3.采样:由x1_mean,P1_cov产生容积点
        gama1 = lamda * S1;              % 4x6
        gama2 = lamda * S2;              % 4x6
        A21 = chol(P1_cov) * gama1;      % 4x6
        A22 = chol(P1_cov) * gama2;      % 4x6
        Y2 = x1_mean(:,ones(1,L+2));     % 4x6
        X21_cuba = [Y2 + A21,Y2 - A21];  % 4x12
        X22_cuba = [Y2 + A22,Y2 - A22];  % 4x12
        X23_cuba = [];
        for i = 1:4  
            gama3 = lamda * I(:,i);                              % 4x1 
            A23 = chol(P1_cov) * gama3;                          % 4x1                                                    
            X23_cuba = [X23_cuba,x1_mean + A23,x1_mean - A23];   % 4x8
        end
        X2_cuba = [x,X21_cuba,X22_cuba,X23_cuba];                % 4x33
        
        %4.非线性测量方程 
        h = @(x)[sqrt(x(1)^2 + x(2)^2);
                 atan(x(2)/x(1));
                 (x(1)*x(3) + x(2)*x(4)) / sqrt(x(1)^2 + x(2)^2)];
        
        %5.容积点经过非线性映射
        x2_mean = zeros(L-1,1);                         % 加权均值:经过非线性映射后均值 3x1
        X2_ckf = zeros(L-1,cols);                       % 容积点经过非线性映射 3x33
        for k = 1 : cols  
            X2_ckf(:,k) = h(X2_cuba(:,k));              % 容积点经过非线性映射 3x33
            x2_mean= x2_mean + W(k) * X2_ckf(:,k);      % 加权均值:经过非线性映射后均值 3x1
        end  
        error2 = X2_ckf - x2_mean(:,ones(1,cols));              % 经过非线性映射后偏差 3x33
        P2_cov = error2 * diag(W) * transpose(error2) + R_r;    % 加权方差:经过非线性映射后方差 3x3
        
        %6.量测更新
        P3_cov = error1 * diag(W) * transpose(error2);   % 方差cross 4x3
        K = P3_cov / P2_cov;                             % 卡尔曼增益 4x3
        x = x1_mean + K * (z - x2_mean);                 % 状态均值更新
        P = P1_cov - K * P2_cov * transpose(K);          % 状态方差更新
        
        %7.保存数据
        HCKF_estimation = [HCKF_estimation;transpose(x)];
        Radar_measurement = [Radar_measurement; transpose(z)];
        Radar_measurement_p = [Radar_measurement_p;transpose(z_p)];
    %======================================================================%
    
    %Lidar传感器
    %线性
    else
        %KF 算法核心部分
        %======================================================================% 
        %1.预测更新状态、状态协方差阵
        x = F * x;
        P = F * P * transpose(F) + Q;

        %2.Lidar测量数据
        z = transpose(Data(n,2:3));
        
        %3.测量更新
        %更新卡尔曼增益矩阵
        y = z - (H_L * x);
        S = H_L * P * transpose(H_L) + R_L;
        K = P * transpose(H_L) / S;
        x = x + (K * y);          % 更新状态
        P = (I - (K * H_L)) * P;  % 更新状态协方差阵
        
        %4.保存状态值
        HCKF_estimation = [HCKF_estimation;transpose(x)];
        Lidar_measurement = [Lidar_measurement; transpose(z)];
        %======================================================================% 
    end     
    
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 数据可视化%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
figure(1);
hold on;
plot(Data(:,5),Data(:,6),'k');                                                %真实状态
scatter(HCKF_estimation(:,1),HCKF_estimation(:,2),5,'filled','r');            %估计状态
scatter(Lidar_measurement(:,1),Lidar_measurement(:,2),5,'filled','blue');     %Lidar传感器测量
scatter(Radar_measurement_p(:,1),Radar_measurement_p(:,2),5,'filled','g');    %Radar传感器测量
legend('truth','HCKF Path result','Lidar Measurement','Radar Measurement');    %标注
title('位置估计');
axis square;
grid on;
hold off;

%位置x误差
figure(2);
hold on;
HCKF_x_error = Data(1:2:1223,5) - HCKF_estimation(1:2:1223,1);  %位置x误差
plot(1:612,HCKF_x_error);
plot(1:612,Data(1:2:1223,5) - Radar_measurement_p(:,1));
legend('HCKFerror','Radarerror');       
title('位置x误差');
grid on;
hold off;

%位置y误差
figure(3);
hold on;
HCKF_y_error = Data(1:2:1223,6) - HCKF_estimation(1:2:1223,2);  %位置y误差
plot(1:612,HCKF_y_error);
plot(1:612,Data(1:2:1223,6) - Radar_measurement_p(:,2));
legend('HCKFerror','Radarerror');       
title('位置y误差');
grid on
hold off;

%速度x误差
figure(4);
hold on;
HCKF_vx_error = Data(1:2:1223,7) - HCKF_estimation(1:2:1223,3);  %速度x误差
plot(1:612,HCKF_vx_error);
plot(1:612,Data(1:2:1223,7) - Radar_measurement_p(:,3));
legend('HCKFerror','Radarerror');       
title('速度x误差');
grid on
hold off;

%速度y误差
figure(5);
hold on;
HCKF_vy_error = Data(1:2:1223,8) - HCKF_estimation(1:2:1223,4);  %速度y误差
plot(1:612,HCKF_vy_error);
plot(1:612,Data(1:2:1223,8) - Radar_measurement_p(:,4));
legend('HCKFerror','Radarerror');       
title('速度y误差');
grid on
hold off;

%将数据保存到 HCKF_error.csv 文件中,用于软法比较
HCKF_error = [HCKF_x_error,HCKF_y_error,HCKF_vx_error,HCKF_vy_error];
csvwrite('HCKF_error.csv',HCKF_error);
%保存到结构体
hckf.estimation = HCKF_estimation;
hckf.error      = HCKF_error;
hckf.measurement_R = Radar_measurement_p;
hckf.measurement_L = Lidar_measurement;
%结束计时
toc;

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!