JuliaControl / ControlSystems.jl

A Control Systems Toolbox for Julia
https://juliacontrol.github.io/ControlSystems.jl/stable/
Other
515 stars 85 forks source link

Equivalent to Simulink "Saturation" block #228

Closed non-Jedi closed 2 years ago

non-Jedi commented 5 years ago

When simulating real-world systems, the saturation block in simulink is very important. Would it be possible to include something like that to compose with transfer functions?

https://www.mathworks.com/help/simulink/slref/saturation.html

baggepinnen commented 5 years ago

The saturation is a nonlinear function, whereas transfer functions are linear. You could simulate a saturation on the input using the function interface to lsim or the Simulator type, but for more advanced usage you would have to resort to Differentialequations.jl directly.

non-Jedi commented 5 years ago

Is there an example somewhere of using the function interface to lsim to hold the output of one particular tf to some saturation limits? I have to admit I'm slightly out of my depth here, but if it's possible without having to actually write out the system of ODEs, that would be great.

My current usage looks something like:

using ControlSystems

Gp = tf(args1...) # Process tf
Gc = tf(args2...) # PID controller tf
Gv = tf(args3...) # actuator tf
Gd = tf(args4...) # disturbance tf
Gm = tf(args4...) # sensor tf

# tf between disturbance and controlled variable
YD = Gd * feedback(tf(1), Gm * Gc * Gv * Gp)

lsimplot(YD, (x,t) -> [t < 30.0 ? 33.0 : 0.0], 0:0.2:100)

So ideally I'd like to put the saturation block between Gc and Gv. I don't see any examples that are related to this kind of thing.

baggepinnen commented 5 years ago

No, connecting systems like that is not something that is supported so far. You may either try your luck with Differentialequations.jl directly, or possibly one of the modeling languages like Modia.jl or Modelingtoolkit.jl

mfalt commented 5 years ago

This is definetely something where we could consider creating a simple API for creating the required differential equations (in the case of no direct terms). For example

dGp, fGp = diffeq(Gp)
dGc, fGc = diffeq(Gc)
# Functions so that dG returns derivative of internal state and
# u = fGc(x1), where x1 is internal state of controller
# y = fGp(x2) , where x2 is internal state of process

# Some definiton of feedback that could be returned by Controllsystems.jl
function dx(x,r)
    x1 = # appropriate index in x vector
    x2 = # appropriate index in x vector
    u = fGc(x1)
    y = fGp(x2)
    e = r - y
    [dGc(x1, e); dGp(x2, u)]
 end
y(x) = fGp(x["indices for x2"])

The dx function can now be used in DifferentialEquations.jl, and y(x) would return output.

There are some details regarding efficiency and direct terms, but in general it would make it easier for the user to add nonlinearities and build their own differential equations.

baggepinnen commented 5 years ago

The Simulator type already does more or less this. A library of nonlinearities feels somewhat out of scope, because people would then want not only saturations, but all other common nonlinearities as well. It would perhaps fit well into an add-on package, but making use of the existing ecosystem for simulation is probably a more powerful apporach.

mfalt commented 5 years ago

It is not clear how you would use the Simulator directly for the feedback case. I agree that we don't need a library of non-linearities, but what we could add is some simple manipulations (for example on the Simulator type) such as feedback with other Simulators.

baggepinnen commented 3 years ago

ComponentArrays.jl was built in part to facilitate composing dynamical systems together, they have a tutorial using ControlSystems here https://jonniedie.github.io/ComponentArrays.jl/dev/examples/adaptive_control/#Helper-Functions-1 The interface in that tutorial is rather low-level, but I believe it could be made very approachable with a slightly higher-level interface built on top.

baggepinnen commented 2 years ago

https://juliacontrol.github.io/ControlSystems.jl/stable/lib/nonlinear/#Control-signal-saturation