# State Space Model with PID controller unstable in Julia compared to Matlab

**URL:** <https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688>\
**Category:** Specific Domains\
**Tags:** control, controlsystems\
**Created:** [July 31, 2024, 5:14pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688 "2024-07-31T17:14:13Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![lstagner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lstagner/32/448_2.png) [@lstagner](https://discourse.julialang.org/u/lstagner)\
**Post date:** [July 31, 2024, 5:14pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/1 "2024-07-31T17:14:13Z")

</div>

I have the following code in Matlab that creates a stable system using a simple PID controller.

```matlab
%% Define system
sys = ss(A,B,C,D);

%% New state space
sys_new = sys([1379],13);

%% Define s domain
Kp = 0;
Ki = 0; % No integrator
Kd = 278.7369;
Tf = 0;
sys_C = pid(Kp,Ki,Kd,Tf);

%% Controller design
sys_cl = feedback(sys_new,sys_C);
step(sys_cl)

```

which produces the following step response  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/b/9/b9acb2fea96567de83794ec8492bfa5846c97b4e.png)

The Julia version (or at least as close as i can make it is

```julia
using ControlSystems

sys = ss(A,B,C,D)
sys_new = sminreal(sys[1379,13])
Kp = 0
Ki = 0
Kd = 278.7369
Tf = 0
sys_C = pid(Kp,Ki,Kd; Tf=0.001, form=:parallel, state_space=true) 
# notice the Tf has to be set to be non-zero here but not in the matlab version
sys_cl = feedback(sys_new,sys_C);

y,t = step(sys_cl);
plot(t,y[1,:])

```

This produces nonsense  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/c/5/c5eb25874f2dfc51335a74d9cdc384196b3e4c4e.png)

The main difference I see in the Matlab version and the Julia version is that in the Julia version is that the PID controller needs to be converted into state\_space and that requires the Tf be set to something non-zero which causes the step response to go bad. Indeed setting `Tf=0.001` in the matlab version produces a similar looking response.  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/0/9/0938c3f86d58f7246cf27eadb9c719537dac5379.png)

My question is how can I make the julia and matlab version agree?

---

<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 31, 2024, 5:22pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/2 "2024-07-31T17:22:09Z")

</div>

