Skip to content

Commit

Permalink
Merge pull request #19 from JuliaComputing/onoff
Browse files Browse the repository at this point in the history
add OnOffController
  • Loading branch information
baggepinnen authored Sep 4, 2024
2 parents 90a5a83 + 697cd43 commit ba3e6ed
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/ModelingToolkitSampledData.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export DiscreteIntegrator, DiscreteDerivative, Delay, Difference, ZeroOrderHold,
DiscretePIDParallel, DiscretePIDStandard, DiscreteStateSpace,
DiscreteTransferFunction, NormalNoise, UniformNoise, Quantization,
ExponentialFilter
export DiscreteOnOffController
include("discrete_blocks.jl")

end
40 changes: 40 additions & 0 deletions src/discrete_blocks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -971,3 +971,43 @@ Exponential filtering with input-output relation ``y(z) ~ (1 - a) y(z-1) + a u(z
end
end

"""
DiscreteOnOffController(b = 0.1, bool = true)
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.
# Connectors:
- `reference`: The reference signal to the controller
- `input`: The measurement feedback
- `output`: The control signal output
# Parameters:
- `b`: Bandwidth around reference signal within which the controller does not react
- `bool`: (structural) If true (default), the controller switches between 0 and 1. If false, the controller switches between -1 and 1.
- `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.
"""
@mtkmodel DiscreteOnOffController begin
@extend u, y = siso = SISO()
@components begin
reference = RealInput()
end
@structural_parameters begin
z = ShiftIndex()
bool = true
end
@parameters begin
b = 0.1, [description = "Bandwidth around reference signal"]
k = 1, [description = "Controller gain"]
end
@variables begin
s(t)=true, [description = "Internal variable"]
end
@equations begin
s(z) ~ (y(z-1) == k) & (u(z) < reference.u(z) + b/2) | (u(z) < reference.u(z) - b/2)
if bool
y(z) ~ k*s(z)
else
y(z) ~ k*(2*s(z) - 1)
end
end
end
27 changes: 27 additions & 0 deletions test/test_discrete_blocks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,33 @@ end
@test 0 uy
end

@testset "OnOff" begin
@info "Testing OnOff"
cl = Clock(0.1)
z = ShiftIndex(cl)
@mtkmodel OnOffModel begin
@components begin
onoff = DiscreteOnOffController(; z, bool=false)
c = Constant(k=1)
end
@variables begin
x(t) = 0
end
@equations begin
onoff.u ~ Sample(cl)(x)
connect(c.output, onoff.reference)
D(x) ~ 0.1x + Hold(onoff.y)
end
end
@named m = OnOffModel()
m = complete(m)
ssys = structural_simplify(IRSystem(m))
prob = ODEProblem(ssys, [m.onoff.y(z-1) => 0], (0.0, 4.0))
sol = solve(prob, Tsit5(), dtmax=0.1)
# plot(sol, idxs=[m.x, m.onoff.y], title="On-off control of an unstable first-order system")
@test 0.89 <= sol(4, idxs=m.x) <= 1.11
end


@testset "ExponentialFilter" begin
@info "Testing ExponentialFilter"
Expand Down

0 comments on commit ba3e6ed

Please sign in to comment.