# Use ControlSystemIdentification.jl for a ModelingToolkit.jl model

**URL:** https://discourse.julialang.org/t/use-controlsystemidentification-jl-for-a-modelingtoolkit-jl-model/116588
**Category:** Modelling & Simulations
**Tags:** modelingtoolkit, controlsystems
**Created:** [July 3, 2024, 1:58pm UTC](https://discourse.julialang.org/t/use-controlsystemidentification-jl-for-a-modelingtoolkit-jl-model/116588 "2024-07-03T13:58:38Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![langestefan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/langestefan/32/207923_2.png) [@langestefan](https://discourse.julialang.org/u/langestefan)
#### Post date: [July 3, 2024, 1:58pm UTC](https://discourse.julialang.org/t/use-controlsystemidentification-jl-for-a-modelingtoolkit-jl-model/116588/1 "2024-07-03T13:58:38Z")

</div>

Hi,

I have an LTI model defined in ModelingToolkit.jl:

```julia
@named T_a_out = TimeVaryingFunction(input_funcs[:T_a])
@named Φ_hp_out = TimeVaryingFunction(input_funcs[:Φ_hp])
@named Φ_cv_out = TimeVaryingFunction(input_funcs[:Φ_cv])
@named Φ_s_out = TimeVaryingFunction(input_funcs[:Φ_s])

vars = @variables T_i(t) T_e(t) T_h(t) T_a(t) Φ_hp(t) Φ_cv(t) Φ_s(t)
pars = @parameters C_i = params[:C_i] C_e = params[:C_e] C_h = params[:C_h] R_ie = params[:R_ie] R_ea = params[:R_ea] R_ih = params[:R_ih] A_w = params[:A_w] A_e = params[:A_e]

eqs = [
    # inputs
    T_a ~ T_a_out.output.u
    Φ_hp ~ Φ_hp_out.output.u
    Φ_cv ~ Φ_cv_out.output.u
    Φ_s ~ Φ_s_out.output.u

    # dynamics
    C_i * D(T_i) ~ A_w * Φ_s + (T_h - T_i) * R_ih + (T_e - T_i) * R_ie
    C_e * D(T_e) ~ A_e * Φ_s + (T_a - T_e) * R_ea + (T_i - T_e) * R_ie
    C_h * D(T_h) ~ Φ_cv + Φ_hp + (T_i - T_h) * R_ih
]

ODESystem(eqs, t, vars, pars; systems=[T_a_out, Φ_hp_out, Φ_cv_out, Φ_s_out], name)

```

Now I’m trying to estimate the parameters of this model using ControlSystemIdentification.jl.

Is there a guide on how to do this? I assume I need some glue code from ControlSystemsMTK.jl, but has anyone worked this out?

---

<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: [July 3, 2024, 2:20pm UTC](https://discourse.julialang.org/t/use-controlsystemidentification-jl-for-a-modelingtoolkit-jl-model/116588/2 "2024-07-03T14:20:25Z")

</div>

> [@langestefan](#):
>
> has anyone worked this out?

I have done this a few times, but never published the glue code. The pieces you need are

- `ModelingToolkit.generate_control_function` to generate a function that computes \dot x = f(x, u, p, t) where x is the state and $u$$ is some external input (if present). In your case, I would remove the `TimeVaryingFunction` and instead treat those as external inputs (if I understand your use case correctly).
- [SeeToDee.jl](https://github.com/baggepinnen/SeeToDee.jl/) to discretize the function f from above.
- Call [`nonlinear_pem`](https://baggepinnen.github.io/ControlSystemIdentification.jl/dev/nonlinear/#Parameter-estimation-in-a-known-model-structure) with the discretized dynamics function returned by SeeToDee.jl

---

<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: [July 3, 2024, 2:22pm UTC](https://discourse.julialang.org/t/use-controlsystemidentification-jl-for-a-modelingtoolkit-jl-model/116588/3 "2024-07-03T14:22:56Z")

</div>

> [@langestefan](#):
>
> I have an LTI model

Ah, if you have an LTI model, you can call `named_ss` from ContorlSystemsMTK or `ModelingToolkit.linearize_symbolic` to obtain the statespace matrices `A,B,C,D`, you can then make use of [`structured_pem`](https://baggepinnen.github.io/ControlSystemIdentification.jl/dev/ss/#ControlSystemIdentification.structured_pem) to estimate the parameters. You’d need to write some glue code yourself in this case, this special-case pipeline of an LTI model from MTK hasn’t been explored yet.

You find some relevant utilities [here](https://juliacontrol.github.io/ControlSystemsMTK.jl/dev/#Symbolic-linearization), in particular the symbolic linearization and code generation that would give you the `constructor` function you need for `structured_pem`.

---

<div class="post-metadata">

### Author: ![langestefan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/langestefan/32/207923_2.png) [@langestefan](https://discourse.julialang.org/u/langestefan)
#### Post date: [July 4, 2024, 11:01am UTC](https://discourse.julialang.org/t/use-controlsystemidentification-jl-for-a-modelingtoolkit-jl-model/116588/4 "2024-07-04T11:01:56Z")

</div>

Okay thanks, unfortunately I don’t have the skills to get that working yet. I thought this would be a very common usecase.

---

<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: [July 4, 2024, 11:07am UTC](https://discourse.julialang.org/t/use-controlsystemidentification-jl-for-a-modelingtoolkit-jl-model/116588/5 "2024-07-04T11:07:46Z")

</div>

You can use the utilities to estimate a generic nonlinear model, it will not be as performant as if the linearity was exploited, but it will get the job done. [Here’s a fully working example.](https://baggepinnen.github.io/ControlSystemIdentification.jl/dev/nonlinear/#Identifying-parameters-in-a-ModelingToolkit-model)

---

<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: [July 4, 2024, 11:26am UTC](https://discourse.julialang.org/t/use-controlsystemidentification-jl-for-a-modelingtoolkit-jl-model/116588/6 "2024-07-04T11:26:10Z")

</div>

> [@langestefan](#):
>
> I thought this would be a very common usecase.

Not really, MTK is a tool for generic, nonlinear acausal modeling. As such, it can of course model simple LTI systems, but there is not much infrastructure in place to handle this special case any different from a fully generic nonlinear model.

If the model you have shown above is the full extent of your system, I would consider MTK a bit overkill and instead use something more minimal, e.g.

- OrdinaryDiffEq.jl directly
- SeeToDee.jl
- ControlSystems.jl

The last two options would be much easier to interface with ControlSystemIdentification.

Your model as you have shown it does not make any use of things like model components, connections, algebraic equations, and for such simple system I think MTK complicates things rather than simplifies. If your end goal is a much bigger model, MTK may of course still make sense.

---

<div class="post-metadata">

### Author: ![langestefan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/langestefan/32/207923_2.png) [@langestefan](https://discourse.julialang.org/u/langestefan)
#### Post date: [July 9, 2024, 4:40pm UTC](https://discourse.julialang.org/t/use-controlsystemidentification-jl-for-a-modelingtoolkit-jl-model/116588/7 "2024-07-09T16:40:56Z")

</div>

Thanks, I’m trying to see if I can get `structured_pem` working. Is there any example or docs on how to setup the state-space model for `constructor`? I wasn’t able to find anything in the docs

---

<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: [July 10, 2024, 4:21am UTC](https://discourse.julialang.org/t/use-controlsystemidentification-jl-for-a-modelingtoolkit-jl-model/116588/8 "2024-07-10T04:21:05Z")

</div>

Here’s an example

> <https://github.com/baggepinnen/ControlSystemIdentification.jl/blob/6573449b12c3c4511fb95e417db1c5f5b8511a94/test/test_pem.jl#L313>
