diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-05-19 21:21:27 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-05-19 21:21:27 +1000 |
| commit | a6ab1504058304012791281f9eb42c262745888f (patch) | |
| tree | f82379cd1e66a8ae2f1afbae5cf083a8ab7acc53 /lib/tinyfsm/examples/elevator/elevator.cpp | |
| parent | b320a6a863cf1c10dc79254af41f573730935564 (diff) | |
| download | tangara-fw-a6ab1504058304012791281f9eb42c262745888f.tar.gz | |
Add tinyfsm, start converting core functions to an FSM-based event loop
Diffstat (limited to 'lib/tinyfsm/examples/elevator/elevator.cpp')
| -rw-r--r-- | lib/tinyfsm/examples/elevator/elevator.cpp | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/lib/tinyfsm/examples/elevator/elevator.cpp b/lib/tinyfsm/examples/elevator/elevator.cpp new file mode 100644 index 00000000..6e792f64 --- /dev/null +++ b/lib/tinyfsm/examples/elevator/elevator.cpp @@ -0,0 +1,115 @@ +#include <tinyfsm.hpp> + +#include "elevator.hpp" +#include "fsmlist.hpp" + +#include <iostream> + +class Idle; // forward declaration + + +// ---------------------------------------------------------------------------- +// Transition functions +// + +static void CallMaintenance() { + std::cout << "*** calling maintenance ***" << std::endl; +} + +static void CallFirefighters() { + std::cout << "*** calling firefighters ***" << std::endl; +} + + +// ---------------------------------------------------------------------------- +// State: Panic +// + +class Panic +: public Elevator +{ + void entry() override { + send_event(MotorStop()); + } +}; + + +// ---------------------------------------------------------------------------- +// State: Moving +// + +class Moving +: public Elevator +{ + void react(FloorSensor const & e) override { + int floor_expected = current_floor + Motor::getDirection(); + if(floor_expected != e.floor) + { + std::cout << "Floor sensor defect (expected " << floor_expected << ", got " << e.floor << ")" << std::endl; + transit<Panic>(CallMaintenance); + } + else + { + std::cout << "Reached floor " << e.floor << std::endl; + current_floor = e.floor; + if(e.floor == dest_floor) + transit<Idle>(); + } + }; +}; + + +// ---------------------------------------------------------------------------- +// State: Idle +// + +class Idle +: public Elevator +{ + void entry() override { + send_event(MotorStop()); + } + + void react(Call const & e) override { + dest_floor = e.floor; + + if(dest_floor == current_floor) + return; + + /* lambda function used for transition action */ + auto action = [] { + if(dest_floor > current_floor) + send_event(MotorUp()); + else if(dest_floor < current_floor) + send_event(MotorDown()); + }; + + transit<Moving>(action); + }; +}; + + +// ---------------------------------------------------------------------------- +// Base state: default implementations +// + +void Elevator::react(Call const &) { + std::cout << "Call event ignored" << std::endl; +} + +void Elevator::react(FloorSensor const &) { + std::cout << "FloorSensor event ignored" << std::endl; +} + +void Elevator::react(Alarm const &) { + transit<Panic>(CallFirefighters); +} + +int Elevator::current_floor = Elevator::initial_floor; +int Elevator::dest_floor = Elevator::initial_floor; + + +// ---------------------------------------------------------------------------- +// Initial state definition +// +FSM_INITIAL_STATE(Elevator, Idle) |
