Skip to content
LIBRARY
Nonlinear.Tests.SlewRateLimiter.md

Nonlinear.Tests.SlewRateLimiter

Test component that validates SlewRateLimiter behavior with a sinusoidal input.

This test component connects a sine wave generator to a slew rate limiter and verifies the expected output value after simulation. The slew rate limiter restricts how quickly the output signal can change, with separate limits for rising and falling rates. The sine input provides a continuously changing signal that exercises both the rising and falling rate limits.

Usage

BlockComponents.Nonlinear.Tests.SlewRateLimiter()

Behavior

julia
using BlockComponents #hide
using ModelingToolkit #hide
@named sys = BlockComponents.Nonlinear.Tests.SlewRateLimiter() #hide
full_equations(sys) #hide
<< @example-block not executed in draft mode >>

Source

dyad
"""
Test component that validates SlewRateLimiter behavior with a sinusoidal input.

This test component connects a sine wave generator to a slew rate limiter and verifies the expected
output value after simulation. The slew rate limiter restricts how quickly the output signal can change,
with separate limits for rising and falling rates. The sine input provides a continuously changing signal
that exercises both the rising and falling rate limits.
"""
test component SlewRateLimiter
  "Slew rate limiter instance with rising/falling limits and small time delay"
  limiter = BlockComponents.Nonlinear.SlewRateLimiter(rising = 1, falling = -1, td = 0.001) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 160, "y1": 20, "x2": 260, "y2": 120, "rot": 0}
      }
    }
  }
  "Sine wave generator producing a 2Hz signal with amplitude 2"
  sine = BlockComponents.Sources.Sine(amplitude = 2, frequency = 2) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 20, "y1": 20, "x2": 120, "y2": 120, "rot": 0}
      }
    }
  }
relations
  "Connects the sine wave output to the slew rate limiter input"
  connect(sine.y, limiter.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {
  "Dyad": {
    "icons": {"default": "dyad://BlockComponents/Example.svg"},
    "tests": {
      "case1": {
        "stop": 1,
        "expect": {"signals": ["limiter.y"], "final": {"limiter.y": -0.03277527668771871}}
      }
    }
  }
}
end
Flattened Source
dyad
"""
Test component that validates SlewRateLimiter behavior with a sinusoidal input.

This test component connects a sine wave generator to a slew rate limiter and verifies the expected
output value after simulation. The slew rate limiter restricts how quickly the output signal can change,
with separate limits for rising and falling rates. The sine input provides a continuously changing signal
that exercises both the rising and falling rate limits.
"""
test component SlewRateLimiter
  "Slew rate limiter instance with rising/falling limits and small time delay"
  limiter = BlockComponents.Nonlinear.SlewRateLimiter(rising = 1, falling = -1, td = 0.001) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 160, "y1": 20, "x2": 260, "y2": 120, "rot": 0}
      }
    }
  }
  "Sine wave generator producing a 2Hz signal with amplitude 2"
  sine = BlockComponents.Sources.Sine(amplitude = 2, frequency = 2) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 20, "y1": 20, "x2": 120, "y2": 120, "rot": 0}
      }
    }
  }
relations
  "Connects the sine wave output to the slew rate limiter input"
  connect(sine.y, limiter.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {
  "Dyad": {
    "icons": {"default": "dyad://BlockComponents/Example.svg"},
    "tests": {
      "case1": {
        "stop": 1,
        "expect": {"signals": ["limiter.y"], "final": {"limiter.y": -0.03277527668771871}}
      }
    }
  }
}
end


Test Cases

julia
using BlockComponents
using DyadInterface: TransientAnalysis, rebuild_sol, ODEAlg
using ModelingToolkit: toggle_namespacing, get_initial_conditions, @named
using CSV, DataFrames, Plots

snapshotsdir = joinpath(dirname(dirname(pathof(BlockComponents))), "test", "snapshots")
<< @setup-block not executed in draft mode >>

Test Case case1

julia
@named model_case1 = BlockComponents.Nonlinear.Tests.SlewRateLimiter()
model_case1 = toggle_namespacing(model_case1, false)

model_case1 = toggle_namespacing(model_case1, true)
result_case1 = TransientAnalysis(; model = model_case1, alg = ODEAlg.Auto(), start = 0e+0, stop = 1e+0, abstol=1e-6, reltol=1e-6)
sol_case1 = rebuild_sol(result_case1)
<< @setup-block not executed in draft mode >>
julia
df_case1 = DataFrame(:t => sol_case1[:t], :actual => sol_case1[model_case1.limiter.y])
dfr_case1 = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Nonlinear.Tests.SlewRateLimiter_case1_sig0.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_case1, idxs=[model_case1.limiter.y], width=2, label="Actual value of limiter.y")
if !isnothing(dfr_case1)
  scatter!(plt, dfr_case1.t, dfr_case1.expected, mc=:red, ms=3, label="Expected value of limiter.y")
end
scatter!(plt, [df_case1.t[end]], [-0.03277527668771871], label="Final Condition for `limiter.y`")
<< @setup-block not executed in draft mode >>
julia
plt
<< @example-block not executed in draft mode >>