Skip to content

Commit 4cf7319

Browse files
committed
add comparison to readme
1 parent fb672ae commit 4cf7319

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

README.md

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ The following example simulates a feedback control system containing a PID contr
4848

4949
```julia
5050
using DiscretePIDs, ControlSystemsBase, Plots
51-
Tf = 15 # Simulation time
51+
Tf = 30 # Simulation time
5252
K = 1 # Proportional gain
5353
Ti = 1 # Integral time
5454
Td = 1 # Derivative time
@@ -60,7 +60,7 @@ pid = DiscretePID(; K, Ts, Ti, Td)
6060
ctrl = function(x,t)
6161
y = (P.C*x)[] # measurement
6262
d = 1 # disturbance
63-
r = 0 # reference
63+
r = (t >= 15) # reference
6464
u = pid(r, y) # control signal
6565
u + d # Plant input is control signal + disturbance
6666
end
@@ -69,10 +69,23 @@ res = lsim(P, ctrl, Tf)
6969

7070
plot(res, plotu=true); ylabel!("u + d", sp=2)
7171
```
72-
![Simulation result](https://user-images.githubusercontent.com/3797491/172366365-c1533aed-e877-499d-9ebb-01df62107dfb.png)
72+
![Simulation result](https://github.com/user-attachments/assets/2de34be7-4811-4801-b6ca-bc4c932b3331)
7373

7474
Here we simulated a linear plant, in which case we were able to call `ControlSystems.lsim` specialized for linear systems. Below, we show two methods for simulation that works with a nonlinear plant, but we still use a linear system to make the comparison easier.
7575

76+
For comparison, we also perform the same simulation with a two degree-of-freedom PID controller
77+
```julia
78+
using ControlSystemsBase, DiscretePIDs, Plots
79+
C = pid_2dof(K, Ti, Td; Ts)
80+
Gcl = feedback(P, C, W1=1, U2=2, W2=1, Z2=1, pos_feedback=true)
81+
t = 0:Ts:Tf
82+
u = [ones(length(t)) t .>= 15]' # Input signal [d; r]
83+
simres = lsim(Gcl, u)
84+
plot(simres, plotu=true, lab=["y" "u" "d" "r"], layout=(2,1), sp=[1 2 2 1], ylabel="")
85+
```
86+
![Simulation result](https://github.com/user-attachments/assets/1267fc64-72f1-4560-ba66-ccf88bcae150)
87+
88+
7689
### Example using DifferentialEquations.jl
7790

7891
This example is identical to the one above except for using [DifferentialEquations.jl](https://docs.sciml.ai/DiffEqDocs/stable/) for the simulation, which makes it possible to consider more complex plants, in particular nonlinear ones.
@@ -89,7 +102,7 @@ We use `DiffEqCallbacks.PeriodicCallback`, in which we perform the PID-controlle
89102
```julia
90103
using DiscretePIDs, ControlSystemsBase, OrdinaryDiffEq, DiffEqCallbacks, Plots
91104

92-
Tf = 15 # Simulation time
105+
Tf = 30 # Simulation time
93106
K = 1 # Proportional gain
94107
Ti = 1 # Integral time
95108
Td = 1 # Derivative time
@@ -109,16 +122,17 @@ end
109122

110123
cb = PeriodicCallback(Ts) do integrator
111124
p = integrator.p # Extract the parameter object from the integrator
112-
(; C, r, d) = p # Extract the reference and disturbance from the parameter object
125+
(; C, d) = p # Extract the reference and disturbance from the parameter object
113126
x = integrator.u[1:P.nx] # Extract the state (the integrator uses the variable name `u` to refer to the state, in control theory we typically use the variable name `x`)
127+
r = (integrator.t >= 15) # Reference
114128
y = (C*x)[] # Simulated measurement
115129
u = pid(r, y) # Compute the control signal
116130
integrator.u[P.nx+1:end] .= u # Update the control-signal state variable
117131
end
118132

119-
parameters = (; A, B, C, r=0, d=1) # reference = 0, disturbance = 1
133+
parameters = (; A, B, C, d=1) # disturbance = 1
120134
xu0 = zeros(P.nx + P.nu) # Initial state of the system + control signals
121-
prob = ODEProblem(dynamics!, xu0, (0, Tf), parameters, callback=cb) # reference = 0, disturbance = 1
135+
prob = ODEProblem(dynamics!, xu0, (0, Tf), parameters, callback=cb) # disturbance = 1
122136
sol = solve(prob, Tsit5(), saveat=Ts)
123137

124138
plot(sol, layout=(2, 1), ylabel=["x" "u"], lab="")
@@ -144,24 +158,25 @@ x(t+T_s) \approx x^+ = \phi(x(t), u(t), p(t), t,T_s).
144158

145159
```julia
146160
using DiscretePIDs, ControlSystemsBase, SeeToDee, Plots
147-
Tf = 15 # Simulation time
161+
Tf = 30 # Simulation time
148162
K = 1 # Proportional gain
149163
Ti = 1 # Integral time
150164
Td = 1 # Derivative time
151165
Ts = 0.01 # sample time
152166
P = ss(tf(1, [1, 1])) # Process to be controlled, in continuous time
153167
A,B,C = ssdata(P) # Extract the system matrices
154-
p = (; A, B, C, r=0, d=1) # reference = 0, disturbance = 1
168+
p = (; A, B, C, d=1) # reference = 0, disturbance = 1
155169

156170
pid = DiscretePID(; K, Ts, Ti, Td)
157171

158172
ctrl = function(x,p,t)
173+
r = (t >= 15) # reference
159174
y = (p.C*x)[] # measurement
160175
pid(r, y)
161176
end
162177

163178
function dynamics(x, u, p, t) # This time we define the dynamics as a function of the state and control signal
164-
A, B, C, r, d = p # We store the reference and disturbance in the parameter object
179+
A, B, C, d = p # We store the reference and disturbance in the parameter object
165180
A*x .+ B*(u .+ d) # Plant input is control signal + disturbance
166181
end
167182
discrete_dynamics = SeeToDee.Rk4(dynamics, Ts) # Create a discrete-time dynamics function

0 commit comments

Comments
 (0)