用matlab写一段仿真INS与GPS组合导航系统的代码
时间: 2024-05-01 13:20:09 浏览: 98
以下是一段简单的MATLAB代码,用于模拟INS与GPS组合导航系统:
```matlab
clc;
clear all;
close all;
%定义常量
R2D = 180/pi;
D2R = pi/180;
g = 9.81;
%定义模拟时间和时间步长
time_final = 100; %总时间
delta_t = 0.1; %时间步长
time = 0:delta_t:time_final; %时间向量
%定义模拟初始状态
lat0 = 39.9*D2R;
lon0 = 116.3*D2R;
h0 = 0;
Vn0 = 10;
Ve0 = 0;
Vd0 = 0;
phi0 = 0;
theta0 = 0;
psi0 = 0*D2R;
p0 = 0;
q0 = 0;
r0 = 0;
x0 = [lat0 lon0 h0 Vn0 Ve0 Vd0 phi0 theta0 psi0 p0 q0 r0]';
%定义GPS传感器误差
sigma_gps = 5; %GPS定位误差,单位:米
%定义INS传感器误差
sigma_gyro = 0.1; %陀螺仪测量误差,单位:度/秒
sigma_accel = 0.1; %加速度计测量误差,单位:m/s^2
%定义GPS数据
gps_data = zeros(6,length(time));
for i=1:length(time)
gps_data(1:3,i) = [lat0 lon0 h0]' + sigma_gps*randn(3,1);
gps_data(4:6,i) = [Vn0 Ve0 Vd0]' + sigma_gps*randn(3,1);
end
%定义INS数据
ins_data = zeros(12,length(time));
ins_data(:,1) = [x0; zeros(3,1)];
for i=2:length(time)
%计算加速度计和陀螺仪的测量值
accel_meas = [Vd0 + g*sin(theta0);
-Ve0*Vd0/(Re+h0) - g*cos(theta0)*sin(phi0);
Vn0*Vd0/(Re+h0) - g*cos(theta0)*cos(phi0)] + sigma_accel*randn(3,1);
gyro_meas = [p0 + sigma_gyro*randn(1,1);
q0 + sigma_gyro*randn(1,1);
r0 + sigma_gyro*randn(1,1)];
%计算INS状态更新
x_prev = ins_data(:,i-1);
f = @(t,x)ins_equations(t,x,accel_meas,gyro_meas);
[~,x] = ode45(f,[0 delta_t],x_prev);
ins_data(:,i) = x(end,:)';
%计算INS和GPS数据融合
if mod(i,10) == 0 %每10个时间步更新一次GPS数据
ins_pos = [ins_data(1,i) ins_data(2,i) ins_data(3,i)];
ins_vel = [ins_data(4,i) ins_data(5,i) ins_data(6,i)];
gps_pos = gps_data(1:3,i)';
gps_vel = gps_data(4:6,i)';
[lat,lon,h,Vn,Ve,Vd,phi,theta,psi,p,q,r] = ins_gps_fusion(ins_pos,ins_vel,gps_pos,gps_vel);
ins_data(1:3,i) = [lat lon h]';
ins_data(4:6,i) = [Vn Ve Vd]';
ins_data(7:9,i) = [phi theta psi]';
ins_data(10:12,i) = [p q r]';
end
end
%绘制INS和GPS数据
figure;
subplot(3,1,1);
plot(time,ins_data(1,:)*R2D,'b',time,gps_data(1,:)*R2D,'r');
xlabel('Time (s)');
ylabel('Latitude (deg)');
legend('INS','GPS');
title('INS and GPS Data');
grid on;
subplot(3,1,2);
plot(time,ins_data(2,:)*R2D,'b',time,gps_data(2,:)*R2D,'r');
xlabel('Time (s)');
ylabel('Longitude (deg)');
legend('INS','GPS');
grid on;
subplot(3,1,3);
plot(time,ins_data(3,:),'b',time,gps_data(3,:),'r');
xlabel('Time (s)');
ylabel('Altitude (m)');
legend('INS','GPS');
grid on;
```
其中,INS方程和INS-GPS融合方程可以通过以下代码实现:
```matlab
function xdot = ins_equations(t,x,accel_meas,gyro_meas)
%INS方程
%输入:
%x:当前状态向量,包括纬度、经度、高度、北向速度、东向速度、下向速度、俯仰角、横滚角、偏航角、角速度
%accel_meas:加速度计测量值
%gyro_meas:陀螺仪测量值
%输出:
%xdot:状态变化率
%定义常量
R2D = 180/pi;
D2R = pi/180;
g = 9.81;
Re = 6378137;
%提取状态向量
lat = x(1);
lon = x(2);
h = x(3);
Vn = x(4);
Ve = x(5);
Vd = x(6);
phi = x(7);
theta = x(8);
psi = x(9);
p = x(10);
q = x(11);
r = x(12);
%计算地球曲率半径
Rn = Re / sqrt(1 - 0.00669437999014*sin(lat)^2);
Rm = Re * (1 - 0.00669437999014) / (1 - 0.00669437999014*sin(lat)^2)^1.5;
%计算加速度计和陀螺仪测量误差
accel_meas_error = 0.1 * randn(3,1);
gyro_meas_error = 0.1 * randn(3,1);
%计算加速度计和陀螺仪测量值
accel = [Vd + g*sin(theta) + accel_meas(1);
(-Ve*Vd/(Rn+h) + g*cos(theta)*sin(phi) + accel_meas(2)) / cos(lat);
(Vn*Vd/(Rm+h) + g*cos(theta)*cos(phi) + accel_meas(3)) / cos(lat)];
gyro = [p + gyro_meas(1);
q + gyro_meas(2)*cos(phi) + gyro_meas(3)*sin(phi);
(q*sin(phi) - r*cos(phi)) / cos(theta) + gyro_meas(2)*sin(phi)*tan(theta) + gyro_meas(3)*cos(phi)*tan(theta)];
%计算状态变化率
xdot = zeros(12,1);
xdot(1) = Vn / (Rm + h);
xdot(2) = Ve / (Rn + h) / cos(lat);
xdot(3) = -Vd;
xdot(4) = accel(1);
xdot(5) = accel(2);
xdot(6) = accel(3);
xdot(7) = p + (q*sin(phi) + r*cos(phi)) * tan(theta);
xdot(8) = q*cos(phi) - r*sin(phi);
xdot(9) = (q*sin(phi) + r*cos(phi)) / cos(theta);
xdot(10) = gyro(1);
xdot(11) = gyro(2);
xdot(12) = gyro(3);
end
function [lat,lon,h,Vn,Ve,Vd,phi,theta,psi,p,q,r] = ins_gps_fusion(ins_pos,ins_vel,gps_pos,gps_vel)
%INS-GPS融合方程
%输入:
%ins_pos:INS计算的位置向量,包括纬度、经度、高度
%ins_vel:INS计算的速度向量,包括北向速度、东向速度、下向速度
%gps_pos:GPS测量的位置向量,包括纬度、经度、高度
%gps_vel:GPS测量的速度向量,包括北向速度、东向速度、下向速度
%输出:
%lat:融合后的纬度
%lon:融合后的经度
%h:融合后的高度
%Vn:融合后的北向速度
%Ve:融合后的东向速度
%Vd:融合后的下向速度
%phi:融合后的横滚角
%theta:融合后的俯仰角
%psi:融合后的偏航角
%p:融合后的横滚角速度
%q:融合后的俯仰角速度
%r:融合后的偏航角速度
%定义常量
R2D = 180/pi;
D2R = pi/180;
%计算INS和GPS计算的位置和速度差
pos_diff = gps_pos - ins_pos;
vel_diff = gps_vel - ins_vel;
%计算位置和速度误差权重矩阵
W_pos = diag(1./(10*pos_diff.^2 + 10^2));
W_vel = diag(1./(2*vel_diff.^2 + 2^2));
%计算加权最小二乘解
H = [eye(3) zeros(3)];
v = [pos_diff; vel_diff];
W = [W_pos zeros(3); zeros(3) W_vel];
K = inv(H'*W*H)*H'*W;
dx = K*v;
%计算融合后的状态向量
lat = ins_pos(1) + dx(1);
lon = ins_pos(2) + dx(2) / cos(lat);
h = ins_pos(3) - dx(3);
Vn = ins_vel(1) + dx(4);
Ve = ins_vel(2) + dx(5) / cos(lat);
Vd = ins_vel(3) + dx(6);
phi = 0;
theta = 0;
psi = 0;
p = 0;
q = 0;
r = 0;
end
```
该代码模拟了一个简单的INS与GPS组合导航系统,包括INS的状态更新和INS-GPS数据融合,可以用于学习和测试组合导航算法。
阅读全文