Skip to content

Commit 6727824

Browse files
committed
add test for multi-rate system
1 parent d617c56 commit 6727824

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

test/clock.jl

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,3 +240,87 @@ ci, varmap = infer_clocks(cl)
240240
@test varmap[f.u] == Clock(t, 0.5)
241241
@test varmap[p.u] == Continuous()
242242
@test varmap[c.r] == Clock(t, 0.5)
243+
244+
245+
## Multiple clock rates
246+
@info "Testing multi-rate hybrid system"
247+
dt = 0.1
248+
dt2 = 0.2
249+
@variables t x(t)=0 y(t)=0 u(t)=0 r(t)=1 yd1(t)=0 ud1(t)=0 yd2(t)=0 ud2(t)=0
250+
@parameters kp=1
251+
D = Differential(t)
252+
253+
eqs = [
254+
# controller (time discrete part `dt=0.1`)
255+
yd1 ~ Sample(t, dt)(y)
256+
ud1 ~ kp * (Sample(t, dt)(r) - yd1)
257+
# controller (time discrete part `dt=0.2`)
258+
yd2 ~ Sample(t, dt2)(y)
259+
ud2 ~ kp * (Sample(t, dt2)(r) - yd2)
260+
261+
# plant (time continuous part)
262+
u ~ Hold(ud1) + Hold(ud2)
263+
D(x) ~ -x + u
264+
y ~ x
265+
]
266+
267+
@named cl = ODESystem(eqs, t)
268+
269+
d = Clock(t, dt)
270+
d2 = Clock(t, dt2)
271+
272+
ci, varmap = infer_clocks(cl)
273+
@test varmap[yd1] == d
274+
@test varmap[ud1] == d
275+
@test varmap[yd2] == d2
276+
@test varmap[ud2] == d2
277+
@test varmap[r] == Continuous()
278+
@test varmap[x] == Continuous()
279+
@test varmap[y] == Continuous()
280+
@test varmap[u] == Continuous()
281+
282+
ss = structural_simplify(cl)
283+
284+
prob = ODEProblem(ss, [x=>0.0], (0.0, 1.0), [kp => 1.0])
285+
sol = solve(prob, Tsit5(), kwargshandle = KeywordArgSilent)
286+
287+
function foo!(dx, x, p, t)
288+
kp, ud1, ud2 = p
289+
dx[1] = -x[1] + ud1 + ud2
290+
end
291+
292+
function affect1!(integrator, saved_values)
293+
kp = integrator.p[1]
294+
y = integrator.u[1]
295+
r = 1.0
296+
ud1 = kp * (r - y)
297+
push!(saved_values.t, integrator.t)
298+
push!(saved_values.saveval, [integrator.p[4]])
299+
integrator.p[2] = ud1
300+
nothing
301+
end
302+
function affect2!(integrator, saved_values)
303+
kp = integrator.p[1]
304+
y = integrator.u[1]
305+
r = 1.0
306+
ud2 = kp * (r - y)
307+
push!(saved_values.t, integrator.t)
308+
push!(saved_values.saveval, [integrator.p[5]])
309+
integrator.p[3] = ud2
310+
nothing
311+
end
312+
saved_values1 = SavedValues(Float64, Vector{Float64})
313+
saved_values2 = SavedValues(Float64, Vector{Float64})
314+
cb1 = PeriodicCallback(Base.Fix2(affect1!, saved_values1), dt)
315+
cb2 = PeriodicCallback(Base.Fix2(affect2!, saved_values2), dt2)
316+
cb = CallbackSet(cb1, cb2)
317+
prob = ODEProblem(foo!, [0.0], (0.0, 1.0), [1.0, 0.0, 0.0, 0.0, 0.0], callback = cb)
318+
sol2 = solve(prob, Tsit5())
319+
320+
321+
@test sol.u == sol2.u
322+
@test saved_values1.t == sol.prob.kwargs[:disc_saved_values][1].t
323+
@test saved_values1.saveval == sol.prob.kwargs[:disc_saved_values][1].saveval
324+
325+
@test saved_values2.t == sol.prob.kwargs[:disc_saved_values][2].t
326+
@test saved_values2.saveval == sol.prob.kwargs[:disc_saved_values][2].saveval

0 commit comments

Comments
 (0)