// Performs a Kalman update on track using measurement and overwrites track with new estimate public void UpdateTrack(GaussianTrack track, GaussianMeasurement measurement) { // Predict track forward to measurement time and add process noise Matrix Q = processNoiseModel.Evaluate(track.gaussianVector.mean, track.dateTime, measurement.dateTime); GaussianVector predictedGaussianVector = track.CoastTrack(stateTransitionModel, measurement.dateTime); predictedGaussianVector.covariance += Q; // Compute residual mean / covariance Vector hx; Matrix H; Coordinate.Convert(new Vector(6), Coordinate.Type.UNITY6, predictedGaussianVector.mean, measurement.creatorUnityReference, measurement.coordinateType, out hx, out H); // Compute innovation and Kalman gain Vector y = measurement.gaussianVector.mean - hx; Matrix HT = H.Clone(); HT.Transpose(); Matrix S = H * predictedGaussianVector.covariance * HT + measurement.gaussianVector.covariance; Matrix K = S.SolveTranspose(predictedGaussianVector.covariance * HT); K.Transpose(); //Matrix K = (predictedGaussianVector.covariance * HT)*S.Inverse(); // Update state estimate int N = predictedGaussianVector.mean.Length; predictedGaussianVector.covariance = (Matrix.Identity(N,N) - K*H) * predictedGaussianVector.covariance; // Problem predictedGaussianVector.mean = predictedGaussianVector.mean + (K * y.ToColumnMatrix()).GetColumnVector(0); // Write to the track track.gaussianVector = predictedGaussianVector; track.dateTime = measurement.dateTime; }
// Compare against result of chi2inv(p,3) where p represents desired probability for test private double Compute3DimChiSquareDistance(GaussianMeasurement measurement, GaussianTrack track) { // Coast track to measurement time using state transition model GaussianVector coastedTrack = track.CoastTrack(fusionEngine.stateTransitionModel, measurement.dateTime); // Only take 3 dimensional components of coasted track Vector coastedMean = VectorUtilities.Resize(coastedTrack.mean,3); Matrix coastedCovariance = VectorUtilities.Resize(coastedTrack.covariance,3,3); // Convert measurement to UNITY (track) 3 dimensional coordinates Vector convMeasurementMean; Matrix convMeasurementJacobian; Coordinate.Convert(measurement.creatorUnityReference, measurement.coordinateType, measurement.gaussianVector.mean, new Vector(3), Coordinate.Type.UNITY3, out convMeasurementMean, out convMeasurementJacobian); Matrix convMeasurementJacobianT = convMeasurementJacobian.Clone(); convMeasurementJacobianT.Transpose(); Matrix convMeasurementCovariance = convMeasurementJacobian * measurement.gaussianVector.covariance * convMeasurementJacobianT; // Compute 3 dimensional chi-square metric Matrix meanDisplacement = (coastedMean - convMeasurementMean).ToColumnMatrix(); Matrix meanDisplacementT = meanDisplacement.Clone(); meanDisplacementT.Transpose(); return (meanDisplacementT*((coastedCovariance + convMeasurementCovariance).Solve(meanDisplacement)))[0,0]; }