diff --git a/Project.toml b/Project.toml index 8a146db26..b8139c3d0 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "ModelPredictiveControl" uuid = "61f9bdb8-6ae4-484a-811f-bbf86720c31c" -version = "2.14.0" +version = "2.14.1" authors = ["Francis Gagnon"] [deps] diff --git a/src/estimator/mhe/construct.jl b/src/estimator/mhe/construct.jl index b0ade0423..68d8fee40 100644 --- a/src/estimator/mhe/construct.jl +++ b/src/estimator/mhe/construct.jl @@ -662,8 +662,11 @@ function default_covestim_mhe(model::SimModel, i_ym, nint_u, nint_ym, P̂_0, Q̂ elseif model isa NonLinModel return UnscentedKalmanFilter(model, i_ym, nint_u, nint_ym, P̂_0, Q̂, R̂; direct) else + # SteadyKalmanFilter with arbitrary LinModel (will be ignored): nx, nu, ny = model.nx, model.nu, model.ny - A, Bu, C = 0.1*I(nx), ones(nx, nu), ones(ny, nx) + poles = nx > 1 ? range(0.1, 0.9, length=nx) : [0.5] + A = Diagonal(poles) # distinct and stable poles for observability + Bu, C = ones(nx, nu), ones(ny, nx) dummy_model = LinModel(A, Bu, C, 0, 0, model.Ts) return SteadyKalmanFilter(dummy_model, i_ym, nint_u, nint_ym, Q̂, R̂; direct) end diff --git a/test/2_test_state_estim.jl b/test/2_test_state_estim.jl index d17376c63..03363df08 100644 --- a/test/2_test_state_estim.jl +++ b/test/2_test_state_estim.jl @@ -1059,6 +1059,11 @@ end mhe2 = MovingHorizonEstimator(dae; He=3, transcription, direct=false) @test mhe2.direct == false + mhe_skf = MovingHorizonEstimator(dae; He=3, nint_ym=0, nint_u=0, σP_0 = [0.5]) + @test mhe_skf.cov.P̂_0 ≈ [0.5^2] + @test mhe_skf.cov.invP̄ ≈ [1/(0.5^2)] + @test mhe_skf.P̂arr_old ≈ [0.5^2] + @test_throws ArgumentError MovingHorizonEstimator(dae, He=3, transcription=SingleShooting()) @test_throws ArgumentError MovingHorizonEstimator(dae, He=3, transcription=MultipleShooting()) end