传递对准MATLAB仿真程序

传递对准(Transfer Alignment)MATLAB仿真程序,包含卡尔曼滤波模型建立、运动轨迹生成和性能分析。

传递对准完整仿真程序

1. 主程序框架

matlab 复制代码
%% 传递对准仿真主程序 - 基于速度+姿态匹配的卡尔曼滤波
clear; close all; clc;
fprintf('========== 传递对准仿真程序 ==========\n');

%% 1. 仿真参数设置
dt = 0.01;                   % 采样时间 (s)
T_total = 60;                % 总仿真时间 (s)
t = 0:dt:T_total;            % 时间序列
N = length(t);               % 数据点数

% 主惯导(Master INS) - 高精度
master.pos = zeros(3, N);    % 位置 (m)
master.vel = zeros(3, N);    % 速度 (m/s)
master.att = zeros(3, N);    % 姿态: 滚转/俯仰/航向 (rad)

% 子惯导(Slave INS) - 低成本
slave.pos = zeros(3, N);
slave.vel = zeros(3, N);
slave.att = zeros(3, N);

%% 2. 生成运动轨迹(载体机动)
fprintf('生成载体运动轨迹...\n');
[motion_profile, maneuver_type] = generate_maneuver_trajectory(t, dt);

%% 3. 传递对准卡尔曼滤波器初始化
fprintf('初始化传递对准卡尔曼滤波器...\n');
[kf_params, state_names] = init_transfer_alignment_kf(dt);

%% 4. 主循环:仿真传递对准过程
fprintf('开始传递对准仿真...\n');
estimation_history = struct();
true_errors = struct();

for k = 1:N
    % 更新主惯导状态(含真实轨迹)
    [master, slave, true_err] = update_ins_states(master, slave, motion_profile, k, dt);
    true_errors = save_true_errors(true_errors, true_err, k);
    
    % 生成量测信息(速度/姿态匹配)
    measurements = generate_measurements(master, slave, k, kf_params);
    
    % 卡尔曼滤波:预测 + 更新
    if k > 1
        [kf_params, est] = kf_transfer_alignment(kf_params, measurements, k);
        estimation_history = save_estimation(estimation_history, est, k);
    end
    
    % 反馈校正(可选:开环或闭环)
    if mod(k, 100) == 0 && k > 10  % 每1秒反馈一次
        slave = apply_correction(slave, kf_params, k);
    end
    
    % 显示进度
    if mod(k, round(N/10)) == 0
        fprintf('进度: %.0f%%\n', k/N*100);
    end
end

%% 5. 结果分析与可视化
fprintf('\n========== 仿真结果分析 ==========\n');
analyze_and_plot_results(t, master, slave, true_errors, estimation_history, ...
                         kf_params, state_names, maneuver_type);

fprintf('传递对准仿真完成!\n');

2. 卡尔曼滤波模型核心实现

