123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- 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
|