@@ -16,7 +16,7 @@ function init_estimate_cov!(estim::MovingHorizonEstimator, _ , d0, u0)
1616 estim. D0[1 : estim. model. nd] .= d0
1717 end
1818 # estim.P̂_0 is in fact P̂(-1|-1) is estim.direct==false, else P̂(-1|0)
19- estim. invP̄ . = inv ( estim. P̂_0)
19+ invert_cov! ( estim, estim. P̂_0)
2020 estim. P̂arr_old .= estim. P̂_0
2121 estim. x̂0arr_old .= 0
2222 return nothing
@@ -433,9 +433,21 @@ function correct_cov!(estim::MovingHorizonEstimator)
433433 y0marr, d0arr = @views estim. Y0m[1 : nym], estim. D0[1 : nd]
434434 estim. covestim. x̂0 .= estim. x̂0arr_old
435435 estim. covestim. P̂ .= estim. P̂arr_old
436- correct_estimate! (estim. covestim, y0marr, d0arr)
437- estim. P̂arr_old .= estim. covestim. P̂
438- estim. invP̄ .= inv (estim. P̂arr_old)
436+ try
437+ correct_estimate! (estim. covestim, y0marr, d0arr)
438+ catch err
439+ if err isa PosDefException
440+ @warn (" Arrival covariance not positive definite: using nearest symmetric one" )
441+ estim. covestim. P̂ .= estim. P̂arr_old .+ estim. P̂arr_old'
442+ lmul! (0.5 , estim. covestim. P̂)
443+ correct_estimate! (estim. covestim, y0marr, d0arr)
444+ else
445+ rethrow (err)
446+ end
447+ end
448+ P̄ = estim. covestim. P̂
449+ invert_cov! (estim, P̄)
450+ estim. P̂arr_old .= P̄
439451 return nothing
440452end
441453
@@ -445,9 +457,35 @@ function update_cov!(estim::MovingHorizonEstimator)
445457 u0arr, y0marr, d0arr = @views estim. U0[1 : nu], estim. Y0m[1 : nym], estim. D0[1 : nd]
446458 estim. covestim. x̂0 .= estim. x̂0arr_old
447459 estim. covestim. P̂ .= estim. P̂arr_old
448- update_estimate! (estim. covestim, y0marr, d0arr, u0arr)
449- estim. P̂arr_old .= estim. covestim. P̂
450- estim. invP̄ .= inv (estim. P̂arr_old)
460+ try
461+ update_estimate! (estim. covestim, y0marr, d0arr, u0arr)
462+ catch err
463+ if err isa PosDefException
464+ @warn (" Arrival covariance not positive definite: using nearest symmetric one" )
465+ estim. covestim. P̂ .= estim. P̂arr_old .+ estim. P̂arr_old'
466+ lmul! (0.5 , estim. covestim. P̂)
467+ update_estimate! (estim. covestim, y0marr, d0arr, u0arr)
468+ else
469+ rethrow (err)
470+ end
471+ end
472+ P̄ = estim. covestim. P̂
473+ invert_cov! (estim, P̄)
474+ estim. P̂arr_old .= P̄
475+ return nothing
476+ end
477+
478+ " Invert the covariance estimate at arrival `P̄`."
479+ function invert_cov! (estim:: MovingHorizonEstimator , P̄)
480+ try
481+ estim. invP̄ .= inv (P̄)
482+ catch err
483+ if err isa SingularException
484+ @warn (" Arrival covariance not invertible: using pseudo-inverse" )
485+ estim. invP̄ .= pinv (P̄)
486+ else
487+ rethrow (err)
488+ end
451489 return nothing
452490end
453491
0 commit comments