matlab 复制代码
function [kf_params, state_names] = init_transfer_alignment_kf(dt)
% 初始化传递对准卡尔曼滤波器参数
% 状态向量: [姿态误差(3), 速度误差(3), 位置误差(3), 陀螺零偏(3), 加表零偏(3), 杆臂误差(3), 安装失准角(3)]
% 共21个状态量

    n_states = 21;
    n_meas = 6;  % 速度差(3) + 姿态差(3)
    
    % 状态名称(用于绘图)
    state_names = {
        '滚转误差 (rad)', '俯仰误差 (rad)', '航向误差 (rad)', ...
        '东向速度误差 (m/s)', '北向速度误差 (m/s)', '天向速度误差 (m/s)', ...
        '纬度误差 (rad)', '经度误差 (rad)', '高度误差 (m)', ...
        '陀螺X零偏 (rad/s)', '陀螺Y零偏 (rad/s)', '陀螺Z零偏 (rad/s)', ...
        '加表X零偏 (m/s²)', '加表Y零偏 (m/s²)', '加表Z零偏 (m/s²)', ...
        '杆臂X (m)', '杆臂Y (m)', '杆臂Z (m)', ...
        '安装X角 (rad)', '安装Y角 (rad)', '安装Z角 (rad)'
    };
    
    % 初始状态估计
    kf_params.x_est = zeros(n_states, 1);
    kf_params.x_est(19:21) = deg2rad([0.5; 0.5; 1.0]);  % 安装失准角初值
    
    % 初始协方差矩阵
    kf_params.P = diag([
        deg2rad([0.5, 0.5, 1.0]).^2,    % 姿态误差 (rad^2)
        [0.1, 0.1, 0.1].^2,             % 速度误差 (m^2/s^2)
        deg2rad([0.0001, 0.0001]).^2, 0.1^2,  % 位置误差
        deg2rad([0.1, 0.1, 0.1]/3600).^2,     % 陀螺零偏 (rad^2/s^2)
        [1e-4, 1e-4, 1e-4].^2,          % 加表零偏 (m^2/s^4)
        [0.1, 0.1, 0.1].^2,             % 杆臂误差 (m^2)
        deg2rad([0.5, 0.5, 1.0]).^2     % 安装失准角 (rad^2)
    ]);
    
    % 过程噪声协方差矩阵 Q
    gyro_noise = deg2rad(0.1/3600);     % 陀螺角随机游走
    accel_noise = 1e-5;                 % 加表速度随机游走
    kf_params.Q = diag([
        zeros(1, 9),                    % 误差状态
        gyro_noise^2 * [1, 1, 1],       % 陀螺零偏驱动噪声
        accel_noise^2 * [1, 1, 1],      % 加表零偏驱动噪声
        zeros(1, 6)                     % 杆臂和安装角(假设常数)
    ]) * dt;
    
    % 量测噪声协方差矩阵 R
    vel_meas_noise = 0.01;              % 速度量测噪声 (m/s)
    att_meas_noise = deg2rad(0.1);      % 姿态量测噪声 (rad)
    kf_params.R = diag([vel_meas_noise^2 * [1, 1, 1], ...
                        att_meas_noise^2 * [1, 1, 1]]);
    
    % 系统矩阵 F (连续时间)
    kf_params.F_cont = zeros(n_states);
    % 姿态误差方程:φ_dot = -ω×φ + δω
    kf_params.F_cont(1:3, 1:3) = -skew_symmetric([0; 0; 7.292115e-5]); % 地球自转
    kf_params.F_cont(1:3, 10:12) = eye(3);  % 陀螺零偏
    
    % 速度误差方程:δv_dot = -f×φ + C_b^n δf + ...
    kf_params.F_cont(4:6, 1:3) = -skew_symmetric([0; 0; 9.8]);  % 重力/比力
    kf_params.F_cont(4:6, 13:15) = eye(3);  % 加表零偏
    
    % 位置误差方程
    kf_params.F_cont(7:9, 4:6) = eye(3);
    
    % 转换为离散时间系统矩阵
    kf_params.F = eye(n_states) + kf_params.F_cont * dt;
    
    % 控制输入矩阵(杆臂效应)
    kf_params.B = zeros(n_states, 3);
    kf_params.B(4:6, 1:3) = eye(3);  % 杆臂加速度到速度误差
    
    % 量测矩阵 H
    kf_params.H = zeros(n_meas, n_states);
    kf_params.H(1:3, 4:6) = eye(3);   % 速度误差观测
    kf_params.H(4:6, 1:3) = eye(3);   % 姿态误差观测
    kf_params.H(4:6, 19:21) = eye(3); % 安装失准角观测
    
    % 存储历史记录
    kf_params.history.state = zeros(n_states, N);
    kf_params.history.cov = zeros(n_states, N);
end

function [kf, est] = kf_transfer_alignment(kf, z, k)
% 传递对准卡尔曼滤波主函数(预测 + 更新)
    
    % ---------- 预测步骤 ----------
    % 状态预测
    kf.x_pred = kf.F * kf.x_est;
    
    % 协方差预测
    kf.P_pred = kf.F * kf.P * kf.F' + kf.Q;
    
    % ---------- 更新步骤 ----------
    % 计算卡尔曼增益
    S = kf.H * kf.P_pred * kf.H' + kf.R;
    K = kf.P_pred * kf.H' / S;
    
    % 计算新息(量测残差)
    innovation = z - kf.H * kf.x_pred;
    
    % 状态更新
    kf.x_est = kf.x_pred + K * innovation;
    
    % 协方差更新 (Joseph形式,数值更稳定)
    I = eye(size(kf.P));
    kf.P = (I - K * kf.H) * kf.P_pred * (I - K * kf.H)' + K * kf.R * K';
    
    % 存储结果
    kf.history.state(:, k) = kf.x_est;
    kf.history.cov(:, k) = diag(kf.P);
    
    % 返回估计值
    est.x_est = kf.x_est;
    est.innovation = innovation;
    est.K = K;
