%%This script converts application specific IMU models into a standard
%%format that can be used by sys_model scripts.
%%Do not change the existing models!!!!!.
%%Whenever you need an additional model, just define a new imutype and add
%%it to this script.
%%SEE also the notes in "imu_err_defs_v000"
function [Ad, Qd, C, R]=imu_err_model(acc, gyro, dt, imutype)
%%imu output model
%%x'=Ax+w, y=[acc;gyro]'+Cx+v, where <w,w>=Q, <v,v>=R
%%x(k+1)=Ad.x(k)+w(k) <w(k),w(k)>=Qd
%Note that the returning system model(Ad,Qd) is in discrete time, whereas the
%bservation model (C,R) is in continuous time
%load continuous time parameters
IMU_ERRDEF=imu_err_defs_v000(imutype);
if imutype==0 %dummy to obtain nav system model from sys_XXX scripts
Ad=[];
Qd=[];
C=[];
R=zeros(6);
elseif ismember(imutype, [1,2,3])
%Imu error states
%1-3:Acc bias
%4-6:gyro bias
%7-9:Acc scale (ppt=part per thousand not million). ppm def can sometimes
%causes numerical problems
%10-12:Gyro scale
%Discrete time model of imu error states
acc_bias_a=exp(-dt/IMU_ERRDEF.acc_bias_Tc);
acc_bias_w=IMU_ERRDEF.acc_bias_Tc*(IMU_ERRDEF.acc_bias_Q)/2*(1-acc_bias_a^2); %(m/s^2)^2 (*s^2)
gyro_bias_a=exp(-dt/IMU_ERRDEF.gyro_bias_Tc);
gyro_bias_w=IMU_ERRDEF.gyro_bias_Tc*(IMU_ERRDEF.gyro_bias_Q)/2*(1-gyro_bias_a^2); %(rad/sec)^2 (*s^2)
acc_scale_a=1;
acc_scale_w=IMU_ERRDEF.acc_scale_Q*dt; %ppt^2 (*s^2)
gyro_scale_a=1;
gyro_scale_w=IMU_ERRDEF.acc_scale_Q*dt; %(ppt)^2 (*s^2)
Ad=diag([acc_bias_a, acc_bias_a, acc_bias_a, gyro_bias_a, gyro_bias_a, gyro_bias_a, acc_scale_a, acc_scale_a, acc_scale_a, gyro_scale_a, gyro_scale_a, gyro_scale_a]);
Qd=diag([acc_bias_w, acc_bias_w, acc_bias_w, gyro_bias_w, gyro_bias_w, gyro_bias_w, acc_scale_w, acc_scale_w, acc_scale_w, gyro_scale_w, gyro_scale_w, gyro_scale_w]);
%Continuous time output model for the imu [acc;gyro]
C=[eye(6), diag([acc(1),acc(2),acc(3),gyro(1),gyro(2),gyro(3)]/1000)];
R=diag([IMU_ERRDEF.acc_vrw;IMU_ERRDEF.acc_vrw;IMU_ERRDEF.acc_vrw;IMU_ERRDEF.gyro_arw;IMU_ERRDEF.gyro_arw;IMU_ERRDEF.gyro_arw]);
elseif ismember(imutype, 4)
%Imu error states
%1-3:Acc bias
%4-6:gyro bias
acc_bias_a=exp(dt*IMU_ERRDEF.Acc.A);
gyro_bias_a=exp(dt*IMU_ERRDEF.Gyro.A);
acc_bias_w=IMU_ERRDEF.Acc.Q/(-IMU_ERRDEF.Acc.A*2)*(1-acc_bias_a^2); %(m/s^2)^2 (*s^2)
gyro_bias_w=IMU_ERRDEF.Gyro.Q/(-IMU_ERRDEF.Gyro.A*2)*(1-gyro_bias_a^2); %(m/s^2)^2 (*s^2)
Ad=diag([ones(1,3)*acc_bias_a, ones(1,3)*gyro_bias_a]);
Qd=diag([ones(1,3)*acc_bias_w, ones(1,3)*gyro_bias_w]);
C=eye(6);
R=diag([ones(1,3)*IMU_ERRDEF.Acc.R, ones(1,3)*IMU_ERRDEF.Gyro.R]);
else
disp('sys_metric_phipsi: IMUTYPE is not defined');
end
end