Skip to content

Commit 3d6534d

Browse files
committed
Add Julia mixed demo nodes
1 parent 77c8836 commit 3d6534d

3 files changed

Lines changed: 205 additions & 0 deletions

File tree

demo/controller_jl.jl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# controller_jl.jl -- Julia bang-bang controller for the concore demo
2+
3+
include("concore.jl")
4+
using .Concore
5+
6+
const ysp = 3.0
7+
8+
function controller(ym)
9+
if ym[1] < ysp
10+
return 1.01 .* ym
11+
end
12+
return 0.9 .* ym
13+
end
14+
15+
Concore.default_maxtime!(150)
16+
Concore.delay = 0.02
17+
18+
init_simtime_u = "[0.0, 0.0]"
19+
init_simtime_ym = "[0.0, 0.0]"
20+
21+
u = initval(init_simtime_u)
22+
23+
while Concore.simtime < Concore.maxtime
24+
ym = initval(init_simtime_ym)
25+
while unchanged()
26+
ym = concore_read(1, "ym", init_simtime_ym)
27+
end
28+
29+
u = controller(ym)
30+
println("$(Concore.simtime). u=$(u) ym=$(ym)")
31+
concore_write(1, "u", u; delta=0)
32+
end
33+
34+
println("retry=$(Concore.retrycount)")

demo/pm_jl.jl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# pm_jl.jl -- Julia plant model for the concore demo
2+
3+
include("concore.jl")
4+
using .Concore
5+
6+
pm(u) = u .+ 0.01
7+
8+
Concore.default_maxtime!(150)
9+
Concore.delay = 0.02
10+
11+
init_simtime_u = "[0.0, 0.0]"
12+
init_simtime_ym = "[0.0, 0.0]"
13+
14+
ym = initval(init_simtime_ym)
15+
16+
while Concore.simtime < Concore.maxtime
17+
u = initval(init_simtime_u)
18+
while unchanged()
19+
u = concore_read(1, "u", init_simtime_u)
20+
end
21+
22+
ym = pm(u)
23+
println("$(Concore.simtime). u=$(u) ym=$(ym)")
24+
concore_write(1, "ym", ym; delta=1)
25+
end
26+
27+
println("retry=$(Concore.retrycount)")