end

3. 运动轨迹生成函数

matlab 复制代码
function [profile, maneuver_type] = generate_maneuver_trajectory(t, dt)
% 生成载体机动轨迹(用于激励传递对准可观性)
    
    N = length(t);
    profile = struct();
    
    % 选择机动类型
    maneuver_list = {'摇摆', 'S形转弯', '加速度机动', '复合机动'};
    maneuver_type = maneuver_list{3};  % 可修改选择
    
    fprintf('机动类型: %s\n', maneuver_type);
    
    % 初始化运动参数
    profile.accel = zeros(3, N);  % 加速度 (m/s^2)
    profile.omega = zeros(3, N);  % 角速度 (rad/s)
    profile.pos = zeros(3, N);    % 位置 (m)
    profile.vel = zeros(3, N);    % 速度 (m/s)
    profile.att = zeros(3, N);    % 姿态 (rad)
    
    % 基础运动(匀速直线)
    vel_const = 20;  % 20 m/s
    profile.vel(1, :) = vel_const;
    
    switch maneuver_type
        case '摇摆'
            % 正弦摇摆运动(激励俯仰和滚转)
            amplitude = deg2rad(15);  % 15度幅度
            frequency = 0.5;          % 0.5 Hz
            
            profile.omega(2, :) = amplitude * 2*pi*frequency * ...
                                  cos(2*pi*frequency*t);  % 俯仰角速度
            profile.att(2, :) = amplitude * sin(2*pi*frequency*t);
            
            % 添加滚转激励
            profile.omega(1, :) = amplitude * 0.7 * 2*pi*frequency * ...
                                  sin(2*pi*frequency*t + pi/4);
            profile.att(1, :) = amplitude * 0.7 * -cos(2*pi*frequency*t + pi/4);
            
        case 'S形转弯'
            % S形转弯(激励航向)
            turn_rate = deg2rad(15);  % 15度/秒转弯率
            turn_duration = 10;       % 每次转弯10秒
            
            for k = 1:N
                phase = floor(t(k)/turn_duration);
                if mod(phase, 2) == 0
                    profile.omega(3, k) = turn_rate;  % 右转
                else
                    profile.omega(3, k) = -turn_rate; % 左转
                end
                profile.att(3, k) = profile.att(3, max(1,k-1)) + ...
                                    profile.omega(3, k) * dt;
            end
            
        case '加速度机动'
            % 加速度变化(激励杆臂效应)
            accel_profile = zeros(1, N);
            segments = floor(N/4);
            
            % 分段加速度
            accel_profile(1:segments) = 2.0;          % 加速
            accel_profile(segments+1:2*segments) = 0; % 匀速
            accel_profile(2*segments+1:3*segments) = -1.5; % 减速
            accel_profile(3*segments+1:end) = 0.5;    % 小加速
            
            profile.accel(1, :) = accel_profile;
            
            % 计算速度和位置
            for k = 2:N
                profile.vel(1, k) = profile.vel(1, k-1) + ...
                                   profile.accel(1, k) * dt;
                profile.pos(1, k) = profile.pos(1, k-1) + ...
                                   profile.vel(1, k) * dt;
            end
            
            % 添加角运动
            profile.omega(2, :) = deg2rad(5) * sin(2*pi*0.2*t);
            profile.att(2, :) = deg2rad(5)/ (2*pi*0.2) * (1 - cos(2*pi*0.2*t));
            
        case '复合机动'
            % 组合多种机动
            % 加速度变化
            profile.accel(1, :) = 1.0 * sin(2*pi*0.1*t);
            
            % 角运动
            profile.omega(1, :) = deg2rad(10) * sin(2*pi*0.3*t);  % 滚转
            profile.omega(2, :) = deg2rad(8) * cos(2*pi*0.25*t);  % 俯仰
            profile.omega(3, :) = deg2rad(12) * sin(2*pi*0.15*t); % 航向
            
            % 积分得到速度和姿态
            for k = 2:N
                profile.vel(:, k) = profile.vel(:, k-1) + ...
                                   profile.accel(:, k) * dt;
                profile.pos(:, k) = profile.pos(:, k-1) + ...
                                   profile.vel(:, k) * dt;
                profile.att(:, k) = profile.att(:, k-1) + ...
                                   profile.omega(:, k) * dt;
            end
    end
    
    % 添加噪声(真实环境)
    process_noise_level = 0.01;
    profile.accel = profile.accel + process_noise_level * randn(3, N);
    profile.omega = profile.omega + deg2rad(0.1) * randn(3, N);
