Skip to content

Commit d881856

Browse files
authored
Merge pull request #18 from JuliaControl/wp
Change `b` to `wp` for consistency
2 parents 7de1c2b + 529c1ea commit d881856

File tree

4 files changed

+24
-19
lines changed

4 files changed

+24
-19
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "DiscretePIDs"
22
uuid = "c1363496-6848-4723-8758-079b737f6baf"
33
authors = ["Fredrik Bagge Carlson"]
4-
version = "0.1.7"
4+
version = "1.0.0"
55

66
[deps]
77
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77
This package implements a discrete-time PID controller as an approximation of the continuous-time PID controller given by
8-
$$U(s) = K \left( bR(s) - Y(s) + \dfrac{1}{sT_i} \left( R(s) - Y(s) \right) + \dfrac{sT_d}{1 + s T_d / N}(w_d R(s) - Y(s)) \right) + U_\textrm{ff}(s),$$
8+
$$U(s) = K \left( w_p R(s) - Y(s) + \dfrac{1}{sT_i} \left( R(s) - Y(s) \right) + \dfrac{sT_d}{1 + s T_d / N}(w_d R(s) - Y(s)) \right) + U_\textrm{ff}(s),$$
99
where
1010
- $u(t) \leftrightarrow U(s)$ is the control signal
1111
- $y(t) \leftrightarrow Y(s)$ is the measurement signal
@@ -15,7 +15,7 @@ where
1515
- $T_i$ is the integral time
1616
- $T_d$ is the derivative time
1717
- $N$ is a parameter that limits the gain of the derivative term at high frequencies, typically ranges from 2 to 20,
18-
- $b \in [0, 1]$ is a parameter that gives the proportion of the reference signal that appears in the proportional term.
18+
- $w_p \in [0, 1]$ is a parameter that gives the proportion of the reference signal that appears in the proportional term.
1919
- $w_d \in [0, 1]$ is a parameter that gives the proportion of the reference signal that appears in the derivative term (default 0).
2020

2121
*Saturation* of the controller output is parameterized by $u_{\min}$ and $u_{\max}$, and the integrator *anti-windup* is parameterized by the tracking time $T_\mathrm{t}$.
@@ -24,7 +24,7 @@ where
2424

