尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

MATLAB实现UKF自行车状态估计:从非线性滤波原理到工程实践

MATLAB实现UKF自行车状态估计:从非线性滤波原理到工程实践 1. 项目概述当自行车遇上UKF状态估计在自动驾驶、机器人导航和智能交通系统等领域准确获取运动载体的实时状态如位置、速度、姿态角是进行决策和控制的基础。然而现实世界充满了不确定性传感器有噪声模型有误差环境有干扰。自行车作为一种经典的非线性动态系统其运动模型虽然相对简单但同样具备强非线性、耦合性等特点是学习和验证先进状态估计算法的绝佳“试验田”。今天要聊的就是如何利用MATLAB实现基于无迹卡尔曼滤波Unscented Kalman Filter, UKF的自行车状态估计。简单来说状态估计就是从一堆带有噪声的、可能不完整的观测数据中尽可能准确地“猜”出系统内部那些我们无法直接测量或测量不准的状态。对于自行车这些状态可能包括质心的位置、速度、航向角、车身倾角等。卡尔曼滤波是解决线性高斯系统状态估计的黄金标准但自行车模型是非线性的。扩展卡尔曼滤波EKF通过一阶泰勒展开线性化在非线性不强时效果尚可但对于强非线性或模型复杂的情况其精度和稳定性会大打折扣。UKF则另辟蹊径它采用一种名为“无迹变换”的确定性采样方法直接逼近非线性函数的概率分布避免了求导雅可比矩阵的繁琐和误差在处理非线性问题时通常比EKF更鲁棒、更精确。这个项目的核心价值在于它提供了一个从理论到实践的完整闭环。你不仅能看到UKF算法的数学框架更能通过MATLAB代码亲手实现并直观地观察滤波器如何从嘈杂的传感器数据中“抽丝剥茧”还原出自行车平滑、真实的运动轨迹。这对于学习非线性滤波、理解传感器融合、乃至为更复杂的机器人系统设计状态估计器都是一个极佳的起点。2. 核心原理UKF为何比EKF更适合非线性系统在深入代码之前我们必须搞清楚UKF的“内力心法”。理解其为何而生才能更好地运用它。2.1 非线性估计的挑战与EKF的局限传统的卡尔曼滤波建立在两个核心假设上系统动态模型和观测模型都是线性的并且过程噪声和观测噪声都是高斯白噪声。对于线性高斯系统卡尔曼滤波给出的状态估计是最优的。然而现实系统大多是非线性的。EKF的策略是对非线性函数进行一阶泰勒展开在上一时刻状态估计值附近进行线性化然后应用标准卡尔曼滤波公式。这种方法存在几个固有缺陷线性化误差一阶近似会引入误差当系统非线性程度高时此误差会急剧放大导致滤波器性能下降甚至发散。雅可比矩阵计算需要推导和计算非线性函数关于状态变量的雅可比矩阵。对于复杂模型这个过程极其繁琐且容易出错。对初值敏感如果初始估计偏差较大线性化点远离真实状态误差会更大。2.2 无迹变换UKF的智慧内核UKF的核心思想非常巧妙与其费力地去线性化一个非线性函数不如直接去逼近这个函数对概率分布的变换结果。它采用一种确定性的采样策略——选取一组特殊的样本点称为Sigma点这些点能精确捕获输入状态均值和协方差的所有信息。无迹变换的步骤可以概括为Sigma点采样根据当前状态估计的均值 (\hat{x}{k-1}) 和协方差 (P{k-1})按照特定规则通常使用对称采样生成一组2n1个n为状态维数Sigma点 (\mathcal{X}_i)。这些点像探针一样分布在状态估计的不确定性范围内。非线性传播将每一个Sigma点分别通过非线性系统模型 (f(\cdot)) 和观测模型 (h(\cdot)) 进行传播得到一组变换后的点 (\mathcal{Y}_i f(\mathcal{X}_i)) 和 (\mathcal{Z}_i h(\mathcal{X}_i))。统计量重构对传播后的点集进行加权求和直接计算出预测状态的均值 (\hat{x}k^-)、协方差 (P_k^-) 以及预测观测的均值 (\hat{z}k^-)、协方差 (P{zz}) 和互协方差 (P{xz})。这里的权重是事先根据参数计算好的。关键参数解析在Sigma点采样中有三个可调参数(\alpha)控制Sigma点围绕均值的扩散程度通常取小正值如1e-3、(\beta)包含状态分布先验信息高斯分布时最优值为2、(\kappa)次要缩放参数通常设为0或3-n。这些参数影响着Sigma点的分布进而影响滤波性能。在实际应用中(\alpha) 是最常微调的参数增大它会使Sigma点更分散可能增强对强非线性的捕捉能力但也可能引入额外误差。UKF相对于EKF的优势精度更高无迹变换至少能精确到二阶对高斯输入可精确到三阶而EFK仅有一阶精度。无需求导完全避免了计算雅可比矩阵的复杂性和潜在错误实现更简单、更稳健。更易实现算法流程规整尤其适合在像MATLAB这样的环境中进行向量化实现。3. 自行车运动模型与传感器建模任何状态估计都离不开两个基石描述状态如何随时间变化的动态模型以及描述状态如何映射到传感器读数的观测模型。3.1 自行车动力学模型我们采用一个简化的自行车动力学模型它足够体现非线性特性又不过于复杂。假设自行车在二维平面运动我们关心以下状态变量 [ \mathbf{x} [p_x, p_y, v, \psi, \phi]^T ] 其中(p_x, p_y)自行车后轮中心或质心在全局坐标系下的位置米。(v)自行车的行进速度米/秒。(\psi)航向角Yaw即车身方向与全局X轴的夹角弧度。(\phi)车身倾角Roll假设为一个小角度弧度。状态方程离散时间 我们可以建立如下非线性状态转移方程 [ \begin{aligned} p_x(k1) p_x(k) T \cdot v(k) \cdot \cos(\psi(k)) \ p_y(k1) p_y(k) T \cdot v(k) \cdot \sin(\psi(k)) \ v(k1) v(k) T \cdot a(k) w_v \ \psi(k1) \psi(k) T \cdot \frac{v(k)}{L} \cdot \tan(\delta(k)) w_{\psi} \ \phi(k1) \phi(k) w_{\phi} \end{aligned} ] 这里(T)是采样时间(a(k))是加速度控制输入来自踩踏或刹车(\delta(k))是前轮转角控制输入(L)是自行车轴距。(w_v, w_{\psi}, w_{\phi})是过程噪声代表了模型未考虑的因素如风阻、路面不平等。模型简化与注意事项这个模型忽略了轮胎侧偏、更复杂的车身动力学等。在实际应用中a(k)和delta(k)通常作为已知的输入量u(k)。如果你没有真实的控制输入数据在仿真中可以根据设定的运动轨迹如匀速圆周运动反向推导出近似的输入序列或者将加速度和转角率也作为状态的一部分用噪声驱动。3.2 传感器观测模型假设我们车上装有一些不完美的传感器GPS接收机提供带有噪声的位置测量 ((z_{px}, z_{py}))。其观测模型简单就是状态中的位置直接加上噪声。 [ \begin{aligned} z_{px} p_x n_{px} \ z_{py} p_y n_{py} \end{aligned} ]速度传感器如轮速编码器提供速度测量 (z_v)通常噪声较小。 [ z_v v n_v ]惯性测量单元IMU提供航向角变化率陀螺仪和加速度加速度计信息。为简化我们假设IMU直接输出带噪声的航向角 (z_{\psi}) 和倾角 (z_{\phi})实际上需要融合解算。 [ \begin{aligned} z_{\psi} \psi n_{\psi} \ z_{\phi} \phi n_{\phi} \end{aligned} ]这里的 (n_{*}) 代表各传感器的观测噪声通常建模为零均值高斯白噪声。观测方程可以写为向量形式 [ \mathbf{z}_k h(\mathbf{x}_k) \mathbf{v}_k, \quad \mathbf{v}_k \sim \mathcal{N}(0, R_k) ] 其中 (R_k) 是观测噪声协方差矩阵其对角线元素就是各传感器噪声的方差这需要根据传感器 datasheet 或实验标定来设定。传感器配置的灵活性UKF的一个优点是能轻松处理不同传感器组合。即使某个时刻某个传感器失效数据缺失你只需要在更新步骤中忽略该观测通道即可。在代码中这可以通过动态调整观测矩阵 (H)在EKF中或调整观测函数 (h(\cdot)) 和噪声矩阵 (R) 的维度来实现。在我们的无迹变换框架下只需不对应的Sigma点不参与特定观测量的计算和更新。4. MATLAB UKF实现全流程拆解下面我们结合MATLAB代码一步步拆解UKF的实现。我将假设一个仿真场景自行车以近似匀速进行“8”字形运动我们拥有带噪声的GPS位置和速度观测。4.1 仿真数据生成首先我们需要一个“真实”的世界和带噪声的观测作为输入。%% 1. 参数设置与真实轨迹生成 T 0.1; % 采样时间 [s] simTime 30; % 总仿真时间 [s] N simTime / T; % 总步数 % 自行车参数 L 1.2; % 轴距 [m] % 生成“8”字形参考轨迹真实状态 time (0:N-1) * T; omega 0.3; % 角频率 A 5; % 运动幅度 % 真实状态 [px, py, v, psi, phi] x_true zeros(N, 5); % 位置 x_true(:,1) A * sin(omega * time); % X方向 x_true(:,2) A * sin(2*omega * time) / 2; % Y方向形成8字 % 速度 (通过对位置差分近似) x_true(2:end, 3) sqrt(diff(x_true(:,1)).^2 diff(x_true(:,2)).^2) / T; x_true(1,3) x_true(2,3); % 航向角 (通过速度方向近似) x_true(2:end, 4) atan2(diff(x_true(:,2)), diff(x_true(:,1))); x_true(1,4) x_true(2,4); % 倾角 (假设与向心加速度相关简单建模) for k 1:N if k N psi_dot (x_true(k1,4) - x_true(k,4)) / T; else psi_dot 0; end % 简化模型倾角与向心加速度成正比 x_true(k,5) 0.05 * x_true(k,3) * abs(psi_dot); end %% 2. 生成带噪声的观测数据 % 定义观测噪声标准差 sigma_gps 0.3; % GPS位置噪声 [m] sigma_vel 0.1; % 速度噪声 [m/s] sigma_psi 0.05; % 航向角噪声 [rad] sigma_phi 0.02; % 倾角噪声 [rad] % 初始化观测数据矩阵 z_meas zeros(N, 4); % 假设观测为 [px, py, v, psi] for k 1:N % 真实值 true_px x_true(k,1); true_py x_true(k,2); true_v x_true(k,3); true_psi x_true(k,4); % 添加高斯噪声 z_meas(k,1) true_px sigma_gps * randn; z_meas(k,2) true_py sigma_gps * randn; z_meas(k,3) true_v sigma_vel * randn; z_meas(k,4) true_psi sigma_psi * randn; % 注意这里我们没有生成倾角的观测将其作为隐藏状态进行估计 end4.2 UKF算法核心函数实现接下来是重头戏实现一个通用的UKF函数。这个函数应该能处理任意的非线性状态方程和观测方程。function [x_est, P_est] ukf_filter(f_func, h_func, z, x0, P0, Q, R, dt, u) % UKF_UNSCENTED_KF 无迹卡尔曼滤波主函数 % 输入: % f_func: 状态转移函数句柄, x_next f(x, u, dt) % h_func: 观测函数句柄, z_pred h(x) % z: 观测数据序列, 每行是一个时刻的观测向量 % x0: 初始状态估计 % P0: 初始状态估计协方差 % Q: 过程噪声协方差矩阵 % R: 观测噪声协方差矩阵 % dt: 采样时间 % u: 控制输入序列 (可选), 每行是一个时刻的输入向量 % 输出: % x_est: 状态估计序列 % P_est: 估计协方差序列 (3维矩阵, 每页是一个时刻的P) n length(x0); % 状态维度 m size(z, 2); % 观测维度 Nsteps size(z, 1); % 总步数 % 初始化输出 x_est zeros(Nsteps, n); P_est zeros(n, n, Nsteps); x_est(1,:) x0; P_est(:,:,1) P0; % UKF参数 alpha 1e-3; % 默认值控制Sigma点分布 beta 2; % 高斯分布最优值 kappa 0; % 次要参数通常设为0 lambda alpha^2 * (n kappa) - n; % 计算Sigma点权重 Wm zeros(2*n1, 1); % 均值权重 Wc zeros(2*n1, 1); % 协方差权重 Wm(1) lambda / (n lambda); Wc(1) Wm(1) (1 - alpha^2 beta); for i 2:(2*n1) Wm(i) 1 / (2*(n lambda)); Wc(i) Wm(i); end % UKF主循环 x_k x0; P_k P0; for k 2:Nsteps % ---- 时间更新 (预测) ---- % 1. 生成Sigma点 sqrtP chol((n lambda) * P_k, lower); % Cholesky分解求矩阵平方根 X zeros(n, 2*n1); X(:,1) x_k; for i 1:n X(:, i1) x_k sqrtP(:, i); X(:, i1n) x_k - sqrtP(:, i); end % 2. 通过状态方程传播Sigma点 X_pred zeros(size(X)); if nargin(f_func) 3 exist(u, var) ~isempty(u) % 如果状态方程需要控制输入 for i 1:(2*n1) X_pred(:,i) f_func(X(:,i), u(k-1,:), dt); end else % 如果状态方程不需要控制输入或u未提供 for i 1:(2*n1) X_pred(:,i) f_func(X(:,i), [], dt); % 传入空输入 end end % 3. 计算预测状态均值和协方差 x_pred zeros(n,1); for i 1:(2*n1) x_pred x_pred Wm(i) * X_pred(:,i); end P_pred Q; % 先加上过程噪声协方差 for i 1:(2*n1) dx X_pred(:,i) - x_pred; P_pred P_pred Wc(i) * (dx * dx); end % ---- 测量更新 (校正) ---- % 4. 再次生成Sigma点 (基于预测均值和协方差) sqrtP_pred chol((n lambda) * P_pred, lower); X_sigma zeros(n, 2*n1); X_sigma(:,1) x_pred; for i 1:n X_sigma(:, i1) x_pred sqrtP_pred(:, i); X_sigma(:, i1n) x_pred - sqrtP_pred(:, i); end % 5. 通过观测方程传播Sigma点 Z_sigma zeros(m, 2*n1); for i 1:(2*n1) Z_sigma(:,i) h_func(X_sigma(:,i)); end % 6. 计算预测观测均值、协方差和互协方差 z_pred zeros(m,1); for i 1:(2*n1) z_pred z_pred Wm(i) * Z_sigma(:,i); end P_zz R; % 先加上观测噪声协方差 P_xz zeros(n, m); for i 1:(2*n1) dz Z_sigma(:,i) - z_pred; dx X_sigma(:,i) - x_pred; P_zz P_zz Wc(i) * (dz * dz); P_xz P_xz Wc(i) * (dx * dz); end % 7. 计算卡尔曼增益、更新状态和协方差 K P_xz / P_zz; % 相当于 P_xz * inv(P_zz) x_k x_pred K * (z(k,:) - z_pred); P_k P_pred - K * P_zz * K; % 存储结果 x_est(k,:) x_k; P_est(:,:,k) P_k; end end4.3 定义模型函数并运行滤波现在我们需要定义具体的状态转移函数f_kinematic和观测函数h_meas并调用UKF函数。%% 3. 定义模型函数 % 状态转移函数 (简化的运动学模型假设速度v和航向角psi变化缓慢) function x_next f_kinematic(x, u, dt) % x [px, py, v, psi, phi] % 本例中我们忽略控制输入u用噪声驱动模型 x_next x; x_next(1) x(1) dt * x(3) * cos(x(4)); % px x_next(2) x(2) dt * x(3) * sin(x(4)); % py % v, psi, phi 假设在短时间内近似不变主要靠过程噪声驱动 % 在实际有IMU的模型中这里应加入角速度和加速度的积分 end % 观测函数 (假设我们能直接观测到px, py, v, psi) function z h_meas(x) % x [px, py, v, psi, phi] % z [px, py, v, psi] 注意phi是隐藏状态未被观测 z [x(1); x(2); x(3); x(4)]; end %% 4. 设置UKF初始参数并运行 % 初始状态估计 (可以给一个粗略的猜测甚至可以从第一次观测初始化) x0 [z_meas(1,1); z_meas(1,2); z_meas(1,3); z_meas(1,4); 0]; % 倾角初始为0 % 初始协方差矩阵 (表示我们对初始估计的不确定度) P0 diag([1.0, 1.0, 0.5, 0.3, 0.1].^2); % 对角线是各状态初始方差 % 过程噪声协方差矩阵Q (表征模型的不确定度) % 需要根据实际系统动力学调整。这里根据状态变量的物理意义和采样时间设定。 Q diag([0.01, 0.01, 0.1, 0.05, 0.02].^2); % 位置噪声小速度、角度噪声稍大 % 观测噪声协方差矩阵R (直接来自传感器噪声特性) R diag([sigma_gps, sigma_gps, sigma_vel, sigma_psi].^2); % 运行UKF滤波 [x_est, P_est] ukf_filter(f_kinematic, h_meas, z_meas, x0, P0, Q, R, T); %% 5. 结果可视化与分析 figure(Position, [100,100,1200,800]); % 子图1: 二维轨迹对比 subplot(2,3,1); plot(x_true(:,1), x_true(:,2), b-, LineWidth, 1.5, DisplayName, 真实轨迹); hold on; plot(z_meas(:,1), z_meas(:,2), r., MarkerSize, 8, DisplayName, GPS观测); plot(x_est(:,1), x_est(:,2), g-, LineWidth, 2, DisplayName, UKF估计); xlabel(X 位置 (m)); ylabel(Y 位置 (m)); title(二维运动轨迹对比); legend(Location, best); grid on; axis equal; % 子图2: X方向位置估计误差 subplot(2,3,2); err_px x_est(:,1) - x_true(:,1); plot(time, err_px, k-, LineWidth, 1.5); hold on; % 绘制 ±2σ 误差边界 (估计的不确定度) sigma_px squeeze(sqrt(P_est(1,1,:))); plot(time, 2*sigma_px, r--, time, -2*sigma_px, r--, LineWidth, 1); xlabel(时间 (s)); ylabel(X位置误差 (m)); title(X方向估计误差与2σ边界); legend(误差, ±2σ边界); grid on; % 子图3: 速度估计对比 subplot(2,3,3); plot(time, x_true(:,3), b-, LineWidth, 1.5, DisplayName, 真实速度); hold on; plot(time, z_meas(:,3), r., MarkerSize, 8, DisplayName, 速度观测); plot(time, x_est(:,3), g-, LineWidth, 2, DisplayName, UKF估计); xlabel(时间 (s)); ylabel(速度 (m/s)); title(速度估计对比); legend(Location, best); grid on; % 子图4: 航向角估计对比 subplot(2,3,4); plot(time, x_true(:,4), b-, LineWidth, 1.5, DisplayName, 真实航向); hold on; plot(time, z_meas(:,4), r., MarkerSize, 8, DisplayName, 航向观测); plot(time, x_est(:,4), g-, LineWidth, 2, DisplayName, UKF估计); xlabel(时间 (s)); ylabel(航向角 \psi (rad)); title(航向角估计对比); legend(Location, best); grid on; % 子图5: 倾角估计 (隐藏状态) subplot(2,3,5); plot(time, x_true(:,5), b-, LineWidth, 1.5, DisplayName, 真实倾角); hold on; plot(time, x_est(:,5), g-, LineWidth, 2, DisplayName, UKF估计); % 由于没有直接观测绘制估计的不确定度 sigma_phi squeeze(sqrt(P_est(5,5,:))); fill([time; flipud(time)], [x_est(:,5)2*sigma_phi; flipud(x_est(:,5)-2*sigma_phi)], ... [0.9 0.9 0.9], EdgeColor, none, FaceAlpha, 0.5, DisplayName, ±2σ区间); xlabel(时间 (s)); ylabel(倾角 \phi (rad)); title(倾角(隐藏状态)估计); legend(Location, best); grid on; % 子图6: 估计误差的RMS统计 subplot(2,3,6); state_labels {px, py, v, \psi, \phi}; rms_error zeros(5,1); for i 1:5 rms_error(i) sqrt(mean((x_est(:,i) - x_true(:,i)).^2)); end bar(1:5, rms_error); set(gca, XTickLabel, state_labels); ylabel(RMS误差); title(各状态估计RMS误差对比); grid on;5. 参数调优、问题排查与实战心得实现UKF只是第一步让它稳定、精确地工作才是真正的挑战。下面分享一些关键的调参经验和踩坑记录。5.1 关键参数调优指南UKF的性能很大程度上取决于四个协方差矩阵初始协方差 (P_0)、过程噪声协方差 (Q)、观测噪声协方差 (R) 以及无迹变换参数主要是 (\alpha)。初始协方差 (P_0)它反映了你对初始状态估计的信心。如果你完全不知道初始状态可以设一个很大的值如对角元素为100滤波器会更快地相信观测数据。如果初始估计比较准确就设小一些。一个实用的技巧是如果状态可以从第一次观测直接推导如位置、速度就用观测值初始化并给一个较小的 (P_0)对于不能直接观测的状态如倾角初始化为0并给一个较大的 (P_0)。过程噪声协方差 (Q)这是最重要的调参对象之一。它代表了你的模型有多不准确。值太小滤波器会过于相信自己的预测模型对观测数据反应迟钝可能导致估计滞后甚至发散。值太大滤波器会过于相信噪声大的观测数据估计结果会变得很“毛躁”跟随观测噪声抖动。调参方法通常根据状态变量的物理意义和采样周期来设定数量级。例如位置的过程噪声可能与速度、加速度有关可以设为 ((0.5*a_{max}*T^2)^2)其中 (a_{max}) 是最大预期加速度。一个黄金法则是在仿真中将真实状态与估计状态作差计算新息序列观测残差。理想情况下新息序列应该是零均值白噪声。如果新息序列表现出明显的自相关或非零均值说明 (Q) 可能设得不合适。观测噪声协方差 (R)这个相对好确定通常来自传感器厂商提供的精度指标如GPS的CEP。如果你有传感器数据手册可以直接使用。如果没有可以通过传感器静止时的数据统计其噪声方差。确保 (R) 的对角线元素单位与观测量的单位平方一致。无迹变换参数 (\alpha)通常设置在 (10^{-3}) 到 (1) 之间。较小的 (\alpha) 使Sigma点更靠近均值适用于状态分布比较集中、非线性度不高的情况。较大的 (\alpha) 使Sigma点更分散能更好地捕捉非线性但若非线性太强或初始误差大可能导致Sigma点跑到物理上无意义的区域造成数值不稳定。建议从默认值 1e-3 开始如果发现滤波器在状态突变时跟踪慢可以尝试适当增大到 0.1 或 0.5。5.2 常见问题与排查技巧滤波器发散估计值爆炸或变成NaN可能原因1数值不稳定。在计算预测协方差 (P^-) 或更新协方差 (P) 时矩阵可能失去正定性。解决方法在代码中用chol函数进行Cholesky分解前可以加入一个正则化步骤P (P P) / 2确保矩阵对称并给对角线加上一个极小值P P eye(n)*1e-6保证正定。也可以使用更稳定的平方根UKFSR-UKF算法。可能原因2过程噪声 (Q) 设得太小。模型误差积累无法被纠正。尝试逐步增大 (Q) 的对角线元素。可能原因3模型函数 (f) 或 (h) 返回了非法值如Inf或NaN。仔细检查模型函数特别是三角函数、除法等操作确保输入值在合理范围内。估计结果滞后滤波器反应慢典型表现在轨迹转弯或速度变化时估计轨迹总是“慢半拍”。主要原因过程噪声 (Q) 设置过小和/或观测噪声 (R) 设置过大。滤波器过于“保守”更相信过去的模型预测而不愿意快速采纳新的观测数据。解决方法适当增大 (Q)增加模型不确定性或适当减小 (R)表示你更信任传感器。注意调整 (Q) 和 (R) 的本质是在模型信任度和传感器信任度之间做权衡。估计结果噪声大曲线毛刺多与滞后相反这是 (Q) 太大或 (R) 太小的表现。滤波器对观测噪声过于敏感。解决方法减小 (Q) 或增大 (R)。一个更精细的做法是使用自适应UKF根据新息序列实时调整 (Q) 或 (R)。隐藏状态如倾角估计不准倾角 (\phi) 没有直接观测完全靠模型动力学和其他状态速度、航向角的耦合关系来估计。如果模型中对倾角的动力学描述过于简单如本例中假设为随机游走估计效果可能不佳。改进方法引入更精确的自行车动力学模型将倾角变化率与向心加速度、车把转角等建立物理关系。即使这个关系不完美也比纯随机游走模型提供更多的信息能显著改善隐藏状态的估计。5.3 实操心得与进阶建议仿真验证是第一步在将算法应用到真实数据前务必进行充分的仿真。仿真可以让你控制“真实状态”从而定量评估滤波器的性能如RMS误差并安全地调试参数。绘制新息序列及其自相关图这是诊断滤波器是否“健康”的听诊器。在MATLAB中滤波后计算新息innovations z_meas - z_pred然后绘制其随时间的变化图并计算其自相关函数autocorr(innovations)。理想的新息应该是零均值、白噪声。如果自相关图在滞后0处有尖峰之后迅速衰减到接近0说明滤波器工作良好如果存在显著的非零滞后相关说明模型或噪声参数有误。从简单模型开始不要一开始就追求复杂的动力学模型。先用一个简单的运动学模型如恒定速度模型CV或恒定转率和速度模型CTRV把UKF的流程跑通确保代码正确参数基本合理。然后再逐步引入更复杂的模型。考虑使用交互式多模型IMM如果自行车运动模式多变如直线、转弯、加速单一模型可能无法很好描述。IMM算法可以并行运行多个不同参数的UKF例如一个用于匀速直线一个用于匀速转弯根据模型匹配概率进行加权输出鲁棒性更强。代码优化上述UKF循环中的for循环在MATLAB中可能较慢。对于性能要求高的实时应用可以考虑将Sigma点的生成和传播向量化或者探索使用MATLAB Coder将核心部分生成C代码。
返回列表