> [@lstagner](#):
>
> My question is how can I make the julia and matlab version agree?

Hard to say without being able to reproduce your problem.

Try any of

```julia
step(balance_statespace(sys_cl)[1])

```

or

```julia
step(c2d(sys_cl, 1e-2))

```

---

<div class="post-metadata">

**Author:** ![lstagner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lstagner/32/448_2.png) [@lstagner](https://discourse.julialang.org/u/lstagner)\
**Post date:** [July 31, 2024, 5:29pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/3 "2024-07-31T17:29:42Z")

</div>

Unfortunately neither of those solultions worked and produced a similar issue

Here is a BSON file containing the ABCD matrices.  
[https://file.io/yXCBg7jmnl4x](https://file.io/yXCBg7jmnl4x)

---

<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 31, 2024, 6:16pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/5 "2024-07-31T18:16:11Z")

</div>

Even with all computations performed using big floats, I still get that the unstable pole in the plant remains unstable after closing the loop:

```julia
using ControlSystems, BSON, LinearAlgebra

function LinearAlgebra.eigvals!(R::Matrix{BigFloat}, A::Matrix{BigFloat}; sortby::Nothing)
    eigvals(A)
end

data = BSON.load("/tmp/state_space.bson")
A,B,C,D = getindex.(Ref(data), [:A, :B, :C, :D])

sys = ss(big.(A),big.(B),big.(C),big.(D))
# sys = ss(A,B,C,D)
sys_new = sminreal(sys[1379,13])
Kp = 0
Ki = 0
Kd = big(278.7369)
Tf = 0
sys_C = pid(Kp,Ki,Kd; Tf=1e-16, form=:parallel, state_space=true) 
# notice the Tf has to be set to be non-zero here but not in the matlab version

L = sys_new*sys_C
sys_cl = feedback(sys_new, sys_C)
isstable(sys_cl)

```

```julia-repl
julia> isstable(sys_cl)
false

```

are you sure that the matlab results are correct?

---

<div class="post-metadata">

**Author:** ![lstagner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lstagner/32/448_2.png) [@lstagner](https://discourse.julialang.org/u/lstagner)\
**Post date:** [July 31, 2024, 6:39pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/6 "2024-07-31T18:39:05Z")

</div>

> are you sure that the matlab results are correct?

Welcome to my life…

I gave the matlab code in my first post and the step response flattens out unlike the julia version. What I don’t understand is how matlab is adding the feedback to the state-space model if the pid controller is in s-function form and not in state-space form. Is matlab taking the state-space system and turning it into a transfer function form?

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [July 31, 2024, 6:40pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/7 "2024-07-31T18:40:12Z")

</div>

According to my experience Matlab and Simulink often give completely wrong results without any warning when trying to solve control problems.

---

<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 31, 2024, 6:51pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/8 "2024-07-31T18:51:51Z")

</div>

> [@lstagner](#):
>
> Is matlab taking the state-space system and turning it into a transfer function form?

I can’t run matlab, you can check what type sys\_cl has, I’d expect them to convert to a descriptor system.

You can directly compute the poles of the closed loop system, that will tell you if you have any unstable ones left, before computing the step response.

---

<div class="post-metadata">

**Author:** ![lstagner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lstagner/32/448_2.png) [@lstagner](https://discourse.julialang.org/u/lstagner)\
**Post date:** [July 31, 2024, 7:14pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/9 "2024-07-31T19:14:36Z")

</div>

The output type for sys\_cl is a state\_space system. Interestingly if I try to recreate the state\_space model from the `sys_cl` ABCD I get an unstable system. For example

```matlab
%% matlab
sys_cp = ss(sys_cl.A, sys_cl.B, sys_cl.C,sys_cl.D)
step(sys_cl)

```

![image](https://global.discourse-cdn.com/julialang/original/3X/1/4/14ddaad2db0a5bb2a4aa2dcd4c286892e3e97331.png)

and I get the same response in Julia. Matlab is doing something behind the scenes and its making me insane

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [July 31, 2024, 7:22pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/10 "2024-07-31T19:22:12Z")

</div>

> [@lstagner](#):
>
> ```julia
> %% New state space
> sys_new = sys([1379],13);
> 
> ```

Are you doing the same thing in MATLAB and Julia? Above is what you do in MATLAB (unless you have a typo) – I don’t see any minimal realization there. Contrast that to what you do in Julia:

```julia
sys_new = sminreal(sys[1379,13])

```

So – in Julia, do you pick out row 1379 and column 13 of a (huge) input-output system, and do `sminreal` on that system? What are you doing in MATLAB?

[Sorry – my MATLAB CST competence is somewhat rusty…]

---

<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 31, 2024, 7:24pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/11 "2024-07-31T19:24:17Z")

</div>

Does the closed-loop system in matlab have an E matrix as well?

---

<div class="post-metadata">

**Author:** ![lstagner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lstagner/32/448_2.png) [@lstagner](https://discourse.julialang.org/u/lstagner)\
**Post date:** [July 31, 2024, 7:30pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/12 "2024-07-31T19:30:09Z")

</div>

Yeah It does have a E matrix but its just the Identity matrix so I wouldn’t expect it to change anything. That being said if I do

```matlab
%% matlab
sys_cp = ss(sys_cl.A, sys_cl.B, sys_cl.C,sys_cl.D)
sys_cp.E = sys_cl.E
step(sys_cl) # this gives the expected response.

```

![image](https://global.discourse-cdn.com/julialang/original/3X/c/1/c158223228dd3e8be0f93584054bc882b4674160.png)

According to the matlab docs E is

> `E` — Matrix for implicit state-space models `[]` (default) | `Nx`-by-`Nx` matrix  
> Matrix for implicit or descriptor state-space models, specified as a `Nx`-by-`Nx` matrix. `E` is empty by default, meaning that the state equation is explicit. To specify an implicit state equation _E_ _dx_/_dt_ = _Ax_ + _Bu_, set this property to a square matrix of the same size as `A`. See [`dss`](https://www.mathworks.com/help/control/ref/dss.html) for more information about creating descriptor state-space models.

---

<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 31, 2024, 7:32pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/13 "2024-07-31T19:32:18Z")

</div>

That seems very strange, are you sure it’s actually identity, or is one or a few elements of the diagonal non-unit?

---

<div class="post-metadata">

**Author:** ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)\
**Post date:** [July 31, 2024, 7:33pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/14 "2024-07-31T19:33:58Z")

</div>

Is it possible to make the A, B, C and D matrices still available to latecomers? The link no longer works.

---

<div class="post-metadata">

**Author:** ![lstagner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lstagner/32/448_2.png) [@lstagner](https://discourse.julialang.org/u/lstagner)\
**Post date:** [July 31, 2024, 7:40pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/15 "2024-07-31T19:40:33Z")

</div>

actually yeah , your right, its not identity its near identity. I still don’t know how they calculate E thought.

@zdenek_hurak  
Here is a new bson file with ABCD and E matrices  
[https://file.io/SitLMMRnHHZG](https://file.io/SitLMMRnHHZG)

---

<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 31, 2024, 7:43pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/16 "2024-07-31T19:43:53Z")

</div>

DescriptorSystems.jl allows system with non-identity E matrices. Still, it seems strange that the statespace system where the pid controller is filtered with an extremely large bandwidth wouldn’t yield the same result. I wonder if mstlab performs some model reduction in any of the steps.

---

<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:** [August 1, 2024, 4:54am UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/17 "2024-08-01T04:54:51Z")

</div>

> [@lstagner](#):
>
> Here is a new bson file with ABCD and E matrices

Does the original system also have a non-unit E matrix? If so, it’s not strange that you get a different result when no including it.

---

<div class="post-metadata">

**Author:** ![lstagner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lstagner/32/448_2.png) [@lstagner](https://discourse.julialang.org/u/lstagner)\
**Post date:** [August 1, 2024, 7:59pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/18 "2024-08-01T19:59:05Z")

</div>

No the original system without feedback control does not use E. Somehow adding PID feedback causes the combined system to have a non-identity E matrix i.e. a Descriptor System. How this happens? I’m not sure but the change does appear to make the system more numerically stable.

---

<div class="post-metadata">

**Author:** ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)\
**Post date:** [August 1, 2024, 8:41pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/19 "2024-08-01T20:41:01Z")

</div>

I am still puzzled by the very model of the system. The full model `sys` is of order 163 (the matrix A is 163x163). What is then the point in doing this?

> [@lstagner](#):
>
> `sys_new = sys([1379],13);`

Both in Matlab and in Julia I get (unsurprisingly) an error.

---

<div class="post-metadata">

**Author:** ![lstagner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lstagner/32/448_2.png) [@lstagner](https://discourse.julialang.org/u/lstagner)\
**Post date:** [August 1, 2024, 8:46pm UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/20 "2024-08-01T20:46:38Z")

</div>

It’s from a larger system we have coded in matlab and we trying to simplify the problem by only considering a single input and output.

---

<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:** [August 2, 2024, 2:49am UTC](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688/21 "2024-08-02T02:49:11Z")

</div>

> [@lstagner](#):
>
> Somehow adding PID feedback causes the combined system to have a non-identity E matrix i.e. a Descriptor System. How this happens?

A pure derivative term, s, is not a proper system, it cannot be represented as a statespace system. This is why you have to add the low-pass filter in the `pid` constructor in order to be able to convert it to statespace. Non-proper systems can, however, be represented as descriptor systems:

```julia
julia> s = rtf('s')
RationalTransferFunction{Int64, :s, Polynomials.Polynomial{Int64, :s}, 0.0}
s

Continuous-time rational transfer function model.

julia> dss(s)
DescriptorStateSpace{Float64, Matrix{Float64}, Matrix{Float64}}

State matrix A:
2×2 Matrix{Float64}:
 1.0 0.0
 0.0 1.0

Descriptor matrix E:
2×2 Matrix{Float64}:
 0.0 1.0
 0.0 0.0

Input matrix B:
2×1 Matrix{Float64}:
 0.0
 1.0

Output matrix C:
1×2 Matrix{Float64}:
 -1.0 0.0

Feedthrough matrix D:
1×1 Matrix{Float64}:
 0.0

Continuous-time state-space model.

```

I performed all computations involved in your problem using DescriptorSystems.jl and still got an unstable system, so if I were you I would double check the matlab results one more time.

[Next page](https://discourse.julialang.org/t/state-space-model-with-pid-controller-unstable-in-julia-compared-to-matlab/117688.md?page=2)
