@@ -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
@@ -108,8 +108,7 @@ function getinfo(estim::MovingHorizonEstimator{NT}) where NT<:Real
108108 nu, ny, nd = model. nu, model. ny, model. nd
109109 nx̂, nym, nŵ, nϵ = estim. nx̂, estim. nym, estim. nx̂, estim. nϵ
110110 nx̃ = nϵ + nx̂
111- MyTypes = Union{JuMP. _SolutionSummary, Hermitian{NT, Matrix{NT}}, Vector{NT}, NT}
112- info = Dict {Symbol, MyTypes} ()
111+ info = Dict {Symbol, Any} ()
113112 V̂, X̂0 = similar (estim. Y0m[1 : nym* Nk]), similar (estim. X̂0[1 : nx̂* Nk])
114113 û0, ŷ0 = similar (model. uop), similar (model. yop)
115114 V̂, X̂0 = predict! (V̂, X̂0, û0, ŷ0, estim, model, estim. Z̃)
@@ -370,7 +369,8 @@ If supported by `estim.optim`, it warm-starts the solver at:
370369where ``\m athbf{ŵ}_{k-1}(k-j)`` is the input increment for time ``k-j`` computed at the
371370last time step ``k-1``. It then calls `JuMP.optimize!(estim.optim)` and extract the
372371solution. A failed optimization prints an `@error` log in the REPL and returns the
373- warm-start value.
372+ warm-start value. A failed optimization also prints [`getinfo`](@ref) results in
373+ the debug log [if activated](https://docs.julialang.org/en/v1/stdlib/Logging/#Example:-Enable-debug-level-messages).
374374"""
375375function optim_objective! (estim:: MovingHorizonEstimator{NT} ) where NT<: Real
376376 model, optim = estim. model, estim. optim
@@ -406,13 +406,19 @@ function optim_objective!(estim::MovingHorizonEstimator{NT}) where NT<:Real
406406 if ! issolved (optim)
407407 status = JuMP. termination_status (optim)
408408 if iserror (optim)
409- @error (" MHE terminated without solution: estimation in open-loop" ,
410- status)
409+ @error (
410+ " MHE terminated without solution: estimation in open-loop " *
411+ " (more info in debug log)" ,
412+ status
413+ )
411414 else
412- @warn (" MHE termination status not OPTIMAL or LOCALLY_SOLVED: keeping " *
413- " solution anyway" , status)
415+ @warn (
416+ " MHE termination status not OPTIMAL or LOCALLY_SOLVED: keeping solution " *
417+ " anyway (more info in debug log)" ,
418+ status
419+ )
414420 end
415- @debug JuMP . solution_summary (optim, verbose = true )
421+ @debug info2debugstr ( getinfo (estim) )
416422 end
417423 if iserror (optim)
418424 estim. Z̃ .= Z̃_0
@@ -433,9 +439,17 @@ function correct_cov!(estim::MovingHorizonEstimator)
433439 y0marr, d0arr = @views estim. Y0m[1 : nym], estim. D0[1 : nd]
434440 estim. covestim. x̂0 .= estim. x̂0arr_old
435441 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)
442+ try
443+ correct_estimate! (estim. covestim, y0marr, d0arr)
444+ estim. P̂arr_old .= estim. covestim. P̂
445+ invert_cov! (estim, estim. P̂arr_old)
446+ catch err
447+ if err isa PosDefException
448+ @warn (" Arrival covariance is not positive definite: keeping the old one" )
449+ else
450+ rethrow ()
451+ end
452+ end
439453 return nothing
440454end
441455
@@ -445,9 +459,31 @@ function update_cov!(estim::MovingHorizonEstimator)
445459 u0arr, y0marr, d0arr = @views estim. U0[1 : nu], estim. Y0m[1 : nym], estim. D0[1 : nd]
446460 estim. covestim. x̂0 .= estim. x̂0arr_old
447461 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)
462+ try
463+ update_estimate! (estim. covestim, y0marr, d0arr, u0arr)
464+ estim. P̂arr_old .= estim. covestim. P̂
465+ invert_cov! (estim, estim. P̂arr_old)
466+ catch err
467+ if err isa PosDefException
468+ @warn (" Arrival covariance is not positive definite: keeping the old one" )
469+ else
470+ rethrow ()
471+ end
472+ end
473+ return nothing
474+ end
475+
476+ " Invert the covariance estimate at arrival `P̄`."
477+ function invert_cov! (estim:: MovingHorizonEstimator , P̄)
478+ try
479+ estim. invP̄ .= inv_cholesky! (estim. buffer. P̂, P̄)
480+ catch err
481+ if err isa PosDefException
482+ @warn (" Arrival covariance is not invertible: keeping the old one" )
483+ else
484+ rethrow ()
485+ end
486+ end
451487 return nothing
452488end
453489
0 commit comments