Skip to content

Commit

Permalink
feat: update timer example (#190)
Browse files Browse the repository at this point in the history
  • Loading branch information
domire8 authored Oct 28, 2024
1 parent 2525a0e commit 2719505
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 57 deletions.
160 changes: 104 additions & 56 deletions docs/docs/getting-started/04-examples/01-timer-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,49 +9,70 @@ application.

## Launcher configuration requirements

This example uses AICA Core v3.1.1 in the Launcher configuration.
This example uses AICA Core v4.0.1 in the Launcher configuration.

## Setting up the application

After starting the application container, open the Developer Interface on `localhost:8080` and press New Application.
Launch AICA Studio and create a new application by pressing "Create new".
Copy the following application code into the text box under the Editor tab, replacing the default content.

```yaml
schema: 2-0-2
dependencies:
core: v4.0.1
on_start:
load:
component: timer
components:
timer:
component: base_components::utilities::Timer
position:
x: 200
y: -300
parameters:
rate: 10
timeout: 2.5
component: aica_core_components::utility::Timer
display_name: Timer
events:
is_unconfigured:
lifecycle: configure
is_inactive:
lifecycle: activate
is_timed_out:
transition: timer_2

timer_2:
component: base_components::utilities::Timer
position:
x: 700
y: -300
transitions:
on_load:
lifecycle:
component: timer
transition: configure
on_configure:
lifecycle:
component: timer
transition: activate
predicates:
is_timed_out:
transition: timer_2
parameters:
rate: 10
timeout: 2.5
timeout: !!float 2.0
timer_2:
component: aica_core_components::utility::Timer
display_name: Timer 2
events:
is_unconfigured:
lifecycle: configure
is_inactive:
lifecycle: activate
is_timed_out:
transition: timer
transitions:
on_load:
lifecycle:
component: timer_2
transition: configure
on_configure:
lifecycle:
component: timer_2
transition: activate
predicates:
is_timed_out:
transition: timer
parameters:
timeout: !!float 4.0
hardware: { }
graph:
positions:
stop:
x: 0
y: 160
components:
timer:
x: 320
y: -20
timer_2:
x: 840
y: -20
```
Then, press the Generate Graph button. The graph should show two components connected with event edges.
Expand All @@ -71,25 +92,23 @@ on_start:
In this case, the first event that occurs in the application is to load the `timer` component.

Application components are listed under the `components` field. Each component has a name and a registration.
The position field is used just for rendering the component on the graph.
The display name field is used just for rendering the component on the graph.

```yaml
timer:
component: base_components::utilities::Timer
position:
x: 0
y: -300
component: aica_core_components::utility::Timer
display_name: Timer
```

In this case, `base_components::utilities::Timer` is the registration of a built-in AICA component. It is a lifecycle
In this case, `aica_core_components::utility::Timer` is the registration of a built-in AICA component. It is a lifecycle
component that starts a timer when the component is activated.

Thereafter, the initial component parameters are defined.

```yaml
parameters:
rate: 10
timeout: 2.5
rate: !!float 5.0
timeout: !!float 2.0
```

All components have a `rate` parameter which defines the frequency of periodic execution steps. The default rate for
Expand All @@ -99,55 +118,84 @@ faster or slower, respectively.
The timer component has a special parameter called `timeout`, which is the duration in seconds that the timer should
be active. At the end of the timeout period, it will be in the "timed out" state.

The `events` field of a component associates component predicates with events.
:::info

The `!!float` tag is used to distinguish floating-point parameters from integer parameters in the YAML. Some YAML
document parsers, formatters or emitters would round a value such as `5.0` to the "equivalent" integer value `5`.
AICA Studio automatically adds the `!!float` tag to ensure that the Event Engine always parses the parameter as a
floating-point value.

:::

The `events` field of a component associates component state transitions and predicates with events.

```yaml
events:
is_unconfigured:
lifecycle: configure
transitions:
on_load:
lifecycle:
component: timer
transition: configure
```

In this case, when the timer component is unconfigured, it triggers a lifecycle transition to configure itself.
Similarly, the next event activates the timer when it is inactive:
In this case, when the timer component is loaded, it triggers a lifecycle transition to configure itself.
Similarly, the next event activates the timer when it is configured:

```yaml
is_inactive:
lifecycle: activate
on_configure:
lifecycle:
component: timer
transition: activate
```

When a lifecycle component configures or activates itself automatically, this is known as "auto-configure" and
"auto-activate", respectively.
"auto-activate", respectively. The graph shows these events with the green icons next to the component name.

![auto lifecycle timer](./assets/auto-lifecycle-events-timer.png)

Finally, the timer component has a special predicate `is_timed_out`, which is internally associated with the `timeout`
parameter.

```yaml
is_timed_out:
transition: timer_2
predicates:
is_timed_out:
transition: timer_2
```

In this case, after the timer component has been active for 2.5 seconds, it triggers a transition event to `timer_2`.
In this case, after the timer component has been active for 2 seconds, it triggers a transition event to `timer_2`.
The `transition` event from `timer` to `timer_2` is a shorthand for unloading the first component and loading the
second.

The second block describing `timer_2` is nearly identical, as the two timers are intended to have symmetrical behavior.
The second block describing `timer_2` is nearly identical (apart from a different value for the `timeout` parameter), as
the two timers are intended to have symmetrical behavior.

## Run the application

Press the Play button to start the application.

When the application is started, the `timer` component is loaded. It is initially unconfigured, which triggers it
to be configured. Thereafter, it lands in the inactive lifecycle state, which triggers it to be activated.
Once activated, the timer starts running. After 2.5 seconds (as specified by the `timeout` parameter),
the `is_timed_out` predicate goes from false to true. As a result, the `transition` event causes `timer` to be unloaded
and `timer_2` to be loaded instead. The second timer then goes through the same steps of configuring and activating
before transitioning back to the first timer.
Once activated, the timer starts running. After 2 seconds (as specified by the `timeout` parameter), the `is_timed_out`
predicate goes from false to true. As a result, the `transition` event causes `timer` to be unloaded and `timer_2` to be
loaded instead. The second timer then goes through the same steps of configuring and activating before transitioning
back to the first timer.

![timer example (animated)](./assets/timer-example.gif)

Use the Pause button to keep the application in an idle state; components will remain loaded and active, but predicates
and events will not be handled until the application is started again.
In the AICA System, events are the key drivers of application logic. While the application is running, events can be
triggered automatically from transitions or predicates, as seen in this example, but also by other event sources such
as conditions, sequences, interactive trigger buttons in AICA Studio and even external API calls.

It is possible to pause an application using the Pause control, which has the effect of blocking any and all events from
being triggered. When an application is paused, all components will remain in their current state; any components and
controllers that are loaded and active will keep running according to their current states. Only the triggering and
automatic propagation of events is paused.

Try pausing the application and see how the state of the timers can be prevented from changing. Notice how pausing the
application while a timer is active does not prevent it from counting towards its timeout threshold, and that resuming
the application after the elapsed time has passed will then immediately trigger the waiting transition.

Use the Stop button to unload all components and reset the application.
Finally, use the Stop button to stop the application. This will deactivate and unload all components and controllers
and fully reset the application.

Next, learn how to edit the application using the interactive graph editor.
22 changes: 21 additions & 1 deletion docs/docs/getting-started/04-examples/02-editor-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ and any changes will automatically be written back to the YAML representation.
Drag the background to pan the graph view and scroll to zoom in or out. Click the arrow icons on the central divider
on the page to expand either the code editor or graph view to full screen.

You can also use the graph control buttons on the bottom left to zoom and fit the view.
You can also use the graph control buttons on the bottom left to zoom and fit the view. The mini-map on the bottom right
can also be used to navigate around the graph.

<!-- TODO: parameters and auto-lifecycle events are no longer dropdowns, but part of the Parameter editor view -->

## Setting component parameters

Expand Down Expand Up @@ -46,6 +49,23 @@ When both toggle switches are enabled, the YAML code will show the corresponding
Disabling one or both auto event switches will also remove the corresponding events from the YAML, while enabling the
switch will regenerate the event in the YAML.
<!-- TODO: Replace the following sections with adding interactive buttons
Show how we can:
- go to the sidebar
- click on add trigger button
- drag to reposition
- create an event edge to the timer
- choose the event type (e.g. deactivate)
- rename the button
Repeat for a second button to show manual deactivation / activation
Then say: now that we learned to add buttons and create event edges, try to do the same for components. As an exercise,
search for and add timer components, set thea auto-lifecycle events, and connect the transition edges to recreate the
example from scratch.
-->
## Creating and deleting event edges
The timers are connected with a Transition event edge. To change the event type on an edge, click on the label. This
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/docs/getting-started/04-examples/assets/timer-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 2719505

Please sign in to comment.