Skip to content

Commit b6214f4

Browse files
authored
add slew-rate limiter (#25)
* add slew-rate limiter * add to docs * rm plot
1 parent 60ff089 commit b6214f4

File tree

4 files changed

+94
-1
lines changed

4 files changed

+94
-1
lines changed

docs/src/blocks.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- [`Difference`](@ref)
1010
- [`DiscreteDerivative`](@ref)
1111
- [`DiscreteIntegrator`](@ref)
12+
- [`DiscreteSlewRateLimiter`](@ref)
1213
- [`Sampler`](@ref)
1314
- [`ZeroOrderHold`](@ref)
1415

src/ModelingToolkitSampledData.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export DiscreteIntegrator, DiscreteDerivative, Delay, Difference, ZeroOrderHold,
88
ClockChanger,
99
DiscretePIDParallel, DiscretePIDStandard, DiscreteStateSpace,
1010
DiscreteTransferFunction, NormalNoise, UniformNoise, Quantization,
11-
ExponentialFilter
11+
DiscreteSlewRateLimiter, ExponentialFilter
1212
export DiscreteOnOffController
1313
include("discrete_blocks.jl")
1414

src/discrete_blocks.jl

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,70 @@ See also [ControlSystemsMTK.jl](https://juliacontrol.github.io/ControlSystemsMTK
878878
# compose(ODESystem(eqs, t, sts, pars; name = name), input, output)
879879
# end
880880

881+
882+
"""
883+
DiscreteSlewRateLimiter(rate = 1.0, rate_negative = rate)
884+
885+
A discrete-time slew rate limiter that limits the rate of change of the input signal.
886+
887+
Note, the sample interval is not taken into account when computing the rate of change, the difference between two consequetive samples is saturated.
888+
889+
# Parameters:
890+
- `rate`: Slew rate limit (in positive/increasing direction). Must be a positive number.
891+
- `rate_negative`: Negative slew rate limit, defaults to `rate`. Must be a positive number.
892+
893+
# Variables
894+
- `d`: Unsaturated rate of change of the input signal
895+
- `u`: Input signal
896+
- `y`: Output signal (saturated slew rate)
897+
898+
# Connectors:
899+
- `input`
900+
- `output`
901+
902+
# Example
903+
```
904+
cl = Clock(0.1)
905+
z = ShiftIndex(cl)
906+
@mtkmodel SlweRateLimiterModel begin
907+
@components begin
908+
input = Sine(amplitude=1, frequency=0.8)
909+
limiter = DiscreteSlewRateLimiter(; z, rate=0.4, rate_negative = 0.3)
910+
end
911+
@variables begin
912+
x(t) = 0 # Dummy variable to workaround JSCompiler bug
913+
end
914+
@equations begin
915+
connect(input.output, limiter.input)
916+
D(x) ~ 0.1x + Hold(limiter.y)
917+
end
918+
end
919+
@named m = SlweRateLimiterModel()
920+
m = complete(m)
921+
ssys = structural_simplify(IRSystem(m))
922+
prob = ODEProblem(ssys, [m.limiter.y(z-1) => 0], (0.0, 2.0))
923+
sol = solve(prob, Tsit5(), dtmax=0.01)
924+
plot(sol, idxs=[m.input.output.u, m.limiter.y], title="Slew rate limited sine wave")
925+
```
926+
"""
927+
@mtkmodel DiscreteSlewRateLimiter begin
928+
@extend u, y = siso = SISO()
929+
@structural_parameters begin
930+
z = ShiftIndex()
931+
end
932+
@parameters begin
933+
rate = 1.0, [description = "Slew rate limit"]
934+
rate_negative = rate, [description = "Negative slew rate limit"]
935+
end
936+
@variables begin
937+
d(t)
938+
end
939+
@equations begin
940+
d(z) ~ u(z) - y(z-1)
941+
y(z) ~ y(z-1) + clamp(d(z), -rate_negative, rate)
942+
end
943+
end
944+
881945
"""
882946
Quantization
883947

test/test_discrete_blocks.jl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,35 @@ end
385385
# @test reduce(vcat, sol((0:10) .+ 1e-2))[:]≈[zeros(2); 1; zeros(8)] atol=1e-2
386386
# end*
387387

388+
##
389+
@testset "SlewRateLimiter" begin
390+
@info "Testing SlewRateLimiter"
391+
cl = Clock(0.1)
392+
z = ShiftIndex(cl)
393+
@mtkmodel SlewRateLimiterModel begin
394+
@components begin
395+
input = Sine(amplitude=1, frequency=0.8)
396+
limiter = DiscreteSlewRateLimiter(; z, rate=0.4, rate_negative = 0.3)
397+
end
398+
@variables begin
399+
x(t) = 0 # Dummy variable to workaround JSCompiler bug
400+
end
401+
@equations begin
402+
connect(input.output, limiter.input)
403+
D(x) ~ 0.1x + Hold(limiter.y)
404+
end
405+
end
406+
@named m = SlewRateLimiterModel()
407+
m = complete(m)
408+
ssys = structural_simplify(IRSystem(m))
409+
prob = ODEProblem(ssys, [m.limiter.y(z-1) => 0], (0.0, 2.0))
410+
sol = solve(prob, Tsit5(), dtmax=0.01)
411+
# plot(sol, idxs=[m.input.output.u, m.limiter.y], title="Slew rate limited sine wave")
412+
@test maximum(diff(sol[m.limiter.y])) 0.4
413+
@test minimum(diff(sol[m.limiter.y])) -0.3
414+
end
388415

416+
##
389417
@testset "quantization" begin
390418
@info "Testing quantization"
391419

0 commit comments

Comments
 (0)