From 2efd9e11624c1ca6810b7e30fb1e6cd0a88a0e51 Mon Sep 17 00:00:00 2001 From: "Edward A. Lee" Date: Sun, 12 Jan 2025 15:28:39 -0800 Subject: [PATCH] Added zero-delay cycles examples from paper --- .../C/src/zero-delay-cycles/CausalityLoop.lf | 37 +++++++++++ .../C/src/zero-delay-cycles/Consistency.lf | 42 +++++++++++++ examples/C/src/zero-delay-cycles/Feedback.lf | 63 +++++++++++++++++++ .../C/src/zero-delay-cycles/ZeroDelayCycle.lf | 33 ++++++++++ 4 files changed, 175 insertions(+) create mode 100644 examples/C/src/zero-delay-cycles/CausalityLoop.lf create mode 100644 examples/C/src/zero-delay-cycles/Consistency.lf create mode 100644 examples/C/src/zero-delay-cycles/Feedback.lf create mode 100644 examples/C/src/zero-delay-cycles/ZeroDelayCycle.lf diff --git a/examples/C/src/zero-delay-cycles/CausalityLoop.lf b/examples/C/src/zero-delay-cycles/CausalityLoop.lf new file mode 100644 index 00000000..42f28a77 --- /dev/null +++ b/examples/C/src/zero-delay-cycles/CausalityLoop.lf @@ -0,0 +1,37 @@ +/** This test has two coupled cycles. In this variant, both are a zero-delay cycles (ZDC). */ +target C { + timeout: 1 sec, + tracing: true +} + +import PhysicalPlant, Planner from "Feedback.lf" + +reactor Controller { + input sensor: double + output control: double + + state plan: double = 0.0 + + output request_for_planning: double + input planning: double + + reaction a1(planning) {= + self->plan = planning->value; + =} + + reaction a2(sensor) -> request_for_planning, control {= + lf_set(request_for_planning, sensor->value); + lf_set(control, self->plan); + =} +} + +federated reactor { + p = new PhysicalPlant() + c = new Controller() + pl = new Planner() + + p.sensor -> c.sensor + c.request_for_planning -> pl.request + pl.response -> c.planning + c.control -> p.control +} diff --git a/examples/C/src/zero-delay-cycles/Consistency.lf b/examples/C/src/zero-delay-cycles/Consistency.lf new file mode 100644 index 00000000..7f115f8c --- /dev/null +++ b/examples/C/src/zero-delay-cycles/Consistency.lf @@ -0,0 +1,42 @@ +/** This test has two coupled cycles. In this variant, both are a zero-delay cycles (ZDC). */ +target C { + timeout: 1 sec, + tracing: true +} + +import PhysicalPlant from "Feedback.lf" + +reactor Controller { + input remote_update: double + input local_update: double + output control: double + + state latest_control: double = 0.0 + state first: bool = true + + reaction c1(local_update, remote_update) {= + =} + + reaction c2(local_update) -> control {= + =} +} + +reactor Platform { + input update: double + output publish: double + + c = new Controller() + p = new PhysicalPlant() + p.sensor -> c.local_update + p.sensor -> publish + update -> c.remote_update + c.control -> p.control +} + +federated reactor { + p1 = new Platform() + p2 = new Platform() + + p1.publish -> p2.update + p2.publish -> p1.update +} diff --git a/examples/C/src/zero-delay-cycles/Feedback.lf b/examples/C/src/zero-delay-cycles/Feedback.lf new file mode 100644 index 00000000..fba20610 --- /dev/null +++ b/examples/C/src/zero-delay-cycles/Feedback.lf @@ -0,0 +1,63 @@ +/** This test has two coupled cycles. In this variant, both are a zero-delay cycles (ZDC). */ +target C { + timeout: 1 sec, + tracing: true +} + +reactor PhysicalPlant { + input control: double + output sensor: double + timer t(0, 100 ms) + + reaction p1(t) -> sensor {= + lf_set(sensor, 42); + =} + + reaction p2(control) {= + lf_print("At logical time: " PRINTF_TIME ", received control input %f with lag " PRINTF_TIME, + lf_time_logical_elapsed(), control->value, lf_time_physical() - lf_time_logical()); + =} +} + +reactor Planner { + input request: double + output response: double + + reaction pl1(request) -> response {= + lf_sleep(MSEC(10)); + lf_set(response, request->value); + =} +} + +reactor Controller { + input sensor: double + output control: double + + state plan: double = 0.0 + + output request_for_planning: double + input planning: double + + reaction c1(sensor) -> request_for_planning {= + lf_set(request_for_planning, sensor->value); + =} + + reaction c2(planning) {= + self->plan = planning->value; + =} + + reaction c3(sensor) -> control {= + lf_set(control, self->plan); + =} +} + +federated reactor { + p = new PhysicalPlant() + c = new Controller() + pl = new Planner() + + p.sensor -> c.sensor + c.request_for_planning -> pl.request + pl.response -> c.planning + c.control -> p.control +} diff --git a/examples/C/src/zero-delay-cycles/ZeroDelayCycle.lf b/examples/C/src/zero-delay-cycles/ZeroDelayCycle.lf new file mode 100644 index 00000000..08230aba --- /dev/null +++ b/examples/C/src/zero-delay-cycles/ZeroDelayCycle.lf @@ -0,0 +1,33 @@ +target C + +reactor A (Period:time = 1 msec) { + input in:int + output out:int + + timer t(0, Period) + + reaction(t) -> out {= + lf_set(out, 42); + =} + + reaction(in) {= + // + =} +} + + +reactor B { + input in:int + output out:int + reaction(in) -> out {= + lf_set(out, in->value); + =} +} + +federated reactor { + a = new A(Period = 1 msec) + b = new B() + + a.out -> b.in + b.out -> a.in +} \ No newline at end of file