news 2026/4/30 9:43:49

三自由度车辆模型的扩展卡尔曼滤波(EKF)程序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
三自由度车辆模型的扩展卡尔曼滤波(EKF)程序

使用扩展卡尔曼滤波(EKF)来估计三自由度车辆模型的状态。这个模型包括纵向速度、横向速度和横摆角速度。

%% 三自由度车辆模型的扩展卡尔曼滤波程序clc;clear;close all;%% 车辆参数设置m=1573;% 车辆质量 (kg)Iz=2873;% 绕Z轴的转动惯量 (kg*m^2)lf=1.1;% 前轴到质心的距离 (m)lr=1.58;% 后轴到质心的距离 (m)Cf=80000;% 前轮侧偏刚度 (N/rad)Cr=80000;% 后轮侧偏刚度 (N/rad)%% 仿真参数dt=0.01;% 时间步长 (s)T=10;% 总仿真时间 (s)N=T/dt;% 总步数%% 初始状态% 状态向量: [纵向速度 vx, 横向速度 vy, 横摆角速度 r]x_true=[20;0;0];% 真实状态 (m/s, m/s, rad/s)x_est=[19;0.1;0.1];% 估计状态 (初始带有误差)P=diag([1,0.1,0.01]);% 估计误差协方差矩阵%% 过程噪声和测量噪声Q=diag([0.1,0.1,0.01]);% 过程噪声协方差R=diag([0.5,0.5,0.05]);% 测量噪声协方差%% 输入控制 (前轮转角和驱动力矩)% 正弦转向输入delta=zeros(1,N);fork=1:Nifk<N/2delta(k)=0.1*sin(2*pi*0.5*k*dt);elsedelta(k)=0.05*sin(2*pi*0.5*k*dt);endend% 简单的驱动力矩输入Fx=200*ones(1,N);% 恒定的驱动力 (N)%% 数据存储x_true_history=zeros(3,N);x_est_history=zeros(3,N);measurements_history=zeros(3,N);innovation_history=zeros(3,N);%% 扩展卡尔曼滤波主循环fork=1:N% 获取当前控制输入u=[delta(k);Fx(k)];% 1. 真实系统动态 (用于生成测量值)x_true=vehicle_dynamics(x_true,u,m,Iz,lf,lr,Cf,Cr,dt);% 2. 生成带有噪声的测量值z=measure(x_true)+sqrt(R)*randn(3,1);% 3. 预测步骤 (使用非线性模型)[x_pred,F]=predict(x_est,u,m,Iz,lf,lr,Cf,Cr,dt);P_pred=F*P*F'+Q;% 4. 更新步骤[z_pred,H]=measurement_model(x_pred);y=z-z_pred;% 创新向量S=H*P_pred*H'+R;K=P_pred*H'/S;x_est=x_pred+K*y;P=(eye(3)-K*H)*P_pred;% 存储数据x_true_history(:,k)=x_true;x_est_history(:,k)=x_est;measurements_history(:,k)=z;innovation_history(:,k)=y;end%% 绘制结果t=0:dt:T-dt;% 状态估计结果figure('Position',[100,100,1200,800]);subplot(3,1,1);plot(t,x_true_history(1,:),'LineWidth',2);hold on;plot(t,x_est_history(1,:),'--','LineWidth',2);plot(t,measurements_history(1,:),'.','MarkerSize',8);legend('真实值','估计值','测量值');title('纵向速度 v_x (m/s)');grid on;subplot(3,1,2);plot(t,x_true_history(2,:),'LineWidth',2);hold on;plot(t,x_est_history(2,:),'--','LineWidth',2);plot(t,measurements_history(2,:),'.','MarkerSize',8);legend('真实值','估计值','测量值');title('横向速度 v_y (m/s)');grid on;subplot(3,1,3);plot(t,x_true_history(3,:),'LineWidth',2);hold on;plot(t,x_est_history(3,:),'--','LineWidth',2);plot(t,measurements_history(3,:),'.','MarkerSize',8);legend('真实值','估计值','测量值');title('横摆角速度 r (rad/s)');grid on;% 创新序列 (应表现为零均值白噪声)figure('Position',[100,100,1000,600]);subplot(3,1,1);plot(t,innovation_history(1,:));title('纵向速度创新序列');grid on;subplot(3,1,2);plot(t,innovation_history(2,:));title('横向速度创新序列');grid on;subplot(3,1,3);plot(t,innovation_history(3,:));title('横摆角速度创新序列');grid on;% 估计误差errors=x_est_history-x_true_history;figure('Position',[100,100,1000,600]);subplot(3,1,1);plot(t,errors(1,:));title('纵向速度估计误差');grid on;subplot(3,1,2);plot(t,errors(2,:));title('横向速度估计误差');grid on;subplot(3,1,3);plot(t,errors(3,:));title('横摆角速度估计误差');grid on;% 计算并显示均方根误差(RMSE)rmse_vx=sqrt(mean(errors(1,:).^2));rmse_vy=sqrt(mean(errors(2,:).^2));rmse_r=sqrt(mean(errors(3,:).^2));fprintf('纵向速度估计RMSE: %.4f m/s\n',rmse_vx);fprintf('横向速度估计RMSE: %.4f m/s\n',rmse_vy);fprintf('横摆角速度估计RMSE: %.4f rad/s\n',rmse_r);%% 车辆动力学模型函数functionx_next=vehicle_dynamics(x,u,m,Iz,lf,lr,Cf,Cr,dt)% 三自由度车辆模型动力学% 状态: x = [vx, vy, r]% 输入: u = [delta, Fx]vx=x(1);vy=x(2);r=x(3);delta=u(1);Fx=u(2);% 计算轮胎侧偏角alpha_f=atan2(vy+lf*r,vx)-delta;alpha_r=atan2(vy-lr*r,vx);% 计算轮胎侧向力Fyf=-Cf*alpha_f;Fyr=-Cr*alpha_r;% 动力学方程vx_dot=(Fx-Fyf*sin(delta))/m+vy*r;vy_dot=(Fyf*cos(delta)+Fyr)/m-vx*r;r_dot=(lf*Fyf*cos(delta)-lr*Fyr)/Iz;% 欧拉积分x_next=x+[vx_dot;vy_dot;r_dot]*dt;end%% 预测步骤函数function[x_pred,F]=predict(x,u,m,Iz,lf,lr,Cf,Cr,dt)% 使用非线性模型进行状态预测% 并计算状态转移雅可比矩阵Fvx=x(1);vy=x(2);r=x(3);delta=u(1);Fx=u(2);% 计算轮胎侧偏角alpha_f=atan2(vy+lf*r,vx)-delta;alpha_r=atan2(vy-lr*r,vx);% 计算轮胎侧向力Fyf=-Cf*alpha_f;Fyr=-Cr*alpha_r;% 动力学方程vx_dot=(Fx-Fyf*sin(delta))/m+vy*r;vy_dot=(Fyf*cos(delta)+Fyr)/m-vx*r;r_dot=(lf*Fyf*cos(delta)-lr*Fyr)/Iz;% 状态预测x_pred=x+[vx_dot;vy_dot;r_dot]*dt;% 计算状态转移雅可比矩阵F% 这里使用数值方法计算雅可比矩阵epsilon=1e-6;F=zeros(3,3);fori=1:3x_plus=x;x_plus(i)=x_plus(i)+epsilon;x_minus=x;x_minus(i)=x_minus(i)-epsilon;f_plus=vehicle_dynamics(x_plus,u,m,Iz,lf,lr,Cf,Cr,dt);f_minus=vehicle_dynamics(x_minus,u,m,Iz,lf,lr,Cf,Cr,dt);F(:,i)=(f_plus-f_minus)/(2*epsilon);endend%% 测量模型函数functionz=measure(x)% 测量模型 - 假设我们可以直接测量所有状态% 在实际应用中,可能需要使用传感器模型z=x;end%% 测量模型雅可比矩阵函数function[z_pred,H]=measurement_model(x)% 测量模型及其雅可比矩阵% 假设直接测量所有状态,所以H是单位矩阵z_pred=x;H=eye(3);end

