Skip to content

Commit 1002dc1

Browse files
authored
Merge pull request #718 from JuliaControl/zeroTi
handle zero integral time
2 parents 3c14fd0 + 26fd7f2 commit 1002dc1

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

src/pid_design.jl

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,15 @@ end
4343
function pid_tf(param_p, param_i, param_d=zero(typeof(param_p)); form=:standard, Ts=nothing, Tf=nothing)
4444
Kp, Ti, Td = convert_pidparams_to_standard(param_p, param_i, param_d, form)
4545
TE = isnothing(Ts) ? Continuous() : Discrete(Ts)
46+
ia = Ti != Inf && Ti != 0 # integral action, 0 would result in division by zero, but typically indicates that the user wants no integral action
4647
if isnothing(Tf)
47-
if Ti != Inf
48+
if ia
4849
return tf([Kp * Td, Kp, Kp / Ti], [1, 0], TE)
4950
else
5051
return tf([Kp * Td, Kp], [1], TE)
5152
end
5253
else
53-
if Ti != Inf
54+
if ia
5455
return tf([Kp * Td, Kp, Kp / Ti], [Tf^2/2, Tf, 1, 0], TE)
5556
else
5657
return tf([Kp * Td, Kp], [Tf^2/2, Tf, 1], TE)
@@ -61,16 +62,27 @@ end
6162
function pid_ss(param_p, param_i, param_d=zero(typeof(param_p)); form=:standard, Ts=nothing, Tf=nothing)
6263
Kp, Ti, Td = convert_pidparams_to_standard(param_p, param_i, param_d, form)
6364
TE = isnothing(Ts) ? Continuous() : Discrete(Ts)
65+
ia = Ti != Inf && Ti != 0 # integral action, 0 would result in division by zero, but typically indicates that the user wants no integral action
6466
if !isnothing(Tf)
65-
A = [0 1 0; 0 0 1; 0 -2/Tf^2 -2/Tf]
66-
B = [0; 0; 1]
67-
C = 2 * Kp / Tf^2 * [1/Ti 1 Td]
67+
if ia
68+
A = [0 1 0; 0 0 1; 0 -2/Tf^2 -2/Tf]
69+
B = [0; 0; 1]
70+
C = 2 * Kp / Tf^2 * [1/Ti 1 Td]
71+
else
72+
A = [0 1; -2/Tf^2 -2/Tf]
73+
B = [0; 1]
74+
C = 2 * Kp / Tf^2 * [1 Td]
75+
end
6876
D = 0
6977
elseif Td == 0
70-
A = 0
71-
B = 1
72-
C = Kp / Ti
73-
D = Kp
78+
if ia
79+
A = 0
80+
B = 1
81+
C = Kp / Ti # Ti == 0 would result in division by zero, but typically indicates that the user wants no integral action
82+
D = Kp
83+
else
84+
return StateSpace([Kp], TE)
85+
end
7486
else
7587
throw(DomainError("cannot create controller as a state space if Td != 0 without a filter. Either create the controller as a transfer function, pid(TransferFunction; params...), or supply Tf to create a filter."))
7688
end

test/test_pid_design.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ C, kp, ki = loopshapingPI(P, ωp, phasemargin=60, form=:parallel, doplot=true)
1616
# ss
1717
@test tf(pid(1.0, 1, 0; state_space=true)) == tf(1) + tf(1,[1,0])
1818

19+
# Zero integral action
20+
Tf = 0.01
21+
@test tf(pid(2.0, 0; state_space=true, Tf)) minreal(pid(2.0, 0; state_space=false, Tf))
22+
23+
@test tf(pid(2.0, 0, 1; state_space=true, Tf)) minreal(pid(2.0, 0, 1; state_space=false, Tf))
24+
1925
# Test pidplots
2026
C = pid(1.0, 1, 1)
2127
pidplots(C, :nyquist, :gof, :pz, :controller; params_p=[1.0, 2], params_i=[2, 3], grid=true) # Simply test that the functions runs and not errors

0 commit comments

Comments
 (0)