$darkmode
simulation_context.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 Robert Bosch GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * SPDX-License-Identifier: Apache-2.0
17  */
23 #pragma once
24 
25 #include <cstdint> // for uint64_t
26 #include <functional> // for function<>
27 #include <map> // for map<>
28 #include <memory> // for unique_ptr<>, shared_ptr<>
29 #include <optional> // for optional<>
30 #include <string> // for string
31 #include <vector> // for vector<>
32 
33 #include <sol/state_view.hpp> // for state_view
34 
35 #include <cloe/cloe_fwd.hpp> // for Simulator, Controller, Registrar, Vehicle, Duration
36 #include <cloe/data_broker.hpp> // for DataBroker
37 #include <cloe/sync.hpp> // for Sync
38 #include <cloe/trigger/nil_event.hpp> // for DEFINE_NIL_EVENT
39 #include <cloe/utility/statistics.hpp> // for Accumulator
40 #include <cloe/utility/timer.hpp> // for DurationTimer
41 
42 #include "coordinator.hpp" // for Coordinator
43 #include "registrar.hpp" // for Registrar
44 #include "server.hpp" // for Server
45 #include "simulation_progress.hpp" // for SimulationProgress
46 #include "stack.hpp" // for Stack
47 #include "utility/command.hpp" // for CommandExecuter
48 #include "utility/time_event.hpp" // for TimeCallback
49 
50 namespace engine {
51 
55 class SimulationSync : public cloe::Sync {
56  public: // Overrides
57  SimulationSync() = default;
58  explicit SimulationSync(const cloe::Duration& step_width) : step_width_(step_width) {}
59 
60  uint64_t step() const override { return step_; }
61  cloe::Duration step_width() const override { return step_width_; }
62  cloe::Duration time() const override { return time_; }
63  cloe::Duration eta() const override { return eta_; }
64 
71  double realtime_factor() const override { return realtime_factor_; }
72 
77  double achievable_realtime_factor() const override {
78  return static_cast<double>(step_width().count()) / static_cast<double>(cycle_time_.count());
79  }
80 
81  public: // Modification
89  void increment_step() {
90  step_ += 1;
91  time_ += step_width_;
92  }
93 
98  void set_realtime_factor(double s) { realtime_factor_ = s; }
99 
100  void set_eta(cloe::Duration d) { eta_ = d; }
101 
102  void reset() {
103  time_ = cloe::Duration(0);
104  step_ = 0;
105  }
106 
107  void set_cycle_time(cloe::Duration d) { cycle_time_ = d; }
108 
109  private:
110  // Simulation State
111  uint64_t step_{0};
112  cloe::Duration time_{0};
113  cloe::Duration eta_{0};
114  cloe::Duration cycle_time_;
115 
116  // Simulation Configuration
117  double realtime_factor_{1.0}; // realtime
118  cloe::Duration step_width_{20'000'000}; // should be 20ms
119 };
120 
122  cloe::utility::Accumulator engine_time_ms;
123  cloe::utility::Accumulator cycle_time_ms;
124  cloe::utility::Accumulator simulator_time_ms;
125  cloe::utility::Accumulator controller_time_ms;
126  cloe::utility::Accumulator padding_time_ms;
127  cloe::utility::Accumulator controller_retries;
128 
129  void reset() {
130  engine_time_ms.reset();
131  cycle_time_ms.reset();
132  simulator_time_ms.reset();
133  controller_time_ms.reset();
134  padding_time_ms.reset();
135  controller_retries.reset();
136  }
137 
138  friend void to_json(cloe::Json& j, const SimulationStatistics& s) {
139  j = cloe::Json{
140  {"engine_time_ms", s.engine_time_ms}, {"simulator_time_ms", s.simulator_time_ms},
141  {"controller_time_ms", s.controller_time_ms}, {"padding_time_ms", s.padding_time_ms},
142  {"cycle_time_ms", s.cycle_time_ms}, {"controller_retries", s.controller_retries},
143  };
144  }
145 };
146 
150 enum class SimulationOutcome {
151  NoStart,
152  Aborted,
153  Stopped,
154  Failure,
155  Success,
156 };
157 
158 // If possible, the following exit codes should not be used as they are used
159 // by the Bash shell, among others: 1-2, 126-165, and 255. That leaves us
160 // primarily with the range 3-125, which should suffice for our purposes.
161 // The following exit codes should not be considered stable.
162 #define EXIT_OUTCOME_SUCCESS EXIT_SUCCESS // normally 0
163 #define EXIT_OUTCOME_UNKNOWN EXIT_FAILURE // normally 1
164 #define EXIT_OUTCOME_NOSTART 4 // 0b.....1..
165 #define EXIT_OUTCOME_STOPPED 8 // 0b....1...
166 #define EXIT_OUTCOME_FAILURE 9 // 0b....1..1
167 #define EXIT_OUTCOME_ABORTED 16 // 0b...1....
168 
169 // clang-format off
170 ENUM_SERIALIZATION(SimulationOutcome, ({
171  {SimulationOutcome::Aborted, "aborted"},
172  {SimulationOutcome::NoStart, "no-start"},
173  {SimulationOutcome::Failure, "failure"},
174  {SimulationOutcome::Success, "success"},
175  {SimulationOutcome::Stopped, "stopped"},
176 }))
177 // clang-format on
178 
179 namespace events {
180 
181 DEFINE_NIL_EVENT(Start, "start", "start of simulation")
182 DEFINE_NIL_EVENT(Stop, "stop", "stop of simulation")
183 DEFINE_NIL_EVENT(Success, "success", "simulation success")
184 DEFINE_NIL_EVENT(Failure, "failure", "simulation failure")
185 DEFINE_NIL_EVENT(Reset, "reset", "reset of simulation")
186 DEFINE_NIL_EVENT(Pause, "pause", "pausation of simulation")
187 DEFINE_NIL_EVENT(Resume, "resume", "resumption of simulation after pause")
188 DEFINE_NIL_EVENT(Loop, "loop", "begin of inner simulation loop each cycle")
189 
190 } // namespace events
191 
200  SimulationContext(sol::state_view&& l) : lua(l) {}
201 
202  sol::state_view lua;
203 
204  // Setup
205  std::unique_ptr<cloe::DataBroker> db;
206  std::unique_ptr<Server> server;
207  std::shared_ptr<Coordinator> coordinator;
208  std::shared_ptr<Registrar> registrar;
209  std::unique_ptr<CommandExecuter> commander;
210 
211  // Configuration
212  cloe::Stack config;
213  std::string uuid{};
214  bool report_progress{false};
215 
216  // State
217  SimulationSync sync;
218  SimulationProgress progress;
219  SimulationStatistics statistics;
220  cloe::Model* now_initializing{nullptr};
221  std::map<std::string, std::unique_ptr<cloe::Simulator>> simulators;
222  std::map<std::string, std::shared_ptr<cloe::Vehicle>> vehicles;
223  std::map<std::string, std::unique_ptr<cloe::Controller>> controllers;
224  std::optional<SimulationOutcome> outcome;
226  bool pause_execution{false};
227 
228  // Events
229  std::shared_ptr<events::LoopCallback> callback_loop;
230  std::shared_ptr<events::PauseCallback> callback_pause;
231  std::shared_ptr<events::ResumeCallback> callback_resume;
232  std::shared_ptr<events::StartCallback> callback_start;
233  std::shared_ptr<events::StopCallback> callback_stop;
234  std::shared_ptr<events::SuccessCallback> callback_success;
235  std::shared_ptr<events::FailureCallback> callback_failure;
236  std::shared_ptr<events::ResetCallback> callback_reset;
237  std::shared_ptr<events::TimeCallback> callback_time;
238 
239  public:
240  std::string version() const;
241  cloe::Logger logger() const { return cloe::logger::get("cloe"); }
242 
243  std::shared_ptr<cloe::Registrar> simulation_registrar();
244 
245  std::vector<std::string> model_ids() const;
246  std::vector<std::string> simulator_ids() const;
247  std::vector<std::string> controller_ids() const;
248  std::vector<std::string> vehicle_ids() const;
249  std::vector<std::string> plugin_ids() const;
250 
251  bool foreach_model(std::function<bool(cloe::Model&, const char* type)> f);
252  bool foreach_model(std::function<bool(const cloe::Model&, const char* type)> f) const;
253  bool foreach_simulator(std::function<bool(cloe::Simulator&)> f);
254  bool foreach_simulator(std::function<bool(const cloe::Simulator&)> f) const;
255  bool foreach_controller(std::function<bool(cloe::Controller&)> f);
256  bool foreach_controller(std::function<bool(const cloe::Controller&)> f) const;
257  bool foreach_vehicle(std::function<bool(cloe::Vehicle&)> f);
258  bool foreach_vehicle(std::function<bool(const cloe::Vehicle&)> f) const;
259 };
260 
261 } // namespace engine
Definition: controller.hpp:126
Definition: model.hpp:203
Definition: simulator.hpp:139
Definition: stack.hpp:879
Definition: sync.hpp:34
Definition: vehicle.hpp:106
Definition: statistics.hpp:110
void reset()
Definition: statistics.hpp:119
Definition: simulation_progress.hpp:37
Definition: simulation_context.hpp:55
double realtime_factor() const override
Definition: simulation_context.hpp:71
double achievable_realtime_factor() const override
Definition: simulation_context.hpp:77
cloe::Duration step_width() const override
Definition: simulation_context.hpp:61
cloe::Duration time() const override
Definition: simulation_context.hpp:62
cloe::Duration eta() const override
Definition: simulation_context.hpp:63
void increment_step()
Definition: simulation_context.hpp:89
void set_realtime_factor(double s)
Definition: simulation_context.hpp:98
uint64_t step() const override
Definition: simulation_context.hpp:60
std::chrono::nanoseconds Duration
Definition: cloe_fwd.hpp:36
#define ENUM_SERIALIZATION(xType, xMap)
Definition: enum.hpp:51
#define DEFINE_NIL_EVENT(xName, xname, xdescription)
Definition: nil_event.hpp:57
SimulationOutcome
Definition: simulation_context.hpp:150
@ Success
Simulation explicitly concluded with success.
@ Aborted
Simulation aborted due to technical problems or interrupt.
@ Stopped
Simulation concluded, but without valuation.
@ Failure
Simulation explicitly concluded with failure.
@ NoStart
Simulation unable to start.
Definition: simulation_context.hpp:199
Definition: simulation_context.hpp:121