说明

这个程序实现了一个基于扩展卡尔曼滤波(EKF)的三自由度车辆状态估计器,主要包括以下部分:

1. 车辆模型

三自由度车辆模型包括:

  • 纵向速度(vx)
  • 横向速度(vy)
  • 横摆角速度®

模型考虑了:

  • 轮胎侧偏特性
  • 前轮转向角输入
  • 驱动力输入

2. 扩展卡尔曼滤波实现

EKF分为两个主要步骤:

预测步骤
  • 使用非线性车辆模型预测状态
  • 计算状态转移雅可比矩阵(使用数值方法)
更新步骤
  • 使用测量值更新状态估计
  • 计算卡尔曼增益
  • 更新估计误差协方差矩阵

3. 仿真设置

  • 使用正弦波作为转向输入
  • 添加过程噪声和测量噪声
  • 比较真实状态、估计状态和测量值

4. 结果分析

程序绘制了以下结果:

  • 状态估计与真实值的比较
  • 创新序列(应表现为零均值白噪声)
  • 估计误差
  • 计算并显示均方根误差(RMSE)

参考代码 应用于三自由度车辆模型的扩展卡尔曼滤波程序www.3dddown.com/csa/54787.html

使用

  1. 运行程序即可看到仿真结果
  2. 可以调整车辆参数以适应不同的车辆类型
  3. 可以修改噪声参数以模拟不同的传感器性能
  4. 可以修改控制输入以模拟不同的驾驶场景
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 7:30:46