end

4. 惯性导航更新函数

matlab 复制代码
function [master, slave, true_err] = update_ins_states(master, slave, motion, k, dt)
% 更新主/子惯导状态(包含真实误差)
    
    if k == 1
        % 初始状态
        master.att(:, 1) = deg2rad([0; 0; 45]);  % 初始航向45度
        slave.att(:, 1) = master.att(:, 1) + deg2rad([0.5; 0.3; 1.0]);  % 初始误差
        
        % 杆臂效应参数(真实值)
        true_err.lever_arm = [0.5; -0.3; 0.2];  % 主惯导到子惯导的杆臂 (m)
        true_err.misalignment = deg2rad([0.5; 0.5; 1.0]);  % 安装失准角 (rad)
        true_err.gyro_bias = deg2rad([0.1; -0.05; 0.08]/3600);  % 陀螺零偏 (rad/s)
        true_err.accel_bias = [1e-3; -5e-4; 2e-3];  % 加表零偏 (m/s^2)
        
        % 子惯导初始位置 = 主惯导位置 + 杆臂
        slave.pos(:, 1) = master.pos(:, 1) + true_err.lever_arm;
        
        return;
    end
    
    % ---------- 主惯导更新(假设完美) ----------
    % 获取当前运动参数
    omega = motion.omega(:, min(k, size(motion.omega, 2)));
    accel = motion.accel(:, min(k, size(motion.accel, 2)));
    
    % 姿态更新(四元数法)
    C_nb_prev = euler2dcm(master.att(:, k-1));
    delta_theta = omega * dt;
    C_nb_curr = C_nb_prev * (eye(3) + skew_symmetric(delta_theta));
    master.att(:, k) = dcm2euler(C_nb_curr);
    
    % 速度更新
    gravity = [0; 0; 9.7803267714];  % 重力向量
    master.vel(:, k) = master.vel(:, k-1) + ...
                      (C_nb_curr * accel + gravity) * dt;
    
    % 位置更新
    master.pos(:, k) = master.pos(:, k-1) + master.vel(:, k) * dt;
    
    % ---------- 子惯导更新(包含误差) ----------
    % 安装误差影响
    C_misalignment = euler2dcm(true_err.misalignment);
    
    % 子惯导处的比力(考虑杆臂效应)
    omega_dot = (omega - motion.omega(:, max(1,k-1))) / dt;
    lever_accel = skew_symmetric(omega_dot) * true_err.lever_arm + ...
                  skew_symmetric(omega) * skew_symmetric(omega) * true_err.lever_arm;
    
    accel_slave = accel + lever_accel;
    
    % 添加传感器误差
    gyro_slave = omega + true_err.gyro_bias + deg2rad(0.1/3600) * randn(3,1);
    accel_slave = accel_slave + true_err.accel_bias + 1e-4 * randn(3,1);
    
    % 子惯导姿态更新
    C_slave_prev = euler2dcm(slave.att(:, k-1));
    delta_theta_slave = gyro_slave * dt;
    C_slave_curr = C_slave_prev * (eye(3) + skew_symmetric(delta_theta_slave));
    slave.att(:, k) = dcm2euler(C_slave_curr);
    
    % 子惯导速度更新
    slave.vel(:, k) = slave.vel(:, k-1) + ...
                     (C_slave_curr * accel_slave + gravity) * dt;
    
    % 子惯导位置更新
    slave.pos(:, k) = slave.pos(:, k-1) + slave.vel(:, k) * dt;
    
    % 保存真实误差(用于验证)
    true_err.att_error = slave.att(:, k) - master.att(:, k);
    true_err.vel_error = slave.vel(:, k) - master.vel(:, k);
    true_err.pos_error = slave.pos(:, k) - master.pos(:, k);
end

5. 辅助工具函数

matlab 复制代码
function C = euler2dcm(euler)
% 欧拉角转换为方向余弦矩阵 (Z-Y-X顺序)
    phi = euler(1); theta = euler(2); psi = euler(3);
    
    Cx = [1, 0, 0; 0, cos(phi), sin(phi); 0, -sin(phi), cos(phi)];
    Cy = [cos(theta), 0, -sin(theta); 0, 1, 0; sin(theta), 0, cos(theta)];
    Cz = [cos(psi), sin(psi), 0; -sin(psi), cos(psi), 0; 0, 0, 1];
    
    C = Cz * Cy * Cx;  % 注意顺序:航向-俯仰-滚转
