Skip to content

Commit 532223f

Browse files
committed
added: testing the MovingHorizonEstimator fallbacks
1 parent 0e60f54 commit 532223f

File tree

3 files changed

+38
-18
lines changed

3 files changed

+38
-18
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ModelPredictiveControl"
22
uuid = "61f9bdb8-6ae4-484a-811f-bbf86720c31c"
33
authors = ["Francis Gagnon"]
4-
version = "1.2.0"
4+
version = "1.2.1"
55

66
[deps]
77
ControlSystemsBase = "aaaaaaaa-a6ca-5380-bf3e-84a91bcd477e"

src/estimator/mhe/execute.jl

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -435,19 +435,15 @@ function correct_cov!(estim::MovingHorizonEstimator)
435435
estim.covestim.P̂ .= estim.P̂arr_old
436436
try
437437
correct_estimate!(estim.covestim, y0marr, d0arr)
438+
estim.P̂arr_old .= estim.covestim.
439+
invert_cov!(estim, estim.covestim.P̂)
438440
catch err
439441
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)
442+
@warn("Arrival covariance is not positive definite: keeping the old one")
444443
else
445444
rethrow(err)
446445
end
447446
end
448-
= estim.covestim.
449-
invert_cov!(estim, P̄)
450-
estim.P̂arr_old .=
451447
return nothing
452448
end
453449

@@ -458,20 +454,16 @@ function update_cov!(estim::MovingHorizonEstimator)
458454
estim.covestim.x̂0 .= estim.x̂0arr_old
459455
estim.covestim.P̂ .= estim.P̂arr_old
460456
try
461-
update_estimate!(estim.covestim, y0marr, d0arr, u0arr)
457+
correct_estimate!(estim.covestim, y0marr, d0arr)
458+
estim.P̂arr_old .= estim.covestim.
459+
invert_cov!(estim, estim.covestim.P̂)
462460
catch err
463461
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)
462+
@warn("Arrival covariance is not positive definite: keeping the old one")
468463
else
469464
rethrow(err)
470465
end
471466
end
472-
= estim.covestim.
473-
invert_cov!(estim, P̄)
474-
estim.P̂arr_old .=
475467
return nothing
476468
end
477469

@@ -481,8 +473,7 @@ function invert_cov!(estim::MovingHorizonEstimator, P̄)
481473
estim.invP̄ .= inv(P̄)
482474
catch err
483475
if err isa SingularException
484-
@warn("Arrival covariance is singular: adding small regularization term")
485-
estim.invP̄ .= inv(P̄ + eps()*I)
476+
@warn("Arrival covariance is not invertible: keeping the old one")
486477
else
487478
rethrow(err)
488479
end

test/test_state_estim.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,35 @@ end
975975
@test info[:Ŷ][end-1:end] [50, 30] atol=1e-9
976976
end
977977

978+
@testset "MovingHorizonEstimator fallbacks for arrival covariance estimation" begin
979+
linmodel = setop!(LinModel(sys,Ts,i_u=[1,2], i_d=[3]), uop=[10,50], yop=[50,30], dop=[5])
980+
f(x,u,d,_) = linmodel.A*x + linmodel.Bu*u + linmodel.Bd*d
981+
h(x,d,_) = linmodel.C*x + linmodel.Dd*d
982+
nonlinmodel = setop!(NonLinModel(f, h, Ts, 2, 4, 2, 1, solver=nothing), uop=[10,50], yop=[50,30], dop=[5])
983+
mhe = MovingHorizonEstimator(nonlinmodel, nint_ym=0, He=1)
984+
preparestate!(mhe, [50, 30], [5])
985+
updatestate!(mhe, [10, 50], [50, 30], [5])
986+
mhe.P̂arr_old[1, 1] = -1e-3 # negative eigenvalue to trigger fallback
987+
P̂arr_old_copy = deepcopy(mhe.P̂arr_old)
988+
invP̄_copy = deepcopy(mhe.invP̄)
989+
@test_logs(
990+
(:warn, "Arrival covariance is not positive definite: keeping the old one"),
991+
preparestate!(mhe, [50, 30], [5])
992+
)
993+
@test mhe.P̂arr_old P̂arr_old_copy
994+
@test mhe.invP̄ invP̄_copy
995+
@test_logs(
996+
(:warn, "Arrival covariance is not positive definite: keeping the old one"),
997+
updatestate!(mhe, [10, 50], [50, 30], [5])
998+
)
999+
@test mhe.P̂arr_old P̂arr_old_copy
1000+
@test mhe.invP̄ invP̄_copy
1001+
@test_logs(
1002+
(:warn, "Arrival covariance is not invertible: keeping the old one"),
1003+
ModelPredictiveControl.invert_cov!(mhe, zeros(mhe.nx̂, mhe.nx̂))
1004+
)
1005+
end
1006+
9781007
@testset "MovingHorizonEstimator set constraints" begin
9791008
linmodel1 = setop!(LinModel(sys,Ts,i_u=[1,2]), uop=[10,50], yop=[50,30])
9801009
mhe1 = MovingHorizonEstimator(linmodel1, He=1, nint_ym=0, Cwt=1e3)

0 commit comments

Comments
 (0)