自动驾驶—CARLA仿真(3) 坐标和坐标变换

官方文档 全局坐标系 CARLA 基于 Unreal Engine 4.26 构建&#xff0c;采用与之相同的左手坐标系。更多关于 Unreal Engine 坐标系的细节&#xff0c;请参阅 Unreal Engine 官方文档。 对于站在原点、面朝 X 轴正方向 的观察者&#xff0c;坐标轴关系如下&#xff1a; Z 轴…

作者头像 李华
网站建设 2026/4/22 2:00:37

Android 渲染(一):刷新机制

概念 硬件 CPU&#xff1a;三大绘制流程中Surface的计算。GPU&#xff1a;以SurfaceFlinger服务的形式工作&#xff0c;将CPU计算好的Surface数据合成后放到buffer中&#xff0c;让显示器进行读取屏幕刷新率&#xff1a;屏幕在1s内去buffer中取数据的次数&#xff0c;单位为HZ。…

作者头像 李华
网站建设 2026/4/30 21:20:28

comfyui基础操作

comfyui基础操作1. ComfyUI SeedVR2新旧插件共存解决方案1. ComfyUI SeedVR2新旧插件共存解决方案 ComfyUI SeedVR2新旧插件共存解决方案

作者头像 李华
网站建设 2026/4/18 6:51:58

在Apple Silicon Mac上运行iOS应用的终极指南:PlayCover完全配置手册

在Apple Silicon Mac上运行iOS应用的终极指南&#xff1a;PlayCover完全配置手册 【免费下载链接】PlayCover Community fork of PlayCover 项目地址: https://gitcode.com/gh_mirrors/pl/PlayCover 想要在Mac上畅玩原神、体验抖音&#xff0c;或是使用iOS专属应用吗&am…

作者头像 李华
网站建设 2026/4/22 4:43:15

MinerU软件版本升级完全指南:实现平滑系统迁移

MinerU软件版本升级完全指南&#xff1a;实现平滑系统迁移 【免费下载链接】MinerU A high-quality tool for convert PDF to Markdown and JSON.一站式开源高质量数据提取工具&#xff0c;将PDF转换成Markdown和JSON格式。 项目地址: https://gitcode.com/GitHub_Trending/m…

作者头像 李华