Skip to content

Commit 2e58e18

Browse files
committed
add sampletime operator
1 parent 1aec75d commit 2e58e18

File tree

5 files changed

+36
-17
lines changed

5 files changed

+36
-17
lines changed

src/ModelingToolkit.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ export debug_system
269269
#export Continuous, Discrete, sampletime, input_timedomain, output_timedomain
270270
#export has_discrete_domain, has_continuous_domain
271271
#export is_discrete_domain, is_continuous_domain, is_hybrid_domain
272-
export Sample, Hold, Shift, ShiftIndex
272+
export Sample, Hold, Shift, ShiftIndex, sampletime
273273
export Clock #, InferredDiscrete,
274274

275275
end # module

src/clock.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ end
117117
Clock(dt::Real) = Clock(nothing, dt)
118118
Clock() = Clock(nothing, nothing)
119119

120-
sampletime(c) = isdefined(c, :dt) ? c.dt : nothing
120+
sampletime() = InferredSampleTime()
121+
sampletime(c) = something(isdefined(c, :dt) ? c.dt : nothing, InferredSampleTime())
121122
Base.hash(c::Clock, seed::UInt) = hash(c.dt, seed 0x953d7a9a18874b90)
122123
function Base.:(==)(c1::Clock, c2::Clock)
123124
((c1.t === nothing || c2.t === nothing) || isequal(c1.t, c2.t)) && c1.dt == c2.dt

src/discretedomain.jl

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
using Symbolics: Operator, Num, Term, value, recursive_hasoperator
22

3+
struct InferredSampleTime <: Operator end
4+
function SymbolicUtils.promote_symtype(::Type{InferredSampleTime}, t...)
5+
Real
6+
end
7+
function InferredSampleTime()
8+
# Term{Real}(InferredSampleTime, Any[])
9+
SymbolicUtils.term(InferredSampleTime, type = Real)
10+
end
11+
312
# Shift
413

514
"""
@@ -15,8 +24,6 @@ $(FIELDS)
1524
```jldoctest
1625
julia> using Symbolics
1726
18-
julia> @variables t;
19-
2027
julia> Δ = Shift(t)
2128
(::Shift) (generic function with 2 methods)
2229
```
@@ -176,16 +183,18 @@ end
176183
function (xn::Num)(k::ShiftIndex)
177184
@unpack clock, steps = k
178185
x = value(xn)
179-
t = clock.t
180186
# Verify that the independent variables of k and x match and that the expression doesn't have multiple variables
181187
vars = Symbolics.get_variables(x)
182188
length(vars) == 1 ||
183189
error("Cannot shift a multivariate expression $x. Either create a new unknown and shift this, or shift the individual variables in the expression.")
184190
args = Symbolics.arguments(vars[]) # args should be one element vector with the t in x(t)
185191
length(args) == 1 ||
186192
error("Cannot shift an expression with multiple independent variables $x.")
187-
isequal(args[], t) ||
188-
error("Independent variable of $xn is not the same as that of the ShiftIndex $(k.t)")
193+
t = args[]
194+
if hasfield(typeof(clock), :t)
195+
isequal(t, clock.t) ||
196+
error("Independent variable of $xn is not the same as that of the ShiftIndex $(k.t)")
197+
end
189198

190199
# d, _ = propagate_time_domain(xn)
191200
# if d != clock # this is only required if the variable has another clock

src/systems/systemstructure.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,18 @@ function structural_simplify!(state::TearingState, io = nothing; simplify = fals
652652
append!(appended_parameters, inputs[i], unknowns(ss))
653653
discrete_subsystems[i] = ss
654654
end
655+
for i in eachindex(discrete_subsystems)
656+
discsys = discrete_subsystems[i]
657+
eqs = collect(discsys.eqs)
658+
for eqi in eachindex(eqs)
659+
clock = id_to_clock[i]
660+
clock isa AbstractDiscrete || continue
661+
Ts = sampletime(clock)
662+
eqs[eqi] = substitute(eqs[eqi], InferredSampleTime() => Ts)
663+
end
664+
@set discsys.eqs = eqs
665+
discrete_subsystems[i] = discsys
666+
end
655667
@set! sys.discrete_subsystems = discrete_subsystems, inputs, continuous_id,
656668
id_to_clock
657669
@set! sys.ps = appended_parameters

test/clock.jl

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ using ModelingToolkitStandardLibrary.Blocks
330330

331331
dt = 0.05
332332
d = Clock(t, dt)
333-
k = ShiftIndex(d)
333+
k = ShiftIndex()
334334

335335
@mtkmodel DiscretePI begin
336336
@components begin
@@ -347,7 +347,7 @@ k = ShiftIndex(d)
347347
y(t)
348348
end
349349
@equations begin
350-
x(k) ~ x(k - 1) + ki * u(k)
350+
x(k) ~ x(k - 1) + ki * u(k) * sampletime() / dt
351351
output.u(k) ~ y(k)
352352
input.u(k) ~ u(k)
353353
y(k) ~ x(k - 1) + kp * u(k)
@@ -364,21 +364,18 @@ end
364364
end
365365
end
366366

367-
@mtkmodel Holder begin
368-
@components begin
369-
input = RealInput()
370-
output = RealOutput()
371-
end
367+
@mtkmodel ZeroOrderHold begin
368+
@extend u, y = siso = Blocks.SISO()
372369
@equations begin
373-
output.u ~ Hold(input.u)
370+
y ~ Hold(u)
374371
end
375372
end
376373

377374
@mtkmodel ClosedLoop begin
378375
@components begin
379376
plant = FirstOrder(k = 0.3, T = 1)
380-
sampler = Sampler()
381-
holder = Holder()
377+
sampler = Blocks.Sampler(; clock = d)
378+
holder = ZeroOrderHold()
382379
controller = DiscretePI(kp = 2, ki = 2)
383380
feedback = Feedback()
384381
ref = Constant(k = 0.5)

0 commit comments

Comments
 (0)