Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- [`Difference`](@ref)
- [`DiscreteDerivative`](@ref)
- [`DiscreteIntegrator`](@ref)
- [`DiscreteSlewRateLimiter`](@ref)
- [`Sampler`](@ref)
- [`ZeroOrderHold`](@ref)

Expand Down
2 changes: 1 addition & 1 deletion src/ModelingToolkitSampledData.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export DiscreteIntegrator, DiscreteDerivative, Delay, Difference, ZeroOrderHold,
ClockChanger,
DiscretePIDParallel, DiscretePIDStandard, DiscreteStateSpace,
DiscreteTransferFunction, NormalNoise, UniformNoise, Quantization,
ExponentialFilter
DiscreteSlewRateLimiter, ExponentialFilter
export DiscreteOnOffController
include("discrete_blocks.jl")

Expand Down
64 changes: 64 additions & 0 deletions src/discrete_blocks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,70 @@ See also [ControlSystemsMTK.jl](https://juliacontrol.github.io/ControlSystemsMTK
# compose(ODESystem(eqs, t, sts, pars; name = name), input, output)
# end


"""
DiscreteSlewRateLimiter(rate = 1.0, rate_negative = rate)

A discrete-time slew rate limiter that limits the rate of change of the input signal.

Note, the sample interval is not taken into account when computing the rate of change, the difference between two consequetive samples is saturated.

# Parameters:
- `rate`: Slew rate limit (in positive/increasing direction). Must be a positive number.
- `rate_negative`: Negative slew rate limit, defaults to `rate`. Must be a positive number.

# Variables
- `d`: Unsaturated rate of change of the input signal
- `u`: Input signal
- `y`: Output signal (saturated slew rate)

# Connectors:
- `input`
- `output`

# Example
```
cl = Clock(0.1)
z = ShiftIndex(cl)
@mtkmodel SlweRateLimiterModel begin
@components begin
input = Sine(amplitude=1, frequency=0.8)
limiter = DiscreteSlewRateLimiter(; z, rate=0.4, rate_negative = 0.3)
end
@variables begin
x(t) = 0 # Dummy variable to workaround JSCompiler bug
end
@equations begin
connect(input.output, limiter.input)
D(x) ~ 0.1x + Hold(limiter.y)
end
end
@named m = SlweRateLimiterModel()
m = complete(m)
ssys = structural_simplify(IRSystem(m))
prob = ODEProblem(ssys, [m.limiter.y(z-1) => 0], (0.0, 2.0))
sol = solve(prob, Tsit5(), dtmax=0.01)
plot(sol, idxs=[m.input.output.u, m.limiter.y], title="Slew rate limited sine wave")
```
"""
@mtkmodel DiscreteSlewRateLimiter begin
@extend u, y = siso = SISO()
@structural_parameters begin
z = ShiftIndex()
end
@parameters begin
rate = 1.0, [description = "Slew rate limit"]
rate_negative = rate, [description = "Negative slew rate limit"]
end
@variables begin
d(t)
end
@equations begin
d(z) ~ u(z) - y(z-1)
y(z) ~ y(z-1) + clamp(d(z), -rate_negative, rate)
end
end

"""
Quantization

Expand Down
28 changes: 28 additions & 0 deletions test/test_discrete_blocks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,35 @@ end
# @test reduce(vcat, sol((0:10) .+ 1e-2))[:]≈[zeros(2); 1; zeros(8)] atol=1e-2
# end*

##
@testset "SlewRateLimiter" begin
@info "Testing SlewRateLimiter"
cl = Clock(0.1)
z = ShiftIndex(cl)
@mtkmodel SlewRateLimiterModel begin
@components begin
input = Sine(amplitude=1, frequency=0.8)
limiter = DiscreteSlewRateLimiter(; z, rate=0.4, rate_negative = 0.3)
end
@variables begin
x(t) = 0 # Dummy variable to workaround JSCompiler bug
end
@equations begin
connect(input.output, limiter.input)
D(x) ~ 0.1x + Hold(limiter.y)
end
end
@named m = SlewRateLimiterModel()
m = complete(m)
ssys = structural_simplify(IRSystem(m))
prob = ODEProblem(ssys, [m.limiter.y(z-1) => 0], (0.0, 2.0))
sol = solve(prob, Tsit5(), dtmax=0.01)
# plot(sol, idxs=[m.input.output.u, m.limiter.y], title="Slew rate limited sine wave")
@test maximum(diff(sol[m.limiter.y])) ≈ 0.4
@test minimum(diff(sol[m.limiter.y])) ≈ -0.3
end

##
@testset "quantization" begin
@info "Testing quantization"

Expand Down
Loading