Skip to content

Commit ba3e6ed

Browse files
authored
Merge pull request #19 from JuliaComputing/onoff
add OnOffController
2 parents 90a5a83 + 697cd43 commit ba3e6ed

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

src/ModelingToolkitSampledData.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export DiscreteIntegrator, DiscreteDerivative, Delay, Difference, ZeroOrderHold,
99
DiscretePIDParallel, DiscretePIDStandard, DiscreteStateSpace,
1010
DiscreteTransferFunction, NormalNoise, UniformNoise, Quantization,
1111
ExponentialFilter
12+
export DiscreteOnOffController
1213
include("discrete_blocks.jl")
1314

1415
end

src/discrete_blocks.jl

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,3 +971,43 @@ Exponential filtering with input-output relation ``y(z) ~ (1 - a) y(z-1) + a u(z
971971
end
972972
end
973973

974+
"""
975+
DiscreteOnOffController(b = 0.1, bool = true)
976+
977+
Discrete-time On-Off controller with hysteresis. The controller switches between two states based on the error signal `reference-input`. The controller is in the on-state if the error signal is within the bandwidth `b` around the reference signal, and in the off-state otherwise.
978+
979+
# Connectors:
980+
- `reference`: The reference signal to the controller
981+
- `input`: The measurement feedback
982+
- `output`: The control signal output
983+
984+
# Parameters:
985+
- `b`: Bandwidth around reference signal within which the controller does not react
986+
- `bool`: (structural) If true (default), the controller switches between 0 and 1. If false, the controller switches between -1 and 1.
987+
- `k`: Controller gain. The output of the contorller is scaled by this gain, i.e., `k = 2, bool = false` will result in an output of -2 or 2.
988+
"""
989+
@mtkmodel DiscreteOnOffController begin
990+
@extend u, y = siso = SISO()
991+
@components begin
992+
reference = RealInput()
993+
end
994+
@structural_parameters begin
995+
z = ShiftIndex()
996+
bool = true
997+
end
998+
@parameters begin
999+
b = 0.1, [description = "Bandwidth around reference signal"]
1000+
k = 1, [description = "Controller gain"]
1001+
end
1002+
@variables begin
1003+
s(t)=true, [description = "Internal variable"]
1004+
end
1005+
@equations begin
1006+
s(z) ~ (y(z-1) == k) & (u(z) < reference.u(z) + b/2) | (u(z) < reference.u(z) - b/2)
1007+
if bool
1008+
y(z) ~ k*s(z)
1009+
else
1010+
y(z) ~ k*(2*s(z) - 1)
1011+
end
1012+
end
1013+
end

test/test_discrete_blocks.jl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,33 @@ end
461461
@test 0 uy
462462
end
463463

464+
@testset "OnOff" begin
465+
@info "Testing OnOff"
466+
cl = Clock(0.1)
467+
z = ShiftIndex(cl)
468+
@mtkmodel OnOffModel begin
469+
@components begin
470+
onoff = DiscreteOnOffController(; z, bool=false)
471+
c = Constant(k=1)
472+
end
473+
@variables begin
474+
x(t) = 0
475+
end
476+
@equations begin
477+
onoff.u ~ Sample(cl)(x)
478+
connect(c.output, onoff.reference)
479+
D(x) ~ 0.1x + Hold(onoff.y)
480+
end
481+
end
482+
@named m = OnOffModel()
483+
m = complete(m)
484+
ssys = structural_simplify(IRSystem(m))
485+
prob = ODEProblem(ssys, [m.onoff.y(z-1) => 0], (0.0, 4.0))
486+
sol = solve(prob, Tsit5(), dtmax=0.1)
487+
# plot(sol, idxs=[m.x, m.onoff.y], title="On-off control of an unstable first-order system")
488+
@test 0.89 <= sol(4, idxs=m.x) <= 1.11
489+
end
490+
464491

465492
@testset "ExponentialFilter" begin
466493
@info "Testing ExponentialFilter"

0 commit comments

Comments
 (0)