2525
Construct a controller by
2626
```julia
27-
pid = DiscretePID(; K = 1, Ti = false, Td = false, Tt = (Ti*Td), N = 10, b = 1, wd = 0, umin = -Inf, umax = Inf, Ts, I = 0, D = 0, yold = 0)
27+
pid = DiscretePID(; K = 1, Ti = false, Td = false, Tt = (Ti*Td), N = 10, wp = 1, wd = 0, umin = -Inf, umax = Inf, Ts, I = 0, D = 0, yold = 0)
2828
```
2929
and compute the control signal at a given time using
3030
```julia
@@ -220,7 +220,7 @@ K (b r - y + 1/T_i (r - y) - s T_d y/(1 + s T_d / N))
220220
using the function `K, Ti, Td = parallel2standard(kp, ki, kd)` or, if a filter parameter is included, `K, Ti, Td, N = parallel2standard(kp, ki, kd, Tf)`. This function also accepts a vector of parameters in the same order, in which case a vector is returned.
221221

222222
## Details
223-
- The derivative term by default only acts on the (filtered) measurement and not the command signal. It is thus safe to pass step changes in the reference to the controller. Set `wd = 1` to let the derivative act on the error `r-y` instead. The parameter $b$ can further be set to zero to avoid step changes in the control signal in response to step changes in the reference.
223+
- The derivative term by default only acts on the (filtered) measurement and not the command signal. It is thus safe to pass step changes in the reference to the controller. Set `wd = 1` to let the derivative act on the error `r-y` instead. The parameter $w_p$ can further be set to zero to avoid step changes in the control signal in response to step changes in the reference.
224224
- Bumpless transfer when updating `K` is realized by updating the state `I`. See the docs for `set_K!` for more details.
225225
- The total control signal $u(t)$ (PID + feedforward) is limited by the integral anti-windup.
226226
- The integrator is discretized using a forward difference (no direct term between the input and output through the integral state) while the derivative is discretized using a backward difference. This approximation has the advantage that it is always stable and that the sampled pole goes to zero when $T_d$ goes to zero. Tustin's approximation gives an approximation such that the pole instead goes to $z = −1$ as $T_d$ goes to zero.

src/DiscretePIDs.jl

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ mutable struct DiscretePID{T} <: Function
1919
"Maximum derivative gain"
2020
const N::T
2121
"Fraction of set point in prop. term"
22-
b::T
22+
wp::T
2323
"Fraction of set point in derivative term"
2424
wd::T
2525
"Low output limit"
@@ -41,7 +41,7 @@ mutable struct DiscretePID{T} <: Function
4141
end
4242

4343
"""
44-
DiscretePID(; K = 1, Ti = false, Td = false, Tt = √(Ti*Td), N = 10, b = 1, wd = 0, umin = -Inf, umax = Inf, Ts, I = 0, D = 0, yold = 0)
44+
DiscretePID(; K = 1, Ti = false, Td = false, Tt = √(Ti*Td), N = 10, wp = 1, wd = 0, umin = -Inf, umax = Inf, Ts, I = 0, D = 0, yold = 0)
4545
4646
A discrete-time PID controller with set-point weighting and integrator anti-windup.
4747
The controller is implemented on the standard form
@@ -50,7 +50,7 @@ u = K \\left( e + \\dfrac{1}{Ti} \\int e dt + T_d \\dfrac{de}{dt} \\right)
5050
```
5151
5252
```math
53-
U(s) = K \\left( bR(s) - Y(s) + \\dfrac{1}{sT_i} \\left( R(s) Y(s) \\right) - \\dfrac{sT_d}{1 + s T_d / N}(Y(s) - w_d R(s))
53+
U(s) = K \\left( wp R(s) - Y(s) + \\dfrac{1}{sT_i} \\left( R(s) Y(s) \\right) - \\dfrac{sT_d}{1 + s T_d / N}(Y(s) - w_d R(s))
5454
```
5555
5656
Call the controller like this
@@ -65,7 +65,7 @@ u = calculate_control!(pid, r, y, uff) # Equivalent to the above
6565
- `Td`: Derivative time
6666
- `Tt`: Reset time for anti-windup
6767
- `N`: Maximum derivative gain
68-
- `b`: Fraction of set point in proportional term
68+
- `wp`: Fraction of set point in proportional term
6969
- `wd`: Fraction of set point in derivative term (default 0)
7070
- `umin`: Low output limit
7171
- `umax`: High output limit
@@ -82,8 +82,9 @@ function DiscretePID(;
8282
Td = false,
8383
Tt = Ti > 0 && Td > 0 ? typeof(K)((Ti*Td)) : typeof(K)(10),
8484
N = typeof(K)(10),
85-
b = typeof(K)(1),
85+
wp = typeof(K)(1),
8686
wd = zero(typeof(K)),
87+
b = nothing,
8788
umin = typemin(typeof(K)),
8889
umax = typemax(typeof(K)),
8990
Ts,
@@ -96,10 +97,14 @@ function DiscretePID(;
9697
else
9798
bi = zero(K * Ts)
9899
end
100+
if b !== nothing
101+
wp = typeof(K)(b)
102+
@warn "Parameter `b` is deprecated. Use `wp` instead."
103+
end
99104
Tt 0 || throw(ArgumentError("Tt must be positive"))
100105
Td 0 || throw(ArgumentError("Td must be positive"))
101106
N 0 || throw(ArgumentError("N must be positive"))
102-
0 b 1 || throw(ArgumentError("b must be ∈ [0, 1]"))
107+
0 wp 1 || throw(ArgumentError("wp must be ∈ [0, 1]"))
103108
0 wd 1 || throw(ArgumentError("wd must be ∈ [0, 1]"))
104109
umax > umin || throw(ArgumentError("umax must be greater than umin"))
105110

@@ -111,9 +116,9 @@ function DiscretePID(;
111116
ad = Td / (Td + N * Ts)
112117
bd = K * N * ad
113118

114-
T2 = promote_type(typeof.((K, Ti, Td, Tt, N, b, wd, umin, umax, Ts, bi, ar, bd, ad, I, D, yold))...)
119+
T2 = promote_type(typeof.((K, Ti, Td, Tt, N, wp, wd, umin, umax, Ts, bi, ar, bd, ad, I, D, yold))...)
115120

116-
DiscretePID(T2.((K, Ti, Td, Tt, N, b, wd, umin, umax, Ts, bi, ar, bd, ad, I, D, yold))...)
121+
DiscretePID(T2.((K, Ti, Td, Tt, N, wp, wd, umin, umax, Ts, bi, ar, bd, ad, I, D, yold))...)
117122
end
118123

119124
"""
@@ -129,7 +134,7 @@ function set_K!(pid::DiscretePID, K, r, y)
129134
pid.bd = K * pid.N * pid.ad
130135
if pid.Ti > 0
131136
pid.bi = K * pid.Ts / pid.Ti
132-
pid.I = pid.I + Kold*(pid.b*r - y) - K*(pid.b*r - y)
137+
pid.I = pid.I + Kold*(pid.wp*r - y) - K*(pid.wp*r - y)
133138
end
134139
nothing
135140
end
@@ -177,7 +182,7 @@ function calculate_control!(pid::DiscretePID{T}, r0, y0, uff0=0; yd=nothing) whe
177182
r = T(r0)
178183
y = T(y0)
179184
uff = T(uff0)
180-
P = pid.K * (pid.b * r - y)
185+
P = pid.K * (pid.wp * r - y)
181186
e = pid.wd * r - y # weighted error for derivative
182187
if yd === nothing
183188
pid.D = pid.ad * pid.D + pid.bd * (e - pid.yold)
@@ -233,10 +238,10 @@ end
233238
K, Ti, Td, N = parallel2standard(Kp, Ki, Kd, Tf)
234239
235240
Convert parameters from form "parallel" form with first-order filter
236-
``K_p (br-y) + K_i (r-y)/s - K_d s y/(Tf s + 1)``
241+
``K_p (w_p r-y) + K_i (r-y)/s - K_d s y/(Tf s + 1)``
237242
238243
to "standard" form used in DiscretePID:
239-
``K (br-y + (r-y)/(T_i s) - T_d s y/(T_d / N s + 1))``
244+
``K (w_p r-y + (r-y)/(T_i s) - T_d s y/(T_d / N s + 1))``
240245
241246
You may provide either four arguments or an array with four elements in the same order.
242247
"""

test/runtests.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ res3 = lsim(P, ctrl, Tf)
148148
## PI control with sp weighting
149149
Tf = 10
150150
Ti = 1
151-
b = 0.0
152-
pid = DiscretePID(; K, Ts, Ti, b)
151+
wp = 0.0
152+
pid = DiscretePID(; K, Ts, Ti, wp)
153153
ctrl = function(x,t)
154154
y = (P.C*x)[]
155155
r = 1

0 commit comments

Comments
 (0)