calcEKF.m 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. function [quatOut,angRateBiasOut,logOut,headingAlignedOut] = calcEKF(delAngSlow,delVelSlow,measVel,gPhi,gPsi,gTheta,magMeas,declParam,time,dtSlow,frameIndex,maxFrameIndex)
  2. persistent velocityAligned;
  3. if isempty(velocityAligned)
  4. velocityAligned = 0;
  5. end
  6. persistent quat;
  7. if isempty(quat)
  8. quat = [1;0;0;0];
  9. end
  10. persistent states;
  11. if isempty(states)
  12. states = zeros(9,1);
  13. end
  14. persistent covariance;
  15. if isempty(covariance)
  16. % define the state covariances with the exception of the quaternion covariances
  17. Sigma_velNED = 0.5; % 1 sigma uncertainty in horizontal velocity components
  18. Sigma_dAngBias = 1*pi/180*dtSlow; % 1 Sigma uncertainty in delta angle bias
  19. Sigma_angErr = 1; % 1 Sigma uncertainty in angular misalignment (rad)
  20. covariance = single(diag([Sigma_angErr*[1;1;1];Sigma_velNED*[1;1;1];Sigma_dAngBias*[1;1;1]]).^2);
  21. end
  22. persistent headingAligned
  23. if isempty(headingAligned)
  24. headingAligned = 0;
  25. end
  26. persistent log;
  27. if isempty(log)
  28. % create data logging variables
  29. log.time = zeros(1,maxFrameIndex);
  30. log.states = zeros(9,maxFrameIndex);
  31. log.quat = zeros(4,maxFrameIndex);
  32. log.euler = zeros(3,maxFrameIndex);
  33. log.tiltCorr = zeros(1,maxFrameIndex);
  34. log.velInnov = zeros(3,maxFrameIndex);
  35. log.decInnov = zeros(1,maxFrameIndex);
  36. log.velInnovVar = log.velInnov;
  37. log.decInnovVar = log.decInnov;
  38. end
  39. % predict states
  40. [quat, states, Tsn, delAngCorrected, delVelCorrected] = PredictStates(quat,states,delAngSlow,delVelSlow,dtSlow);
  41. % log state prediction data
  42. log.states(:,frameIndex) = states;
  43. log.quat(:,frameIndex) = quat;
  44. log.euler(:,frameIndex) = QuatToEul(quat);
  45. % predict covariance matrix
  46. covariance = PredictCovarianceOptimised(delAngCorrected,delVelCorrected,quat,states,covariance,dtSlow);
  47. if (velocityAligned == 0)
  48. % initialise velocity states
  49. states(4:6) = measVel;
  50. velocityAligned = 1;
  51. else
  52. % fuse velocity measurements
  53. [quat,states,tiltCorrection,covariance,velInnov,velInnovVar] = FuseVelocity(quat,states,covariance,measVel);
  54. % log velocity fusion data
  55. log.velInnov(:,frameIndex) = velInnov;
  56. log.velInnovVar(:,frameIndex) = velInnovVar;
  57. log.tiltCorr(1,frameIndex) = tiltCorrection;
  58. end
  59. % Align the heading once there has been enough time for the filter to
  60. % settle and the tilt corrections have dropped below a threshold
  61. if (((time > 5.0 && tiltCorrection < 1e-4) || (time > 30.0)) && headingAligned==0)
  62. % calculate the initial heading using magnetometer, gimbal,
  63. % estimated tilt and declination
  64. quat = AlignHeading(gPhi,gPsi,gTheta,Tsn,magMeas,quat,declParam);
  65. headingAligned = 1;
  66. end
  67. % fuse magnetometer measurements and log fusion data
  68. if (headingAligned == 1)
  69. [quat,states,covariance,decInnov,decInnovVar] = FuseMagnetometer(quat,states,covariance,magMeas,declParam,gPhi,gPsi,gTheta);
  70. log.decInnov(:,frameIndex) = decInnov;
  71. log.decInnovVar(:,frameIndex) = decInnovVar;
  72. end
  73. % time stamp the log data
  74. log.time(frameIndex) = time;
  75. % write to the output data
  76. quatOut = quat;
  77. angRateBiasOut = states(7:9)/dtSlow;
  78. logOut = log;
  79. headingAlignedOut = headingAligned;
  80. end