end

function euler = dcm2euler(C)
% 方向余弦矩阵转换为欧拉角
    phi = atan2(C(3,2), C(3,3));  % 滚转
    theta = -asin(C(3,1));        % 俯仰
    psi = atan2(C(2,1), C(1,1));  % 航向
    euler = [phi; theta; psi];
end

function S = skew_symmetric(v)
% 生成反对称矩阵
    S = [0, -v(3), v(2); 
         v(3), 0, -v(1); 
         -v(2), v(1), 0];
end

function measurements = generate_measurements(master, slave, k, kf_params)
% 生成量测信息(速度差 + 姿态差)
    
    % 速度差量测
    vel_diff = slave.vel(:, k) - master.vel(:, k);
    
    % 姿态差量测(通过方向余弦矩阵计算)
    C_master = euler2dcm(master.att(:, k));
    C_slave = euler2dcm(slave.att(:, k));
    C_diff = C_slave * C_master';
    
    % 将旋转矩阵转换为旋转向量(姿态误差)
    theta = acos((trace(C_diff) - 1)/2);
    if abs(theta) < 1e-10
        att_diff = zeros(3,1);
    else
        axis = [C_diff(3,2)-C_diff(2,3); 
                C_diff(1,3)-C_diff(3,1); 
                C_diff(2,1)-C_diff(1,2)] / (2*sin(theta));
        att_diff = theta * axis;
    end
    
    % 添加量测噪声
    vel_noise = sqrt(kf_params.R(1,1)) * randn(3,1);
    att_noise = sqrt(kf_params.R(4,4)) * randn(3,1);
    
    measurements = [vel_diff + vel_noise; att_diff + att_noise];
end

6. 结果分析与可视化