demo/run_julia_mixed_demo.jl

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# run_julia_mixed_demo.jl -- run Python/Julia concore demo pairs
2+
#
3+
# Usage:
4+
# julia demo/run_julia_mixed_demo.jl [maxtime]
5+
6+
const DEMO_DIR = @__DIR__
7+
const REPO_ROOT = dirname(DEMO_DIR)
8+
const MAXTIME = length(ARGS) >= 1 ? parse(Int, ARGS[1]) : 5
9+
const PYTHON = get(ENV, "PYTHON", Sys.iswindows() ? "python" : "python3")
10+
11+
function link_dir(target, link)
12+
ispath(link) && return
13+
try
14+
symlink(target, link; dir_target=true)
15+
catch
16+
if Sys.iswindows()
17+
run(`cmd /c mklink /J $link $target`)
18+
else
19+
rethrow()
20+
end
21+
end
22+
end
23+
24+
function prepare_node(node_dir, in_edge, out_edge, source_file, runtime_files)
25+
mkpath(node_dir)
26+
link_dir(in_edge, joinpath(node_dir, "in1"))
27+
link_dir(out_edge, joinpath(node_dir, "out1"))
28+
cp(source_file, joinpath(node_dir, basename(source_file)); force=true)
29+
for runtime_file in runtime_files
30+
cp(runtime_file, joinpath(node_dir, basename(runtime_file)); force=true)
31+
end
32+
end
33+
34+
function wait_with_timeout(procs, timeout_sec)
35+
start = time()
36+
while any(process_running, procs)
37+
if time() - start > timeout_sec
38+
for proc in procs
39+
process_running(proc) && kill(proc)
40+
end
41+
return false
42+
end
43+
sleep(0.1)
44+
end
45+
return true
46+
end
47+
48+
function run_pair(label, controller_source, controller_cmd, pm_source, pm_cmd)
49+
workspace = mktempdir(; cleanup=true)
50+
cu_dir = joinpath(workspace, "CU")
51+
pym_dir = joinpath(workspace, "PYM")
52+
cz_dir = joinpath(workspace, "CZ")
53+
pz_dir = joinpath(workspace, "PZ")
54+
55+
mkpath(cu_dir)
56+
mkpath(pym_dir)
57+
58+
write(joinpath(cu_dir, "u"), "[0.0, 0.0]")
59+
write(joinpath(pym_dir, "ym"), "[0.0, 0.0]")
60+
write(joinpath(cu_dir, "concore.maxtime"), string(MAXTIME))
61+
write(joinpath(pym_dir, "concore.maxtime"), string(MAXTIME))
62+
63+
prepare_node(
64+
cz_dir,
65+
pym_dir,
66+
cu_dir,
67+
controller_source,
68+
endswith(controller_source, ".jl") ?
69+
[joinpath(REPO_ROOT, "concore.jl")] :
70+
[joinpath(REPO_ROOT, "concore.py"), joinpath(REPO_ROOT, "concore_base.py")],
71+
)
72+
prepare_node(
73+
pz_dir,
74+
cu_dir,
75+
pym_dir,
76+
pm_source,
77+
endswith(pm_source, ".jl") ?
78+
[joinpath(REPO_ROOT, "concore.jl")] :
79+
[joinpath(REPO_ROOT, "concore.py"), joinpath(REPO_ROOT, "concore_base.py")],
80+
)
81+
82+
write(joinpath(cz_dir, "concore.iport"), "{'ym': 1}")
83+
write(joinpath(cz_dir, "concore.oport"), "{'u': 1}")
84+
write(joinpath(pz_dir, "concore.iport"), "{'u': 1}")
85+
write(joinpath(pz_dir, "concore.oport"), "{'ym': 1}")
86+
87+
controller_out = joinpath(cz_dir, "concoreout.txt")
88+
pm_out = joinpath(pz_dir, "concoreout.txt")
89+
90+
println("Running $label")
91+
controller_proc = open(controller_out, "w") do out
92+
run(pipeline(Cmd(controller_cmd; dir=cz_dir), stdout=out, stderr=out); wait=false)
93+
end
94+
pm_proc = open(pm_out, "w") do out
95+
run(pipeline(Cmd(pm_cmd; dir=pz_dir), stdout=out, stderr=out); wait=false)
96+
end
97+
98+
completed = wait_with_timeout([controller_proc, pm_proc], 60)
99+
wait(controller_proc)
100+
wait(pm_proc)
101+
102+
controller_log = read(controller_out, String)
103+
pm_log = read(pm_out, String)
104+
final_ym = read(joinpath(pym_dir, "ym"), String)
105+
106+
ok = completed &&
107+
controller_proc.exitcode == 0 &&
108+
pm_proc.exitcode == 0 &&
109+
occursin("retry=", controller_log) &&
110+
occursin("retry=", pm_log) &&
111+
startswith(strip(final_ym), "[")
112+
113+
if ok
114+
println("PASS: $label")
115+
else
116+
println("FAIL: $label")
117+
println("--- controller output ---")
118+
print(controller_log)
119+
println("--- plant output ---")
120+
print(pm_log)
121+
end
122+
123+
return ok
124+
end
125+
126+
julia_cmd = Base.julia_cmd()
127+
128+
ok_controller_jl = run_pair(
129+
"Julia controller + Python plant",
130+
joinpath(DEMO_DIR, "controller_jl.jl"),
131+
`$julia_cmd controller_jl.jl`,
132+
joinpath(DEMO_DIR, "pm.py"),
133+
`$PYTHON pm.py`,
134+
)
135+
136+
ok_pm_jl = run_pair(
137+
"Python controller + Julia plant",
138+
joinpath(DEMO_DIR, "controller.py"),
139+
`$PYTHON controller.py`,
140+
joinpath(DEMO_DIR, "pm_jl.jl"),
141+
`$julia_cmd pm_jl.jl`,
142+
)
143+
144+
exit(ok_controller_jl && ok_pm_jl ? 0 : 1)

0 commit comments

Comments
 (0)