FuseMagnetometer.m 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. function [...
  2. states, ... % state vector after fusion of measurements
  3. P, ... % state covariance matrix after fusion of corrections
  4. innovation, ... % Declination innovation - rad
  5. varInnov] ... %
  6. = FuseMagnetometer( ...
  7. states, ... % predicted states
  8. P, ... % predicted covariance
  9. magData, ... % body frame magnetic flux measurements
  10. measDec, ... % magnetic field declination - azimuth angle measured from true north (rad)
  11. Tbn) % Estimated coordinate transformation matrix from body to NED frame
  12. q0 = states(1);
  13. q1 = states(2);
  14. q2 = states(3);
  15. q3 = states(4);
  16. magX = magData(1);
  17. magY = magData(2);
  18. magZ = magData(3);
  19. R_MAG = 0.05^2;
  20. H = calcH_MAG(magX,magY,magZ,q0,q1,q2,q3);
  21. varInnov = (H*P*transpose(H) + R_MAG);
  22. Kfusion = (P*transpose(H))/varInnov;
  23. % Calculate the predicted magnetic declination
  24. magMeasNED = Tbn*[magX;magY;magZ];
  25. predDec = atan2(magMeasNED(2),magMeasNED(1));
  26. % Calculate the measurement innovation
  27. innovation = predDec - measDec;
  28. % correct the state vector
  29. states = states - Kfusion * innovation;
  30. % re-normalise the quaternion
  31. quatMag = sqrt(states(1)^2 + states(2)^2 + states(3)^2 + states(4)^2);
  32. states(1:4) = states(1:4) / quatMag;
  33. % correct the covariance P = P - K*H*P
  34. P = P - Kfusion*H*P;
  35. % Force symmetry on the covariance matrix to prevent ill-conditioning
  36. % of the matrix which would cause the filter to blow-up
  37. P = 0.5*(P + transpose(P));
  38. % ensure diagonals are positive
  39. for i=1:10
  40. if P(i,i) < 0
  41. P(i,i) = 0;
  42. end
  43. end
  44. end