You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
3.1 KiB
96 lines
3.1 KiB
function [quatOut,angRateBiasOut,logOut,headingAlignedOut] = calcEKF(delAngSlow,delVelSlow,measVel,gPhi,gPsi,gTheta,magMeas,declParam,time,dtSlow,frameIndex,maxFrameIndex) |
|
|
|
persistent velocityAligned; |
|
if isempty(velocityAligned) |
|
velocityAligned = 0; |
|
end |
|
|
|
persistent quat; |
|
if isempty(quat) |
|
quat = [1;0;0;0]; |
|
end |
|
|
|
persistent states; |
|
if isempty(states) |
|
states = zeros(9,1); |
|
end |
|
|
|
persistent covariance; |
|
if isempty(covariance) |
|
% define the state covariances with the exception of the quaternion covariances |
|
Sigma_velNED = 0.5; % 1 sigma uncertainty in horizontal velocity components |
|
Sigma_dAngBias = 1*pi/180*dtSlow; % 1 Sigma uncertainty in delta angle bias |
|
Sigma_angErr = 1; % 1 Sigma uncertainty in angular misalignment (rad) |
|
covariance = single(diag([Sigma_angErr*[1;1;1];Sigma_velNED*[1;1;1];Sigma_dAngBias*[1;1;1]]).^2); |
|
end |
|
|
|
persistent headingAligned |
|
if isempty(headingAligned) |
|
headingAligned = 0; |
|
end |
|
|
|
persistent log; |
|
if isempty(log) |
|
% create data logging variables |
|
log.time = zeros(1,maxFrameIndex); |
|
log.states = zeros(9,maxFrameIndex); |
|
log.quat = zeros(4,maxFrameIndex); |
|
log.euler = zeros(3,maxFrameIndex); |
|
log.tiltCorr = zeros(1,maxFrameIndex); |
|
log.velInnov = zeros(3,maxFrameIndex); |
|
log.decInnov = zeros(1,maxFrameIndex); |
|
log.velInnovVar = log.velInnov; |
|
log.decInnovVar = log.decInnov; |
|
end |
|
|
|
% predict states |
|
[quat, states, Tsn, delAngCorrected, delVelCorrected] = PredictStates(quat,states,delAngSlow,delVelSlow,dtSlow); |
|
|
|
% log state prediction data |
|
log.states(:,frameIndex) = states; |
|
log.quat(:,frameIndex) = quat; |
|
log.euler(:,frameIndex) = QuatToEul(quat); |
|
|
|
% predict covariance matrix |
|
covariance = PredictCovarianceOptimised(delAngCorrected,delVelCorrected,quat,states,covariance,dtSlow); |
|
|
|
if (velocityAligned == 0) |
|
% initialise velocity states |
|
states(4:6) = measVel; |
|
velocityAligned = 1; |
|
else |
|
% fuse velocity measurements |
|
[quat,states,tiltCorrection,covariance,velInnov,velInnovVar] = FuseVelocity(quat,states,covariance,measVel); |
|
% log velocity fusion data |
|
log.velInnov(:,frameIndex) = velInnov; |
|
log.velInnovVar(:,frameIndex) = velInnovVar; |
|
log.tiltCorr(1,frameIndex) = tiltCorrection; |
|
end |
|
|
|
|
|
% Align the heading once there has been enough time for the filter to |
|
% settle and the tilt corrections have dropped below a threshold |
|
if (((time > 5.0 && tiltCorrection < 1e-4) || (time > 30.0)) && headingAligned==0) |
|
% calculate the initial heading using magnetometer, gimbal, |
|
% estimated tilt and declination |
|
quat = AlignHeading(gPhi,gPsi,gTheta,Tsn,magMeas,quat,declParam); |
|
headingAligned = 1; |
|
end |
|
|
|
% fuse magnetometer measurements and log fusion data |
|
if (headingAligned == 1) |
|
[quat,states,covariance,decInnov,decInnovVar] = FuseMagnetometer(quat,states,covariance,magMeas,declParam,gPhi,gPsi,gTheta); |
|
log.decInnov(:,frameIndex) = decInnov; |
|
log.decInnovVar(:,frameIndex) = decInnovVar; |
|
end |
|
|
|
% time stamp the log data |
|
log.time(frameIndex) = time; |
|
|
|
% write to the output data |
|
quatOut = quat; |
|
angRateBiasOut = states(7:9)/dtSlow; |
|
logOut = log; |
|
headingAlignedOut = headingAligned; |
|
|
|
end |