Elma
An event loop manager for embedded systems
driving.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <chrono>
3 #include "elma.h"
4 
6 
7 using namespace std::chrono;
8 using std::vector;
9 using namespace elma;
10 
11 namespace driving_example {
12 
14 
16  class Car : public Process {
17  public:
18 
21  Car(std::string name) : Process(name) {}
22 
24  void init() {}
25 
28  void start() {
29  velocity = 0;
30  }
31 
36  void update() {
37  if ( channel("Throttle").nonempty() ) {
38  force = channel("Throttle").latest();
39  }
40  velocity += ( delta() / 1000 ) * ( - k * velocity + force ) / m;
41  channel("Velocity").send(velocity);
42  std::cout << milli_time() << ","
43  << velocity << " \n";
44  }
45 
47  void stop() {}
48 
49  private:
50  double velocity;
51  double force;
52  const double k = 0.02;
53  const double m = 1000;
54  };
55 
57 
59  class CruiseControl : public Process {
60 
61  public:
62 
65  CruiseControl(std::string name) : Process(name) {}
66 
68  void init() {
69  watch("desired speed", [this](Event& e) {
70  desired_speed = e.value();
71  });
72  }
73 
75  void start() {}
76 
80  void update() {
81  if ( channel("Velocity").nonempty() ) {
82  speed = channel("Velocity").latest();
83  }
84  channel("Throttle").send(-KP*(speed - desired_speed));
85  }
86 
88  void stop() {}
89 
90  private:
91  double speed = 0;
92  double desired_speed = 0.0;
93  const double KP = 314.15;
94  vector<double> _v;
95  };
96 
98  class Driver : public Process {
99 
100  public:
101 
104  Driver(std::string name) : Process(name) {}
105 
107  void init() {
108  desired_speed = 50;
109  }
110 
112  void start() {}
113 
116  void update() {
117  if ( desired_speed == 50 ) {
118  desired_speed = 60;
119  } else {
120  desired_speed = 50;
121  }
122  emit(Event("desired speed", desired_speed));
123  }
124 
126  void stop() {}
127 
128  private:
129  double desired_speed;
130 
131  };
132 
133 }
134 
135 int main() {
136 
137  Manager m;
138 
139  driving_example::Car car("Car");
140  driving_example::CruiseControl cc("Control");
141  driving_example::Driver driver("Steve");
142  Channel throttle("Throttle");
143  Channel velocity("Velocity");
144 
145  m.schedule(car, 100_ms)
146  .schedule(cc, 100_ms)
147  .schedule(driver, 5_s)
148  .add_channel(throttle)
149  .add_channel(velocity)
150  .init()
151  .run(40_s);
152 
153 }
void init()
Watch for events that change the desired speed.
Definition: driving.cc:68
void init()
Nothing to do to initialize.
Definition: driving.cc:24
The Process Manager class.
Definition: manager.h:27
void stop()
Nothing to do to stop.
Definition: driving.cc:88
void start()
Nothing to do to initialize.
Definition: driving.cc:75
Manager & schedule(Process &process, high_resolution_clock::duration period)
Definition: manager.cc:13
json value() const
Definition: event.h:34
Example: A cruise controller for a Car process. See examples/driving.cc.
Definition: driving.cc:59
Car(std::string name)
Definition: driving.cc:21
CruiseControl(std::string name)
Definition: driving.cc:65
Driver(std::string name)
Definition: driving.cc:104
Manager & run(high_resolution_clock::duration runtime)
Definition: manager.cc:190
void init()
initialize the desired speed
Definition: driving.cc:107
Events that can be emitted, watched, and responded to with event handlers.
Definition: event.h:23
Manager & add_channel(Channel &)
Definition: manager.cc:43
void stop()
Nothing to do to stop.
Definition: driving.cc:126
Example: Another car simulation process. See examples/driving.cc.
Definition: driving.cc:16
void stop()
Nothing to do to stop.
Definition: driving.cc:47
Manager & init()
Definition: manager.cc:109
Example: A simulated driver, who keeps cycling between 50 and 60 kph. See examples/driving.cc.
Definition: driving.cc:98
A channel for sending double values to and from Process objects.
Definition: channel.h:21
void start()
Nothing to do to start.
Definition: driving.cc:112
Definition: channel.cc:5
An abstract base class for processes.
Definition: process.h:24