9 #include "sg_monitorbase.h"
10 #include "sg_signalidgroup.h"
21 namespace signal_monitor {
33 template<
typename T,
typename CompareFunctor = std::equal_to<T>>
38 TriggerType trigger_type;
44 bool input_ref_is_local;
45 std::reference_wrapper<T> input_ref;
47 std::function<bool(
void)> clb;
52 class SignalDataFactory {
55 static signal_data make(
const SignalId& signal_id, T& input_ref,
56 T objective_val, std::function<
bool()> callback,
57 TriggerType trigger_type,
double start_time_s,
58 double stop_time_s,
bool input_ref_is_local) {
60 signal_data sd = {.enabled =
true, .trigger_type = trigger_type,
61 .changed =
true, .start_time_s = start_time_s, .actual_time_s = 0,
62 .stop_time_s = stop_time_s, .cmp =
64 .input_ref_is_local = input_ref_is_local, .input_ref = input_ref,
65 .objective = objective_val, .clb = callback};
70 static signal_data make(
const SignalId& signal_id, T& input_ref,
71 T objective_val, std::function<
bool(
const SignalId&)> callback,
72 TriggerType trigger_type,
double start_time_s,
73 double stop_time_s,
bool input_ref_is_local) {
75 auto clb = std::bind(callback, signal_id);
76 signal_data sd = {.enabled =
true, .trigger_type = trigger_type,
77 .changed =
true, .start_time_s = start_time_s, .actual_time_s = 0,
78 .stop_time_s = stop_time_s, .cmp =
80 .input_ref_is_local = input_ref_is_local, .input_ref = input_ref,
81 .objective = objective_val, .clb = clb};
86 static signal_data make(
const SignalId& signal_id, T& input_ref,
87 T objective_val, std::function<
bool(
const SignalId&, T)> callback,
88 TriggerType trigger_type,
double start_time_s,
double stop_time_s,
89 bool input_ref_is_local) {
91 auto clb = std::bind(callback, signal_id, std::ref(input_ref));
92 signal_data sd = {.enabled =
true, .trigger_type = trigger_type,
93 .changed =
true, .start_time_s = start_time_s, .actual_time_s = 0,
94 .stop_time_s = stop_time_s, .cmp =
95 {}, .input_ref_is_local = input_ref_is_local, .input_ref = input_ref,
96 .objective = objective_val, .clb = clb};
102 static signal_data make(
const SignalId& signal_id, T& input_ref,
103 T objective_val, std::pair<std::function<
bool(U*)>, U*
106 TriggerType trigger_type,
109 bool input_ref_is_local
112 auto clb = std::bind(callback.first, callback.second);
113 signal_data sd = {.enabled =
true, .trigger_type = trigger_type,
114 .changed =
true, .start_time_s = start_time_s, .actual_time_s = 0,
115 .stop_time_s = stop_time_s, .cmp =
116 {}, .input_ref_is_local = input_ref_is_local, .input_ref = input_ref,
117 .objective = objective_val, .clb = clb};
123 static signal_data make(
const SignalId& signal_id, T& input_ref,
125 std::pair<std::function<
bool(U*,
const SignalId& signal_id)>, U*> callback,
126 TriggerType trigger_type,
double start_time_s,
double stop_time_s,
127 bool input_ref_is_local) {
129 auto clb = std::bind(callback.first, callback.second, signal_id);
130 signal_data sd = {.enabled =
true, .trigger_type = trigger_type,
131 .changed =
true, .start_time_s = start_time_s, .actual_time_s = 0,
132 .stop_time_s = stop_time_s, .cmp =
133 {}, .input_ref_is_local = input_ref_is_local, .input_ref = input_ref,
134 .objective = objective_val, .clb = clb};
140 static signal_data make(
const SignalId& signal_id, T& input_ref,
141 T objective_val, std::pair<std::function<
bool(U*,
const SignalId&, T)>, U*> callback,
142 TriggerType trigger_type,
double start_time_s,
double stop_time_s,
143 bool input_ref_is_local) {
145 auto clb = std::bind(callback.first, callback.second, signal_id,
146 std::ref(input_ref));
147 signal_data sd = {.enabled =
true, .trigger_type = trigger_type,
148 .changed =
true, .start_time_s = start_time_s, .actual_time_s = 0,
149 .stop_time_s = stop_time_s, .cmp =
150 {}, .input_ref_is_local = input_ref_is_local, .input_ref = input_ref,
151 .objective = objective_val, .clb = clb};
157 std::queue<typename bool_stub<T>::type> values_storage_;
158 using callback_data = std::pair<SignalId, signal_data>;
159 std::vector<callback_data> callback_vector_;
161 void addToVector(
const SignalId& signal_id, signal_data&& clb_data) {
163 typename std::vector<callback_data>::iterator itr =
164 std::find_if(callback_vector_.begin(), callback_vector_.end(),
165 [&](
const auto& obj) {
166 return obj.first >= signal_id;
168 callback_vector_.emplace(itr, std::make_pair(signal_id, clb_data));
171 bool isInRange(
const signal_data& data)
const {
172 return (data.start_time_s <= data.actual_time_s) &&
173 (data.actual_time_s < data.stop_time_s);
176 template<
typename Action>
177 void seekAndDestroy(
const SignalIdGroup& signal_id_group,
const Action& action) {
178 auto new_err_itr = signal_id_group.begin();
179 auto new_err_end = signal_id_group.end();
181 auto err_itr = callback_vector_.begin();
182 auto prev_itr = err_itr;
183 auto err_end = callback_vector_.end();
187 for (; new_err_itr != new_err_end; ++new_err_itr) {
188 if (err_itr == err_end) {
191 while ((err_itr != err_end) && (err_itr->first <= *new_err_itr)) {
192 err_itr = std::find_if(err_itr, err_end, [&](
const auto& obj) {
193 return obj.first == *new_err_itr;
195 if (err_itr != err_end) {
196 action(err_itr->second);
206 using SignalMonitorBase::set;
207 using SignalMonitorBase::reset;
208 using SignalMonitorBase::enable;
209 using SignalMonitorBase::disable;
218 void add(
const SignalId& signal_id, T& input_ref, T objective_val,
219 std::function<
bool()> callback, TriggerType trigger_type = TRIGGER_ALWAYS,
220 double start_time_s = 0,
221 double stop_time_s = std::numeric_limits<double>::max()) {
223 addToVector(signal_id, SignalDataFactory::make(signal_id, input_ref,
224 objective_val, callback, trigger_type, start_time_s, stop_time_s,
229 void add(
const SignalId& signal_id, T& input_ref, T objective_val,
230 std::function<
bool(
const SignalId& signal_id)> callback,
231 TriggerType trigger_type = TRIGGER_ALWAYS,
double start_time_s = 0,
232 double stop_time_s = std::numeric_limits<double>::max()) {
234 addToVector(signal_id, SignalDataFactory::make(signal_id, input_ref,
235 objective_val, callback, trigger_type, start_time_s, stop_time_s,
240 void add(
const SignalId& signal_id, T& input_ref, T objective_val,
241 std::function<
bool(
const SignalId& signal_id, T)> callback,
242 TriggerType trigger_type = TRIGGER_ALWAYS,
double start_time_s = 0,
243 double stop_time_s = std::numeric_limits<double>::max()) {
245 addToVector(signal_id, SignalDataFactory::make(signal_id, input_ref,
246 objective_val, callback, trigger_type, start_time_s, stop_time_s,
252 void add(
const SignalId& signal_id, T& input_ref, T objective_val,
253 std::pair<std::function<
bool(U*)>, U*> callback,
254 TriggerType trigger_type = TRIGGER_ALWAYS,
255 double start_time_s = 0,
256 double stop_time_s = std::numeric_limits<double>::max()
259 addToVector(signal_id, SignalDataFactory::make(signal_id, input_ref,
260 objective_val, callback, trigger_type, start_time_s, stop_time_s,
266 void add(
const SignalId& signal_id, T& input_ref, T objective_val,
267 std::pair<std::function<
bool(U*,
const SignalId& signal_id)>, U*> callback,
268 TriggerType trigger_type = TRIGGER_ALWAYS,
double start_time_s = 0,
269 double stop_time_s = std::numeric_limits<double>::max()) {
271 addToVector(signal_id, SignalDataFactory::make(signal_id, input_ref,
272 objective_val, callback, trigger_type, start_time_s, stop_time_s,
278 void add(
const SignalId& signal_id, T& input_ref, T objective_val,
279 std::pair<std::function<
bool(U*,
const SignalId& signal_id, T)>, U*> callback,
280 TriggerType trigger_type = TRIGGER_ALWAYS,
double start_time_s = 0,
281 double stop_time_s = std::numeric_limits<double>::max()) {
283 addToVector(signal_id, SignalDataFactory::make(signal_id, input_ref,
284 objective_val, callback, trigger_type, start_time_s, stop_time_s,
291 void add(
const SignalId& signal_id,
const T&& input_val, T objective_val,
292 std::function<
bool()> callback, TriggerType trigger_type = TRIGGER_ALWAYS,
293 double start_time_s = 0,
294 double stop_time_s = std::numeric_limits<double>::max()) {
296 values_storage_.push(std::move(input_val));
297 addToVector(signal_id, SignalDataFactory::make(signal_id,
298 reinterpret_cast<T&
> (values_storage_.back()), objective_val,
300 trigger_type, start_time_s, stop_time_s,
true));
304 void add(
const SignalId& signal_id,
const T&& input_val, T objective_val,
305 std::function<
bool(
const SignalId& signal_id)> callback,
306 TriggerType trigger_type = TRIGGER_ALWAYS,
double start_time_s = 0,
307 double stop_time_s = std::numeric_limits<double>::max()) {
309 values_storage_.push(std::move(input_val));
310 addToVector(signal_id, SignalDataFactory::make(signal_id,
311 reinterpret_cast<T&
> (values_storage_.back()), objective_val,
313 trigger_type, start_time_s, stop_time_s,
true));
317 void add(
const SignalId& signal_id,
const T&& input_val, T objective_val,
318 std::function<
bool(
const SignalId& signal_id, T)> callback,
319 TriggerType trigger_type = TRIGGER_ALWAYS,
double start_time_s = 0,
320 double stop_time_s = std::numeric_limits<double>::max()) {
322 values_storage_.push(std::move(input_val));
323 addToVector(signal_id, SignalDataFactory::make(signal_id,
324 reinterpret_cast<T&
> (values_storage_.back()), objective_val,
326 trigger_type = TRIGGER_ALWAYS, start_time_s, stop_time_s,
true));
331 void add(
const SignalId& signal_id,
const T&& input_val, T objective_val,
332 std::pair<std::function<
bool(U*)>, U*> callback,
333 TriggerType trigger_type = TRIGGER_ALWAYS,
334 double start_time_s = 0,
335 double stop_time_s = std::numeric_limits<double>::max()
338 values_storage_.push(std::move(input_val));
339 addToVector(signal_id, SignalDataFactory::make(signal_id,
340 reinterpret_cast<T&
> (values_storage_.back()), objective_val,
342 trigger_type, start_time_s, stop_time_s,
true));
347 void add(
const SignalId& signal_id,
const T&& input_val, T objective_val,
348 std::pair<std::function<
bool(U*,
const SignalId& signal_id)>, U*> callback,
349 TriggerType trigger_type = TRIGGER_ALWAYS,
double start_time_s = 0,
350 double stop_time_s = std::numeric_limits<double>::max()) {
352 values_storage_.push(std::move(input_val));
353 addToVector(signal_id, SignalDataFactory::make(signal_id,
354 reinterpret_cast<T&
> (values_storage_.back()), objective_val,
356 trigger_type, start_time_s, stop_time_s,
true));
361 void add(
const SignalId& signal_id,
const T&& input_val, T objective_val,
362 std::pair<std::function<
bool(U*,
const SignalId& signal_id, T)>, U*> callback,
363 TriggerType trigger_type = TRIGGER_ALWAYS,
double start_time_s = 0,
364 double stop_time_s = std::numeric_limits<double>::max()) {
366 values_storage_.push(std::move(input_val));
367 addToVector(signal_id, SignalDataFactory::make(signal_id,
368 reinterpret_cast<T&
> (values_storage_.back()), objective_val,
370 trigger_type, start_time_s, stop_time_s,
true));
374 void iterate(
double dt_sec);
376 void set(
const SignalId& signal_id);
378 void set(
const SignalId& signal_id,
const T& value);
380 void setObjective(
const SignalId& signal_id,
const T& value);
382 void reset(
const SignalId& signal_id);
384 void enable(
const SignalId& signal_id);
386 void disable(
const SignalId& signal_id);
404 template<
typename T,
typename CompareFunctor>
406 for (
auto& a : callback_vector_) {
407 auto& signal_data = a.second;
408 if (signal_data.enabled) {
409 bool signal_cmp = signal_data.cmp(signal_data.input_ref, signal_data.objective);
410 if (isInRange(signal_data) && signal_cmp) {
411 switch (signal_data.trigger_type) {
412 case TriggerType::TRIGGER_ONCE:
413 if (signal_data.changed) {
414 signal_data.changed = !signal_data.clb();
417 case TriggerType::TRIGGER_TOGGLE:
418 if (signal_data.clb()) {
419 signal_data.objective = !signal_data.input_ref;
422 case TriggerType::TRIGGER_ALWAYS:
426 log_assert(0,
"TriggerType has unknown value!");
430 signal_data.actual_time_s += dt_sec;
432 signal_data.changed =
true;
433 signal_data.actual_time_s = 0;
439 template<
typename T,
typename CompareFunctor>
440 void SignalMonitor<T, CompareFunctor>::set(
const SignalId& signal_id) {
441 for (
auto& itr : callback_vector_) {
442 if (itr.first == signal_id) {
443 itr.second.input_ref.get() = itr.second.objective;
448 template<
typename T,
typename CompareFunctor>
449 void SignalMonitor<T, CompareFunctor>::set(
const SignalId& signal_id,
const T& value) {
450 for (
auto& itr : callback_vector_) {
451 if (itr.first == signal_id) {
452 itr.second.input_ref.get() = value;
457 template<
typename T,
typename CompareFunctor>
458 void SignalMonitor<T, CompareFunctor>::setObjective(
const SignalId& signal_id,
const T& value) {
459 for (
auto& itr : callback_vector_) {
460 if (itr.first == signal_id) {
461 itr.second.objective = value;
466 template<
typename T,
typename CompareFunctor>
467 void SignalMonitor<T, CompareFunctor>::reset(
const SignalId& signal_id) {
468 for (
auto& itr : callback_vector_) {
469 if (itr.first == signal_id) {
470 itr.second.changed =
true;
471 itr.second.actual_time_s = 0;
472 if (itr.second.input_ref_is_local) {
473 itr.second.input_ref.get() = !itr.second.objective;
479 template<
typename T,
typename CompareFunctor>
480 void SignalMonitor<T, CompareFunctor>::enable(
const SignalId& signal_id) {
481 for (
auto& itr : callback_vector_) {
482 if (itr.first == signal_id) {
483 itr.second.enabled =
true;
488 template<
typename T,
typename CompareFunctor>
489 void SignalMonitor<T, CompareFunctor>::disable(
const SignalId& signal_id) {
490 for (
auto& itr : callback_vector_) {
491 if (itr.first == signal_id) {
492 itr.second.enabled =
false;
497 template<
typename T,
typename CompareFunctor>
498 void SignalMonitor<T, CompareFunctor>::set(
const SignalIdGroup& signal_id_group) {
499 auto action = [](
auto& signal) {
500 signal.input_ref.get() = signal.objective;
502 seekAndDestroy(signal_id_group, action);
505 template<
typename T,
typename CompareFunctor>
506 void SignalMonitor<T, CompareFunctor>::reset(
const SignalIdGroup& signal_id_group) {
507 auto action = [](
auto& signal) {
508 signal.changed =
true;
509 signal.actual_time_s = 0;
510 if (signal.input_ref_is_local) {
511 signal.input_ref.get() = !signal.objective;
514 seekAndDestroy(signal_id_group, action);
517 template<
typename T,
typename CompareFunctor>
518 void SignalMonitor<T, CompareFunctor>::enable(
const SignalIdGroup& signal_id_group) {
519 auto action = [](
auto& signal) {
520 signal.enabled =
true;
522 seekAndDestroy(signal_id_group, action);
525 template<
typename T,
typename CompareFunctor>
526 void SignalMonitor<T, CompareFunctor>::disable(
const SignalIdGroup& signal_id_group) {
527 auto action = [](
auto& signal) ->
void {
528 signal.enabled =
false;
530 seekAndDestroy(signal_id_group, action);
533 template<
typename T,
typename CompareFunctor>
534 void SignalMonitor<T, CompareFunctor>::reset(
void) {
535 for (
auto& itr : callback_vector_) {
536 itr.second.changed =
true;
537 itr.second.actual_time_s = 0;
538 if (itr.second.input_ref_is_local) {
539 itr.second.input_ref.get() = !itr.second.objective;
544 template<
typename T,
typename CompareFunctor>
545 void SignalMonitor<T, CompareFunctor>::enable(
void) {
546 for (
auto& itr : callback_vector_) {
547 itr.second.enabled =
true;
551 template<
typename T,
typename CompareFunctor>
552 void SignalMonitor<T, CompareFunctor>::disable(
void) {
553 for (
auto& itr : callback_vector_) {
554 itr.second.enabled =
false;