123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- function [...
- quat, ... % quaternion state vector after fusion of measurements
- states, ... % state vector after fusion of measurements
- tiltErr, ... % angle error
- P, ... % state covariance matrix after fusion of corrections
- innovation,... % NED velocity innovations (m/s)
- varInnov] ... % NED velocity innovation variance ((m/s)^2)
- = FuseVelocity( ...
- quat, ... % predicted quaternion states from the INS
- states, ... % predicted states from the INS
- P, ... % predicted covariance
- measVel) % NED velocity measurements (m/s)
- R_OBS = 0.5^2;
- innovation = zeros(1,3);
- varInnov = zeros(1,3);
- % Fuse measurements sequentially
- angErrVec = [0;0;0];
- for obsIndex = 1:3
- stateIndex = 3 + obsIndex;
- % Calculate the velocity measurement innovation
- innovation(obsIndex) = states(stateIndex) - measVel(obsIndex);
-
- % Calculate the Kalman Gain taking advantage of direct state observation
- H = zeros(1,9);
- H(1,stateIndex) = 1;
- varInnov(obsIndex) = P(stateIndex,stateIndex) + R_OBS;
- K = P(:,stateIndex)/varInnov(obsIndex);
-
- % Calculate state corrections
- xk = K * innovation(obsIndex);
-
- % Apply the state corrections
- states(1:3) = 0;
- states = states - xk;
-
- % Store tilt error estimate for external monitoring
- angErrVec = angErrVec + states(1:3);
-
- % the first 3 states represent the angular misalignment vector. This is
- % is used to correct the estimated quaternion
- % Convert the error rotation vector to its equivalent quaternion
- % truth = estimate + error
- rotationMag = sqrt(states(1)^2 + states(2)^2 + states(3)^2);
- if rotationMag > 1e-12
- deltaQuat = [cos(0.5*rotationMag); [states(1);states(2);states(3)]/rotationMag*sin(0.5*rotationMag)];
- % Update the quaternion states by rotating from the previous attitude through
- % the error quaternion
- quat = QuatMult(quat,deltaQuat);
- % re-normalise the quaternion
- quatMag = sqrt(quat(1)^2 + quat(2)^2 + quat(3)^2 + quat(4)^2);
- quat = quat / quatMag;
- end
-
- % Update the covariance
- P = P - K*P(stateIndex,:);
-
- % Force symmetry on the covariance matrix to prevent ill-conditioning
- P = 0.5*(P + transpose(P));
-
- % ensure diagonals are positive
- for i=1:9
- if P(i,i) < 0
- P(i,i) = 0;
- end
- end
-
- end
- tiltErr = sqrt(dot(angErrVec(1:2),angErrVec(1:2)));
- end
|