# Unobservable linearized model in ModelPredictiveControl.jl

**URL:** <https://discourse.julialang.org/t/unobservable-linearized-model-in-modelpredictivecontrol-jl/121052>\
**Category:** Modelling & Simulations\
**Tags:** modelpredictivecontr\
**Created:** [October 8, 2024, 9:11am UTC](https://discourse.julialang.org/t/unobservable-linearized-model-in-modelpredictivecontrol-jl/121052 "2024-10-08T09:11:32Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bart\_van\_de\_Lint](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bart_van_de_lint/32/212161_2.png) [@Bart\_van\_de\_Lint](https://discourse.julialang.org/u/Bart_van_de_Lint)\
**Post date:** [October 8, 2024, 9:11am UTC](https://discourse.julialang.org/t/unobservable-linearized-model-in-modelpredictivecontrol-jl/121052/1 "2024-10-08T09:11:32Z")

</div>

I have a model that I am trying to linearize around `x_0` in order to use a linear MPC in ModelPredictiveControl.jl.

```julia
println("linearize")
linmodel = ModelPredictiveControl.linearize(model; x=x_0)

println("sim")
u = [100, 100, -100]
res = sim!(linmodel, N, u; x_0 = x_0)
display(plot(res, plotu=false))

println("linear mpc")
skf = SteadyKalmanFilter(linmodel; nint_ym=0, nint_u=0)
mpc = LinMPC(skf; Hp, Hc, Mwt, Nwt, Cwt=Inf)
nmpc = setconstraint!(nmpc; umin=umin, umax=umax)
res = sim!(nmpc, N, wanted_outputs, x_0 = x_0, x̂_0 = x̂_0, lastu = [0, 0, -50.0])
display(plot(res))

```

But I am getting stuck when trying to create the SKF:

```julia
ERROR: LoadError: The augmented model is unobservable. You may try to use 0 integrator on model integrating outputs with nint_ym parameter. Adding integrators at both inputs (nint_u) and outputs (nint_ym) can also violate observability.

```

Setting the integrators to 0 does not make a difference. The simulation works fine. The observed variables (outputs) are also state variables (x). Are there any other things I can do / what can be the reasons for an unobservable linearized model?

This is the C matrix. It has a 1.0 for each output variable, as expected.

```julia
julia> println(linmodel.C)
[0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0; 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0]

```

---

<div class="post-metadata">

**Author:** ![Bart\_van\_de\_Lint](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bart_van_de_lint/32/212161_2.png) [@Bart\_van\_de\_Lint](https://discourse.julialang.org/u/Bart_van_de_Lint)\
**Post date:** [October 8, 2024, 11:52am UTC](https://discourse.julialang.org/t/unobservable-linearized-model-in-modelpredictivecontrol-jl/121052/2 "2024-10-08T11:52:14Z")

</div>

Problem solved. As I understand it now: in the linear model in ModelPredictiveControl.jl it is assumed that only the outputs are measured state variables. So if any of the state variables cannot be calculated from the output variables (aka are not linearly dependent on some combination of the outputs), the system will be non-observable. @franckgaga does it make any sense what I am saying?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [October 8, 2024, 12:06pm UTC](https://discourse.julialang.org/t/unobservable-linearized-model-in-modelpredictivecontrol-jl/121052/3 "2024-10-08T12:06:28Z")

</div>

Outputs y may be _any_ linear combination of the state variables, y = Cx. An unobservable model is one that has a [rank-deficient observability matrix](https://en.wikipedia.org/wiki/Observability). TLDR: with an observable model it is possible to reconstruct the state given a _sequence_ of outputs.

> [@Bart\_van\_de\_Lint](#):
>
> So if any of the state variables cannot be calculated from the output variables (aka are not linearly dependent on some combination of the outputs)

what you describe here is a much stronger notion of observability, the ability to reconstruct the state from a single measurement. This is generally _not_ as important.

To understand the difference, consider estimating velocity from position measurements. With a single position measurement, you cannot figure out the velocity. However, with a sequence of position measurements you can estimate also the velocity. Hence, the space of positions and velocities are observable from position measurements only.

---

<div class="post-metadata">

**Author:** ![Bart\_van\_de\_Lint](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bart_van_de_lint/32/212161_2.png) [@Bart\_van\_de\_Lint](https://discourse.julialang.org/u/Bart_van_de_Lint)\
**Post date:** [October 8, 2024, 1:01pm UTC](https://discourse.julialang.org/t/unobservable-linearized-model-in-modelpredictivecontrol-jl/121052/4 "2024-10-08T13:01:35Z")

</div>

Thanks, really helpful explanation!

---

<div class="post-metadata">

**Author:** ![franckgaga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/franckgaga/32/218241_2.png) [@franckgaga](https://discourse.julialang.org/u/franckgaga)\
**Post date:** [October 8, 2024, 1:35pm UTC](https://discourse.julialang.org/t/unobservable-linearized-model-in-modelpredictivecontrol-jl/121052/5 "2024-10-08T13:35:21Z")

</div>

Also, it’s common that non minimal realizations are not observable. You may try `sminreal` and `minreal` on your linear model. Something like:

```julia
using ControlSystemsBase
uop, yop, dop, xop, fop = linmodel.uop, linmodel.yop, linmodel.dop, linmodel.xop, linmodel.fop
sys = ss(linmodel.A, linmodel.Bu, linmodel.C, 0, linmodel.Ts)
sys2 = sminreal(sys) # or minreal, also try to modify atol and rtol kwargs
linmodel_2 = setop!(LinModel(sys2); uop, yop, dop, xop, fop)

```

edit: FYI @baggepinnen I will modify the error message to guide the user a little bit. The new error message is:

```julia
ERROR: The augmented model is unobservable. You may try to use 0 integrator on model
integrating outputs with nint_ym parameter. Adding integrators at both inputs (nint_u) and 
outputs (nint_ym) can also violate observability. If the model is still unobservable without 
any integrators, you may need to call sminreal or minreal on your system.

```

---

<div class="post-metadata">

**Author:** ![Bart\_van\_de\_Lint](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bart_van_de_lint/32/212161_2.png) [@Bart\_van\_de\_Lint](https://discourse.julialang.org/u/Bart_van_de_Lint)\
**Post date:** [October 8, 2024, 3:24pm UTC](https://discourse.julialang.org/t/unobservable-linearized-model-in-modelpredictivecontrol-jl/121052/6 "2024-10-08T15:24:15Z")

</div>

Is it possible as well to have some observed states (outputs) that are not used as setpoints, but just as measurements? My first guess would be to change the Mwt to 0 for all outputs that should not be optimized.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [October 8, 2024, 3:26pm UTC](https://discourse.julialang.org/t/unobservable-linearized-model-in-modelpredictivecontrol-jl/121052/7 "2024-10-08T15:26:45Z")

</div>

> [@Bart\_van\_de\_Lint](#):
>
> My first guess would be to change the Mwt to 0 for all outputs that should not be optimize

That should work fine

---

<div class="post-metadata">

**Author:** ![franckgaga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/franckgaga/32/218241_2.png) [@franckgaga](https://discourse.julialang.org/u/franckgaga)\
**Post date:** [October 8, 2024, 3:57pm UTC](https://discourse.julialang.org/t/unobservable-linearized-model-in-modelpredictivecontrol-jl/121052/8 "2024-10-08T15:57:25Z")

</div>

Yes exactly, that’s the way to do this.
