From c34fa0ca0ac691a40d9e7ba2b670cc92bebfdaf9 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Mon, 3 Aug 2026 16:55:10 -0400 Subject: [PATCH 1/2] debug: do not increment `mhe.Nk` if `updatestate!` was not called This is a minor debug to ensure that the length of the data windows are not incremented if the user did not called `updatestate!` on a `MovingHorizonEstimator` with `direct=true`. This should not happen on normal usage of the package. This is however useful for benchmarking. We can call `preparestate!` multiple time (e.g. with `@btime`) and the data windows will be identical at each call. --- src/estimator/mhe/execute.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/estimator/mhe/execute.jl b/src/estimator/mhe/execute.jl index 0da59d0e7..9070bb16c 100644 --- a/src/estimator/mhe/execute.jl +++ b/src/estimator/mhe/execute.jl @@ -506,7 +506,9 @@ function add_data_windows!(estim::MovingHorizonEstimator, y0m, d0, u0=estim.last Nk = estim.Nk[] p = estim.direct ? 0 : 1 # u0 argument is u0(k-1) if estim.direct, else u0(k) x̂0_old = estim.x̂0 # x̂0_old is x̂0(k-1|k-1) if estim.direct, else x̂0(k|k-1) - estim.Nk .+= 1 + if !estim.direct || !estim.prepared[] + estim.Nk .+= 1 # direct=true: only increments if updatestate! was called + end Nk = estim.Nk[] ismoving = (Nk > estim.He) # see MovingHorzionEstimator extended help for the exact time steps in each data window From fd550863616087f7fa46633d00fee02112bec498 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Mon, 3 Aug 2026 17:00:04 -0400 Subject: [PATCH 2/2] test: new window length tests for the MHE --- test/2_test_state_estim.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/2_test_state_estim.jl b/test/2_test_state_estim.jl index 98cd8a88d..cef6130b1 100644 --- a/test/2_test_state_estim.jl +++ b/test/2_test_state_estim.jl @@ -1038,10 +1038,15 @@ end mhe2 = MovingHorizonEstimator(linmodel, He=2) preparestate!(mhe2, [50, 30], [5]) + @test mhe2.Nk[] == 1 + preparestate!(mhe2, [50, 30], [5]) + @test mhe2.Nk[] == 1 x̂ = updatestate!(mhe2, [10, 50], [50, 30], [5]) + @test mhe2.Nk[] == 1 @test x̂ ≈ zeros(6) atol=1e-9 @test mhe2.x̂0 ≈ zeros(6) atol=1e-9 preparestate!(mhe2, [50, 30], [5]) + @test mhe2.Nk[] == 2 info = getinfo(mhe2) @test info[:x̂] ≈ x̂ atol=1e-9 @test info[:Ŷ][end-1:end] ≈ [50, 30] atol=1e-9 @@ -1060,7 +1065,9 @@ end mhe2 = MovingHorizonEstimator(linmodel, He=2, nint_u=[1, 1], nint_ym=[0, 0], direct=false) preparestate!(mhe2, [50, 30], [5]) + @test mhe2.Nk[] == 0 x̂ = updatestate!(mhe2, [10, 50], [50, 30], [5]) + @test mhe2.Nk[] == 1 @test x̂ ≈ zeros(6) atol=1e-9 @test mhe2.x̂0 ≈ zeros(6) atol=1e-9 info = getinfo(mhe2)