Skip to content

Commit

Permalink
Merge pull request #7 from JuliaControl/fp2
Browse files Browse the repository at this point in the history
convert signals to correct type before computations
  • Loading branch information
baggepinnen authored Jun 29, 2023
2 parents 6450135 + 6585eaf commit a2c1770
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "DiscretePIDs"
uuid = "c1363496-6848-4723-8758-079b737f6baf"
authors = ["Fredrik Bagge Carlson"]
version = "0.1.2"
version = "0.1.3"

[compat]
julia = "1.7"
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ u = calculate_control!(pid, r, y, uff)

The parameters $K, T_i, T_d$ may be updated using the functions, `set_K!, set_Ti!, set_Td!`.

The numeric type used by the controller (the `T` in `DiscretePID{T}`) is determined by the types of the parameters. To use a custom number type, e.g., a fixed-point number type, simply pass the parameters as that type, see example below. The controller will automatically convert measurements and references to this type before performing the control calculations.

## Example using ControlSystems:
The following example simulates the PID controller using ControlSystems.jl. We will simulate a load disturbance $d(t) = 1$ entering on the process input, while the reference is $r(t) = 0$.

Expand Down Expand Up @@ -125,7 +127,7 @@ pid = DiscretePID(; K = T(K), Ts = T(Ts), Ti = T(Ti), Td = T(Td))
res_fp = lsim(P, ctrl, Tf)
plot([res, res_fp], plotu=true, lab=["Float64" "" string(T) ""]); ylabel!("u + d", sp=2)
```
![Fixed-point simulation result](https://user-images.githubusercontent.com/3797491/249722782-2157d625-7eb0-4f77-b630-69199237f164.png)
![Fixed-point simulation result](https://user-images.githubusercontent.com/3797491/249732319-0a3890d5-cb9c-45c2-93c7-20d3c7db0cf2.png)

The fixed-point controller behaves roughly the same in this case, but artifacts are clearly visible. If the number of bits used for the fractional part is decreased, the controller will start to misbehave.

Expand Down
6 changes: 5 additions & 1 deletion src/DiscretePIDs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,12 @@ end
(pid)(r, y, uff=0) # Alternative syntax
Calculate the control output from the PID controller when `r` is the reference (set point), `y` is the latest measurement and `uff` is the feed-forward contribution.
If the type of the input arguments differ from the numeric type used by the PID controller, they will be converted before computations are performed.
"""
function calculate_control!(pid::DiscretePID, r, y, uff=0)
function calculate_control!(pid::DiscretePID{T}, r0, y0, uff0=0) where T
r = T(r0)
y = T(y0)
uff = T(uff0)
P = pid.K * (pid.b * r - y)
pid.D = pid.ad * pid.D - pid.bd * (y - pid.yold)
v = P + pid.I + pid.D + uff
Expand Down
2 changes: 1 addition & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ res2 = lsim(P, ctrl, Tf)

## Test with FixedPointNumbers
using FixedPointNumbers
T = Fixed{Int16, 10} # 16-bit signed fixed-point with 11 bits for the fractional part
T = Fixed{Int16, 10} # 16-bit signed fixed-point with 10 bits for the fractional part
pid = DiscretePID(; K = T(K), Ts = T(Ts), Ti = T(Ti), Td = T(Td))
@test pid isa DiscretePID{T}

Expand Down

0 comments on commit a2c1770

Please sign in to comment.