@@ -276,7 +276,7 @@ function init_defaultcon_mhe(model::SimModel{NT}, He, nx̂) where {NT<:Real}
276276 con = EstimatorConstraint {NT} (X̂min, X̂max, x̂min, x̂max, A_x̂min, A_x̂max, A, b, i_b, i_g)
277277end
278278
279-
279+ # TODO : MODIFIER L'EQ ET LA MÉTHODE POUR QUE E ET F CONTIENNE AUSSI LE STOCK DE XBAR
280280
281281@doc raw """
282282 init_predmat_mhe(model::LinModel{NT}, He, i_ym, Â, B̂u, Ĉ, B̂d, D̂d) -> E, F, G, J, ex̄, fx̄
@@ -288,9 +288,10 @@ Introducing the decision variables vector ``\mathbf{Z} =
288288estimated sensor noise over the time window is given by:
289289```math
290290\b egin{aligned}
291- \m athbf{V̂} &= \m athbf{Y^m - Ŷ^m} \\
292- &= \m athbf{Y^m - (E Z + G U + J D)} \\
293- &= \m athbf{Y^m - (E Z + F)}
291+ [\b egin{smallmatrix}\m athbf{x̄} \\ \m athbf{V̂} \e nd{smallmatrix}]
292+ &= \m athbf{Y^m - Ŷ^m} \\
293+ &= \m athbf{Y^m - (E Z + G U + J D)} \\
294+ &= \m athbf{Y^m - (E Z + F)}
294295\e nd{aligned}
295296in which ``Y^m``, ``U`` and ``D`` contains respectively the measured outputs, manipulated
296297inputs and measured disturbances from time ``k-N_k+1`` to ``k``. The method also returns
@@ -386,7 +387,7 @@ function init_optimization!(
386387 estim:: MovingHorizonEstimator , model:: SimModel , optim:: JuMP.GenericModel{JNT} ,
387388) where JNT<: Real
388389 He, con = estim. He, estim. con
389- nV̂ , nX̂, ng = He* estim. nym, He* estim. nx̂, length (con. i_g)
390+ nx̄V̂ , nX̂, ng = estim . nx̂ + He* estim. nym, He* estim. nx̂, length (con. i_g)
390391 # --- variables and linear constraints ---
391392 nvar = length (estim. Z̃)
392393 set_silent (optim)
@@ -397,42 +398,42 @@ function init_optimization!(
397398 @constraint (optim, linconstraint, A* Z̃var .≤ b)
398399 # --- nonlinear optimization init ---
399400 # see init_optimization!(mpc::NonLinMPC, optim) for details on the inspiration
400- Jfunc, gfunc = let estim= estim, model= model, nvar= nvar , nV̂ = nV̂ , nX̂= nX̂, ng= ng
401+ Jfunc, gfunc = let estim= estim, model= model, nvar= nvar , nx̄V̂ = nx̄V̂ , nX̂= nX̂, ng= ng
401402 last_Z̃tup_float, last_Z̃tup_dual = nothing , nothing
402- V̂_cache :: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nV̂ ), nvar + 3 )
403- g_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, ng), nvar + 3 )
404- X̂_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nX̂), nvar + 3 )
403+ x̄V̂_cache :: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nx̄V̂ ), nvar + 3 )
404+ g_cache :: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, ng), nvar + 3 )
405+ X̂_cache :: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nX̂), nvar + 3 )
405406 function Jfunc (Z̃tup:: JNT... )
406- V̂ = get_tmp (V̂_cache , Z̃tup[1 ])
407+ x̄V̂ = get_tmp (x̄V̂_cache , Z̃tup[1 ])
407408 Z̃ = collect (Z̃tup)
408409 if Z̃tup != = last_Z̃tup_float
409410 g = get_tmp (g_cache, Z̃tup[1 ])
410411 X̂ = get_tmp (X̂_cache, Z̃tup[1 ])
411- V̂ , X̂ = predict! (V̂ , X̂, estim, model, Z̃)
412+ x̄V̂ , X̂ = predict! (x̄V̂ , X̂, estim, model, Z̃)
412413 g = con_nonlinprog! (g, estim, model, X̂)
413414 last_Z̃tup_float = Z̃tup
414415 end
415- return obj_nonlinprog (estim, model, V̂ , Z̃)
416+ return obj_nonlinprog (estim, model, x̄V̂ , Z̃)
416417 end
417418 function Jfunc (Z̃tup:: ForwardDiff.Dual... )
418- V̂ = get_tmp (V̂_cache , Z̃tup[1 ])
419+ x̄V̂ = get_tmp (x̄V̂_cache , Z̃tup[1 ])
419420 Z̃ = collect (Z̃tup)
420421 if Z̃tup != = last_Z̃tup_dual
421422 g = get_tmp (g_cache, Z̃tup[1 ])
422423 X̂ = get_tmp (X̂_cache, Z̃tup[1 ])
423- V̂ , X̂ = predict! (V̂ , X̂, estim, model, Z̃)
424+ x̄V̂ , X̂ = predict! (x̄V̂ , X̂, estim, model, Z̃)
424425 g = con_nonlinprog! (g, estim, model, X̂)
425426 last_Z̃tup_dual = Z̃tup
426427 end
427- return obj_nonlinprog (estim, model, V̂ , Z̃)
428+ return obj_nonlinprog (estim, model, x̄V̂ , Z̃)
428429 end
429430 function gfunc_i (i, Z̃tup:: NTuple{N, JNT} ) where N
430431 g = get_tmp (g_cache, Z̃tup[1 ])
431432 if Z̃tup != = last_Z̃tup_float
432- V̂ = get_tmp (V̂_cache , Z̃tup[1 ])
433- X̂ = get_tmp (X̂_cache, Z̃tup[1 ])
434- Z̃ = collect (Z̃tup)
435- V̂ , X̂ = predict! (V̂ , X̂, estim, model, Z̃)
433+ x̄V̂ = get_tmp (x̄V̂_cache , Z̃tup[1 ])
434+ X̂ = get_tmp (X̂_cache, Z̃tup[1 ])
435+ Z̃ = collect (Z̃tup)
436+ x̄V̂ , X̂ = predict! (x̄V̂ , X̂, estim, model, Z̃)
436437 g = con_nonlinprog! (g, estim, model, X̂)
437438 last_Z̃tup_float = Z̃tup
438439 end
@@ -441,10 +442,10 @@ function init_optimization!(
441442 function gfunc_i (i, Z̃tup:: NTuple{N, ForwardDiff.Dual} ) where N
442443 g = get_tmp (g_cache, Z̃tup[1 ])
443444 if Z̃tup != = last_Z̃tup_dual
444- V̂ = get_tmp (V̂_cache , Z̃tup[1 ])
445- X̂ = get_tmp (X̂_cache, Z̃tup[1 ])
445+ x̄V̂ = get_tmp (x̄V̂_cache , Z̃tup[1 ])
446+ X̂ = get_tmp (X̂_cache, Z̃tup[1 ])
446447 Z̃ = collect (Z̃tup)
447- V̂ , X̂ = predict! (V̂ , X̂, estim, model, Z̃)
448+ x̄V̂ , X̂ = predict! (x̄V̂ , X̂, estim, model, Z̃)
448449 g = con_nonlinprog! (g, estim, model, X̂)
449450 last_Z̃tup_dual = Z̃tup
450451 end
@@ -514,6 +515,10 @@ function setconstraint!(
514515 estim:: MovingHorizonEstimator ;
515516 x̂min = nothing , x̂max = nothing ,
516517 X̂min = nothing , X̂max = nothing ,
518+ ŵmin = nothing , ŵmax = nothing ,
519+ Ŵmin = nothing , Ŵmax = nothing ,
520+ v̂min = nothing , v̂max = nothing ,
521+ V̂min = nothing , V̂max = nothing ,
517522)
518523 model, optim, con = estim. model, estim. optim, estim. con
519524 nx̂, He = estim. nx̂, estim. He
@@ -644,11 +649,11 @@ function update_estimate!(estim::MovingHorizonEstimator{NT}, u, ym, d) where NT<
644649 Nk = estim. Nk[]
645650 nŴ, nYm, nX̂ = nx̂* Nk, nym* Nk, nx̂* Nk
646651 Z̃var:: Vector{VariableRef} = optim[:Z̃var ]
647- Ŷm = Vector {NT} (undef, nYm)
652+ x̄V̂ = Vector {NT} (undef, nx̂ + nYm)
648653 X̂ = Vector {NT} (undef, nX̂)
649654 Z̃0 = [estim. x̂arr_old; estim. Ŵ]
650- Ŷm , X̂ = predict! (Ŷm , X̂, estim, model, Z̃0)
651- J0 = obj_nonlinprog (estim, model, Ŷm , Z̃0)
655+ x̄V̂ , X̂ = predict! (x̄V̂ , X̂, estim, model, Z̃0)
656+ J0 = obj_nonlinprog (estim, model, x̄V̂ , Z̃0)
652657 # initial Z̃0 with Ŵ=0 if objective or constraint function not finite :
653658 isfinite (J0) || (Z̃0 = [estim. x̂arr_old; zeros (NT, nŴ)])
654659 set_start_value .(Z̃var, Z̃0)
@@ -683,7 +688,7 @@ function update_estimate!(estim::MovingHorizonEstimator{NT}, u, ym, d) where NT<
683688 estim. Z̃[:] = ! isfatal (status) ? Z̃curr : Z̃last
684689 # --------- update estimate -----------------------
685690 estim. Ŵ[1 : nŴ] = estim. Z̃[nx̂+ 1 : nx̂+ nŴ] # update Ŵ with optimum for next time step
686- Ŷm , X̂ = predict! (Ŷm , X̂, estim, model, estim. Z̃)
691+ x̄V̂ , X̂ = predict! (x̄V̂ , X̂, estim, model, estim. Z̃)
687692 x̂[:] = X̂[(1 + nx̂* (Nk- 1 )): (nx̂* Nk)]
688693 if Nk == He
689694 uarr, ymarr, darr = estim. U[1 : nu], estim. Ym[1 : nym], estim. D[1 : nd]
@@ -739,54 +744,55 @@ end
739744
740745
741746function obj_nonlinprog (
742- estim:: MovingHorizonEstimator , :: LinModel , Ŷm , Z̃:: Vector{T}
747+ estim:: MovingHorizonEstimator , :: LinModel , x̄V̂ , Z̃:: Vector{T}
743748) where {T<: Real }
744- return obj_quadprog (Z̃, estim. H̃, estim. q̃)
749+ return obj_quadprog (Z̃, estim. H̃, estim. q̃) + estim . p[]
745750end
746751
747752"""
748- obj_nonlinprog(estim::MovingHorizonEstimator, model::SimModel, V̂ , Z̃)
753+ obj_nonlinprog(estim::MovingHorizonEstimator, model::SimModel, x̄V̂ , Z̃)
749754
750755Objective function for the [`MovingHorizonEstimator`](@ref).
751756
752757The function `dot(x, A, x)` is a performant way of calculating `x'*A*x`.
753758"""
754759function obj_nonlinprog (
755- estim:: MovingHorizonEstimator , :: SimModel , V̂ , Z̃:: Vector{T}
760+ estim:: MovingHorizonEstimator , :: SimModel , x̄V̂ , Z̃:: Vector{T}
756761) where {T<: Real }
757762 Nk = estim. Nk[]
758763 nYm, nŴ, nx̂, invP̄ = Nk* estim. nym, Nk* estim. nx̂, estim. nx̂, estim. invP̄
759764 invQ̂_Nk, invR̂_Nk = @views estim. invQ̂_He[1 : nŴ, 1 : nŴ], estim. invR̂_He[1 : nYm, 1 : nYm]
760- x̂arr = @views Z̃[1 : nx̂]
761- x̄ = estim. x̂arr_old - x̂arr
765+ x̄ = @views x̄V̂[1 : nx̂]
762766 Ŵ = @views Z̃[nx̂+ 1 : nx̂+ nŴ]
763- V̂ = @views V̂[ 1 : nYm]
767+ V̂ = @views x̄V̂[nx̂ + 1 : nx̂ + nYm]
764768 return dot (x̄, invP̄, x̄) + dot (Ŵ, invQ̂_Nk, Ŵ) + dot (V̂, invR̂_Nk, V̂)
765769end
766770
767771"""
768- predict!(V̂ , X̂, estim::MovingHorizonEstimator, model::SimModel, Z̃) -> V̂ , X̂
772+ predict!(x̄V̂ , X̂, estim::MovingHorizonEstimator, model::SimModel, Z̃) -> x̄V̂ , X̂
769773
770- Compute the estimated sensor noises `V̂` and states `X̂` for the `MovingHorizonEstimator`.
774+ Compute the `x̄V̂` vector and `X̂` vectors for the `MovingHorizonEstimator`.
771775
772- The method mutates `V̂` and `X̂` vector arguments. Note that `V̂` goes from ``k-N_k+1`` to
773- ``k``, and `X̂`, from ``k-N_k+2`` to ``k+1``.
776+ The method mutates `x̄V̂` and `X̂` vector arguments. The vector `x̄V̂` is a concatenation of the
777+ estimated error at arrival `x̄` and the sensor noises `V̂` from ``k-N_k+1`` to ``k``. The `X̂`
778+ vector is estimated states from ``k-N_k+2`` to ``k+1``.
774779"""
775780function predict! (
776- V̂ , X̂, estim:: MovingHorizonEstimator , model:: SimModel , Z̃:: Vector{T}
781+ x̄V̂ , X̂, estim:: MovingHorizonEstimator , model:: SimModel , Z̃:: Vector{T}
777782) where {T<: Real }
778783 nu, nd, nx̂, nym, Nk = model. nu, model. nd, estim. nx̂, estim. nym, estim. Nk[]
779- x̂ = @views Z̃[1 : nx̂] # Z̃ = [x̂(k-Nk+1|k); Ŵ]
784+ x̂ = @views Z̃[1 : nx̂]
785+ x̄V̂[1 : nx̂] = estim. x̂arr_old - x̂
780786 for j= 1 : Nk
781787 u = @views estim. U[ (1 + nu* (j- 1 )): (nu* j)]
782788 ym = @views estim. Ym[(1 + nym* (j- 1 )): (nym* j)]
783789 d = @views estim. D[ (1 + nd* (j- 1 )): (nd* j)]
784790 ŵ = @views Z̃[(1 + nx̂* j): (nx̂* (j+ 1 ))]
785- V̂ [(1 + nym* (j- 1 )): (nym* j)] = ym - ĥ (estim, model, x̂, d)[estim. i_ym]
786- X̂[(1 + nx̂ * (j- 1 )): (nx̂ * j)] = f̂ (estim, model, x̂, u, d) + ŵ
791+ x̄V̂ [(1 + nx̂ + nym* (j- 1 )): (nx̂ + nym* j)] = ym - ĥ (estim, model, x̂, d)[estim. i_ym]
792+ X̂[(1 + nx̂* (j- 1 )): (nx̂ * j)] = f̂ (estim, model, x̂, u, d) + ŵ
787793 x̂ = @views X̂[(1 + nx̂* (j- 1 )): (nx̂* j)]
788794 end
789- return V̂ , X̂
795+ return x̄V̂ , X̂
790796end
791797
792798"""
0 commit comments