matlab 复制代码
function analyze_and_plot_results(t, master, slave, true_errors, ...
                                 estimation_history, kf_params, ...
                                 state_names, maneuver_type)
    
    fprintf('\n========== 对准性能分析 ==========\n');
    
    % 提取估计结果
    est_states = estimation_history.state;
    n_states = size(est_states, 1);
    
    % 计算对准误差
    final_att_error = rad2deg(slave.att(:, end) - master.att(:, end));
    final_vel_error = slave.vel(:, end) - master.vel(:, end);
    final_pos_error = slave.pos(:, end) - master.pos(:, end);
    
    fprintf('最终姿态误差: 滚转=%.4f°, 俯仰=%.4f°, 航向=%.4f°\n', ...
            final_att_error(1), final_att_error(2), final_att_error(3));
    fprintf('最终速度误差: [%.4f, %.4f, %.4f] m/s\n', ...
            final_vel_error(1), final_vel_error(2), final_vel_error(3));
    fprintf('最终位置误差: [%.4f, %.4f, %.4f] m\n', ...
            final_pos_error(1), final_pos_error(2), final_pos_error(3));
    
    % 1. 误差状态估计对比图
    figure('Position', [100, 100, 1400, 800]);
    
    % 姿态误差估计
    subplot(3, 4, 1:2);
    true_att_err = rad2deg(reshape([true_errors.att_error], 3, []));
    plot(t, true_att_err', '--', 'LineWidth', 1.5); hold on;
    plot(t, rad2deg(est_states(1:3, 1:length(t))'), '-', 'LineWidth', 1);
    xlabel('时间 (s)'); ylabel('姿态误差 (°)');
    title('姿态误差估计对比');
    legend('真实滚转', '真实俯仰', '真实航向', ...
           '估计滚转', '估计俯仰', '估计航向', 'Location', 'best');
    grid on;
    
    % 速度误差估计
    subplot(3, 4, 3:4);
    true_vel_err = reshape([true_errors.vel_error], 3, []);
    plot(t, true_vel_err', '--', 'LineWidth', 1.5); hold on;
    plot(t, est_states(4:6, 1:length(t))', '-', 'LineWidth', 1);
    xlabel('时间 (s)'); ylabel('速度误差 (m/s)');
    title('速度误差估计对比');
    legend('真实东向', '真实北向', '真实天向', ...
           '估计东向', '估计北向', '估计天向', 'Location', 'best');
    grid on;
    
    % 传感器零偏估计
    subplot(3, 4, 5:6);
    gyro_bias_est = rad2deg(est_states(10:12, :)) * 3600;  % 转换为°/h
    plot(t, gyro_bias_est', 'LineWidth', 1.5);
    xlabel('时间 (s)'); ylabel('陀螺零偏 (°/h)');
    title('陀螺零偏估计');
    legend('X轴', 'Y轴', 'Z轴', 'Location', 'best');
    grid on;
    
    subplot(3, 4, 7:8);
    accel_bias_est = est_states(13:15, :) * 1e3;  % 转换为mg
    plot(t, accel_bias_est', 'LineWidth', 1.5);
    xlabel('时间 (s)'); ylabel('加表零偏 (mg)');
    title('加表零偏估计');
    legend('X轴', 'Y轴', 'Z轴', 'Location', 'best');
    grid on;
    
    % 安装误差和杆臂估计
    subplot(3, 4, 9:10);
    misalignment_est = rad2deg(est_states(19:21, :));
    plot(t, misalignment_est', 'LineWidth', 1.5);
    xlabel('时间 (s)'); ylabel('安装失准角 (°)');
    title('安装失准角估计');
    legend('X轴', 'Y轴', 'Z轴', 'Location', 'best');
    grid on;
    
    subplot(3, 4, 11:12);
    lever_est = est_states(16:18, :);
    plot(t, lever_est', 'LineWidth', 1.5);
    xlabel('时间 (s)'); ylabel('杆臂 (m)');
    title('杆臂估计');
    legend('X轴', 'Y轴', 'Z轴', 'Location', 'best');
    grid on;
    
    sgtitle(sprintf('传递对准状态估计结果 - 机动类型: %s', maneuver_type));
    
    % 2. 收敛特性分析
    figure('Position', [100, 100, 1200, 400]);
    
    % 协方差收敛(3σ边界)
    subplot(1, 2, 1);
    sigma_att = 3 * sqrt(estimation_history.cov(1:3, :));
    plot(t, rad2deg(sigma_att'), 'LineWidth', 1.5);
    xlabel('时间 (s)'); ylabel('3σ边界 (°)');
    title('姿态误差协方差收敛');
    legend('滚转', '俯仰', '航向', 'Location', 'best');
    grid on;
    
    % 新息序列(检验滤波器一致性)
    subplot(1, 2, 2);
    innovations = estimation_history.innovation(1:3, :);
    plot(t, innovations', 'LineWidth', 1);
    hold on;
    innov_std = sqrt(kf_params.R(1,1));
    plot(t, 3*innov_std*ones(size(t)), 'r--', 'LineWidth', 1.5);
    plot(t, -3*innov_std*ones(size(t)), 'r--', 'LineWidth', 1.5);
    xlabel('时间 (s)'); ylabel('速度新息 (m/s)');
    title('新息序列及3σ边界');
    legend('东向', '北向', '天向', '±3σ', 'Location', 'best');
    grid on;
    
    % 3. 对准精度统计
    figure('Position', [100, 100, 800, 600]);
    
    % 计算稳态误差(最后10秒)
    steady_start = find(t >= t(end)-10, 1);
    steady_idx = steady_start:length(t);
    
    att_steady = rad2deg(est_states(1:3, steady_idx));
    vel_steady = est_states(4:6, steady_idx);
    
    att_std = std(att_steady, 0, 2);
    vel_std = std(vel_steady, 0, 2);
    
    subplot(2, 2, 1);
    bar([att_std'; vel_std']);
    set(gca, 'XTickLabel', {'姿态(°)', '速度(m/s)'});
    ylabel('稳态标准差');
    title('对准精度统计');
    legend('滚转/X轴', '俯仰/Y轴', '航向/Z轴', 'Location', 'best');
    grid on;
    
    % 收敛时间分析(达到95%最终值的时间)
    subplot(2, 2, 2);
    conv_time = zeros(3, 1);
    for i = 1:3
        final_val = abs(est_states(i, end));
        idx_95 = find(abs(est_states(i, :)) >= 0.95*final_val, 1);
        if ~isempty(idx_95)
            conv_time(i) = t(idx_95);
        end
    end
    bar(conv_time);
    ylabel('收敛时间 (s)');
    set(gca, 'XTickLabel', {'滚转', '俯仰', '航向'});
    title('主要状态收敛时间');
    grid on;
    
    % 机动效果分析
    subplot(2, 2, 3);
    % 计算不同机动阶段的估计精度
    if strcmp(maneuver_type, 'S形转弯')
        turn_period = 10;  % 转弯周期
        n_turns = floor(t(end)/turn_period);
        turn_accuracy = zeros(n_turns, 3);
        
        for turn = 1:n_turns
            turn_idx = find(t >= (turn-1)*turn_period & t < turn*turn_period);
            if ~isempty(turn_idx)
                turn_accuracy(turn, :) = std(rad2deg(est_states(1:3, turn_idx)), 0, 2)';
            end
        end
        
        plot(1:n_turns, turn_accuracy, 'o-', 'LineWidth', 1.5);
        xlabel('转弯序号'); ylabel('姿态误差标准差 (°)');
        title('不同转弯阶段对准精度');
        legend('滚转', '俯仰', '航向', 'Location', 'best');
        grid on;
    end
    
    % 杆臂效应估计精度
    subplot(2, 2, 4);
    lever_true = true_errors.lever_arm;
    lever_est_final = est_states(16:18, end);
    lever_error = abs(lever_est_final - lever_true);
    
    bar(lever_error);
    ylabel('杆臂估计绝对误差 (m)');
    set(gca, 'XTickLabel', {'X轴', 'Y轴', 'Z轴'});
    title('杆臂估计最终精度');
    grid on;
    
    fprintf('\n========== 对准性能总结 ==========\n');
    fprintf('机动类型: %s\n', maneuver_type);
    fprintf('姿态对准精度 (3σ): 滚转=%.4f°, 俯仰=%.4f°, 航向=%.4f°\n', ...
            3*att_std(1), 3*att_std(2), 3*att_std(3));
    fprintf('速度对准精度 (3σ): [%.4f, %.4f, %.4f] m/s\n', ...
            3*vel_std(1), 3*vel_std(2), 3*vel_std(3));
    fprintf('航向收敛时间: %.2f s\n', conv_time(3));
end

7. 程序使用说明

  1. 运行方式

    • 将以上所有函数保存为独立的.m文件或放在一个文件中运行
    • 从主程序开始执行
  2. 关键参数调整

    matlab 复制代码
    % 在init_transfer_alignment_kf函数中调整:
    - 初始协方差P:影响收敛速度
    - 过程噪声Q:模型不确定性
    - 量测噪声R:传感器精度
    
    % 在generate_maneuver_trajectory函数中调整:
    - 机动类型:选择不同激励运动
    - 机动幅度:影响可观性
  3. 仿真场景定制

    • 修改true_err结构体中的误差参数模拟不同设备
    • 添加新的机动类型以测试不同环境下的对准性能
    • 修改量测方案(如增加位置匹配)

参考代码 关于传递对准的MATLAB仿真源代码 www.3dddown.com/csa/97398.html

8. 扩展功能建议

  1. 多算法比较

    matlab 复制代码
    % 实现UKF、EKF等不同滤波器的比较
    algorithms = {'EKF', 'UKF', 'PF'};
    results = cell(length(algorithms), 1);
    for i = 1:length(algorithms)
        results{i} = run_transfer_alignment(algorithm);
    end
  2. 硬件在环测试接口

    matlab 复制代码
    % 添加串口/UDP接口接收真实IMU数据
    function real_data = read_imu_from_port(port)
        % 从硬件读取数据
    end
相关推荐
编程武士3 小时前
Python 各版本主要变化速览
开发语言·python
hqwest3 小时前
码上通QT实战29--系统设置04-用户操作管理
开发语言·qt·模态窗体·addbindvalue·bindvalue
专注于大数据技术栈3 小时前
java学习--LinkedHashSet
java·开发语言·学习
这个图像胖嘟嘟3 小时前
前端开发的基本运行环境配置
开发语言·javascript·vue.js·react.js·typescript·npm·node.js
星竹晨L4 小时前
【C++内存安全管理】智能指针的使用和原理
开发语言·c++
宵时待雨4 小时前
数据结构(初阶)笔记归纳3:顺序表的应用
c语言·开发语言·数据结构·笔记·算法
旺仔小拳头..4 小时前
Java ---变量、常量、类型转换、默认值、重载、标识符、输入输出、访问修饰符、泛型、迭代器
java·开发语言·python
lsx2024064 小时前
Vue3 自定义指令
开发语言
牛奔5 小时前
Go语言中结构体转Map优雅实现
开发语言·后端·macos·golang·xcode