I have started using ParametrizedInterpolation from the standard library in my code, and while it works fine, having to add a clock to each component that uses it tarnishes the code a bit. So I wrote this:
""" A step function, where `step_function.u` is `ys[i]` when `t = ts[i]` (and afterwards).
The point is that while `ParametrizedInterpolation` can be used directly, its interface requires an
explicit `clock`. `StepFunction` is simple: add it as a System, and access its values with `sf.u`
@mtkcompile sf = StepFunction([1,2,3], [4,5,3])
res = solve(ODEProblem(sf, [], [1,10]))
println(res.([1,1.5,2,3,4,8], idxs=sf.val))
# output
[4.0, 4.0, 5.0, 3.0, 3.0, 3.0]
"""
@component function StepFunction(ts, ys; name=:unnamed_interpolator)
@named interp = ParametrizedInterpolation(ExtrapolatedConstantInterpolation,
Float64.(ys), Float64.(ts))
@named clk = ContinuousClock()
@variables val(t)
eqs = [connect(clk.output, interp.input),
val ~ interp.output.u]
return System(eqs, t, [val], []; name, systems=[interp, clk])
end
And it works nicely.
Question 1: is there anything wrong with that?
Questions 2: Now setting the ts parameter looks like my_motor.input.interp.ts => [1,2,10]. How can I make it like my_motor.input.ts => [1,2,10]? I’ve read Initialization of Systems · ModelingToolkit.jl, but I’m not so confident. Should I set the interp.ts to missing, and set up an equation like interp.ts ~ ts with an additional ts parameter in StepFunction?