Motorcortex Core  version: 2.7.6
ct_module.h
1 /*
2  * Developer : Alexey Zakharov (alexey.zakharov@vectioneer.com)
3  * All rights reserved. Copyright (c) 2015 - 2021 VECTIONEER.
4  */
5 
6 #ifndef CONTAINER_CT_MODULE_H
7 #define CONTAINER_CT_MODULE_H
8 
9 #include "ct_helpers.h"
10 #include "ct_time.h"
11 #include "ps_parameter.h"
12 #include "utl_span.h"
13 #include "visit_helper.h"
14 #include "visit_struct.h"
15 #include <cstdint>
16 #include <functional>
17 #include <mutex>
18 #include <string>
19 #include <vector>
20 
21 namespace mcx::container {
22 
62 
64 class Module {
65 public:
70  enum class ModuleStates {
71  NOT_INITIALIZED = 0,
72  PHASE_0 = 1,
73  PHASE0 = 2,
74  PHASE0_1 = 3,
75  PHASE1 = 4,
76  PHASE1_2 = 5,
77  PHASE2 = 6,
78  PHASE2_OP = 7,
79  OP = 8,
80  OP_PHASE2 = 9,
81  PHASE2_NOT_INIT = 10,
82  };
83 
88  enum class ModuleErrors { NO_ERROR = 0, NO_CALLBACK_DEFINED = 1, CALLBACK_FAILED = 2, WRONG_STATE = 3 };
89 
94  enum class ModuleEvents { EMPTY = -1, STOP = 0, START = 1, PAUSE = 2, ACK = 0xFF };
95 
97  Module();
98 
100  virtual ~Module() = default;
101 
103  Module(const Module& orig) = delete;
104 
106  Module& operator=(const Module&) = delete;
107 
123  void create(const char* name, parameter_server::Parameter* parameter_server, uint64_t dt_micro_s = 0);
124 
142  void create(const char* name, parameter_server::Parameter* parameter_server, uint64_t dt_micro_s,
143  parameter_server::UserGroup owner_group, uint32_t permissions = parameter_server::default_permissions);
144 
153  bool initPhase1();
154 
163  bool initPhase2();
164 
173  bool startOp();
174 
183  bool stopOp();
184 
192  bool iterate(const TaskTime& task_time, UserTime* user_time);
193 
198  void setName(const char* name);
199 
204  const char* getName() const;
205 
210  void setDtMicroSec(uint64_t micro_sec);
211 
216  uint64_t getDtMicroSec() const;
217 
222  void setDtSec(double sec);
223 
228  double getDtSec() const;
229 
235  ModuleStates getState() const;
236 
242  void setEvent(ModuleEvents event);
243 
249  ModuleErrors getError() const;
250 
251 protected:
259  virtual void create_(const char* name, parameter_server::Parameter* parameter_server, uint64_t dt_micro_s) = 0;
260 
267  virtual bool initPhase1_() = 0;
268 
278  virtual bool initPhase2_() = 0;
279 
290  virtual bool startOp_() = 0;
291 
298  virtual bool stopOp_() = 0;
299 
311  virtual bool iteratePreOp_(const TaskTime& system_time, UserTime* user_time) { return true; }
312 
319  virtual bool iterateOp_(const TaskTime& system_time, UserTime* user_time) = 0;
320 
336  void createSubmodule(Module* module, const char* name);
337 
350  template <typename T>
351  void createSubmodules(utils::span<T> module_array, const char* basename) {
352  size_t idx = 0;
353  for (auto& module : module_array) {
354  createSubmodule(&module, fmt::format("{}{:02d}", basename, ++idx).c_str());
355  }
356  }
357 
365  void setType(const char* name);
366 
383  template <size_t buffer_size = parameter_server::DEFAULT_INPUT_BUFFER_LENGTH>
384  parameter_server::ParamHandle addParameter(const char* id, parameter_server::ParameterType param_type, char* str_ptr,
385  size_t length);
386 
408  template <typename T, size_t buffer_size = parameter_server::DEFAULT_INPUT_BUFFER_LENGTH,
409  add_visitable::EnableIfNotVisitable<T> = true>
410  parameter_server::ParamHandle addParameter(const char* id, parameter_server::ParameterType param_type, T* value_ptr,
411  size_t length = 1,
412  parameter_server::Unit param_unit = parameter_server::Unit::undefined);
413 
439  template <typename T, size_t buffer_size = parameter_server::DEFAULT_INPUT_BUFFER_LENGTH,
440  add_visitable::EnableIfVisitable<T> = true>
441  parameter_server::GroupHandle addParameter(const char* id, parameter_server::ParameterType param_type, T* value_ptr,
442  size_t length = 1,
443  parameter_server::Unit param_unit = parameter_server::Unit::undefined);
444 
471  template <typename T, size_t buffer_size = parameter_server::DEFAULT_INPUT_BUFFER_LENGTH>
472  parameter_server::ParamHandle addParameter(const char* id, parameter_server::ParameterType param_type,
473  parameter_server::DataType data_type, T* value_ptr, size_t length = 1,
474  parameter_server::Unit param_unit = parameter_server::Unit::undefined);
475 
484  parameter_server::SubHandle subscribe(const char* path);
485 
494  parameter_server::ReqHandle request(const char* path);
495 
504  parameter_server::PubHandle publish(const char* path);
505 
511 
517 
518 private:
519  friend class Task;
520 
521  inline void updateLinks() {
522  if (local_branch_.isLinkUpdated()) {
523  local_branch_.updateLink();
524  }
525  }
526 
527  inline void updateInputs() {
528  if (local_branch_.isInputUpdated()) {
529  local_branch_.updateInput();
530  }
531 
532  if (local_branch_.isOverwriteInputUpdated()) {
533  local_branch_.overwriteInput();
534  }
535  }
536 
537  parameter_server::ParamHandle addParameter(const char* name, parameter_server::ParameterType param_type,
538  uint32_t data_type, int32_t data_type_size, parameter_server::Unit unit,
539  void* value_ptr, uint32_t origin_length, uint32_t buffer_length);
540 
541  bool createWrapper();
542 
543  const char* stateToStr(ModuleStates state) const;
544 
545  bool readyToStart();
546 
547  bool switchState(ModuleStates* actual_state_ptr, ModuleErrors* error_ptr, ModuleStates expected_state,
548  ModuleStates new_state, const std::function<bool(Module*)>&, std::mutex* switch_guard);
549 
550  uint64_t dt_micro_s_{};
551  uint64_t utilization_{};
552  std::string module_name_{"Undefined"};
553  std::string module_type_;
554  parameter_server::Parameter* root_ptr_{};
555  parameter_server::Parameter local_branch_;
556  std::vector<Module*> submodules_;
557 
558  ModuleStates state_{ModuleStates::NOT_INITIALIZED};
559  ModuleErrors error_{ModuleErrors::NO_ERROR};
560  ModuleEvents event_{ModuleEvents::EMPTY};
561  ModuleEvents old_event_{ModuleEvents::EMPTY};
562  mutable std::mutex switch_guard_;
563 };
564 
568 
569 inline parameter_server::Parameter* Module::getLocalBranch() { return &local_branch_; }
570 
571 inline void Module::setDtMicroSec(uint64_t micro_sec) {
572  dt_micro_s_ = micro_sec;
573  for (auto& m : submodules_) {
574  m->setDtMicroSec(micro_sec);
575  }
576 }
577 
578 inline uint64_t Module::getDtMicroSec() const { return dt_micro_s_; }
579 
580 inline void Module::setDtSec(double sec) { setDtMicroSec(static_cast<uint64_t>(sec * 1000000)); }
581 
582 inline double Module::getDtSec() const { return dt_micro_s_ / 1000000.0; }
583 
584 template <size_t buffer_size>
585 parameter_server::ParamHandle Module::addParameter(const char* id, parameter_server::ParameterType param_type,
586  char* str_ptr, size_t length) {
587 
588  parameter_server::DataType data_type = parameter_server::DataType::STRING;
589  parameter_server::Unit param_unit = parameter_server::Unit::undefined;
590 
591  return addParameter<char, buffer_size>(id, param_type, data_type, str_ptr, length, param_unit);
592 }
593 
594 template <typename T, size_t buffer_size, add_visitable::EnableIfNotVisitable<T>>
596 Module::addParameter(const char* id, parameter_server::ParameterType param_type, T* value_ptr, size_t length /*= 1*/,
597  parameter_server::Unit param_unit /*= parameter_server::Unit::undefined*/) {
598  auto type = mcx::getType(*value_ptr);
599  return addParameter<T, buffer_size>(id, param_type, std::get<0>(type), value_ptr, length, param_unit);
600 }
601 
602 template <typename T, size_t buffer_size, add_visitable::EnableIfVisitable<T>>
603 parameter_server::GroupHandle Module::addParameter(const char* id, parameter_server::ParameterType param_type,
604  T* value_ptr, size_t length, parameter_server::Unit) {
605  log_assert(length == 1, "addParameter for the visitable structures does not support length > 1");
606  add_visitable::ParamHandleMap params_handle_map;
607  auto root = add_visitable::addParameterVisitableArrayImpl<buffer_size>(
608  &local_branch_, &local_branch_, params_handle_map, nullptr, id, param_type, *value_ptr);
609  return mcx::parameter_server::GroupHandle(root, std::move(params_handle_map));
610 }
611 
612 template <typename T, size_t buffer_size>
613 parameter_server::ParamHandle Module::addParameter(const char* id, parameter_server::ParameterType param_type,
614  parameter_server::DataType data_type, T* value_ptr, size_t length,
615  parameter_server::Unit param_unit) {
616  size_t type_size = sizeof(T);
617  return addParameter(id, param_type, static_cast<unsigned int>(data_type), static_cast<int32_t>(type_size), param_unit,
618  value_ptr, static_cast<uint32_t>(length), static_cast<uint32_t>(buffer_size));
619 }
620 
621 } // namespace mcx::container
622 
623 #endif // CONTAINER_CT_MODULE_H
mcx::container::Module::request
parameter_server::ReqHandle request(const char *path)
Helper function to request a parameter's value.
Definition: ct_module.cpp:291
mcx::container::Module::stopOp_
virtual bool stopOp_()=0
User-defined callback before to stop Operation mode.
mcx::container::Module::addParameter
parameter_server::ParamHandle addParameter(const char *id, parameter_server::ParameterType param_type, char *str_ptr, size_t length)
Helper function to register C-string member variable in the parameter tree.
Definition: ct_module.h:585
mcx::container::Module::initPhase2_
virtual bool initPhase2_()=0
User-defined callback after the parameter tree is ready.
mcx::container::Module::getDtMicroSec
uint64_t getDtMicroSec() const
Returns a cycle time as an integer in microseconds.
Definition: ct_module.h:578
mcx::container::Module::publish
parameter_server::PubHandle publish(const char *path)
Helper function to update parameter's value.
Definition: ct_module.cpp:293
mcx::container::Module::stopOp
bool stopOp()
Stops Operation mode, switches back to PHASE2.
Definition: ct_module.cpp:145
mcx::parameter_server::Parameter
Definition: ps_parameter.h:45
mcx::container::Module::setEvent
void setEvent(ModuleEvents event)
Command an event.
Definition: ct_module.cpp:255
mcx::container::Module::ModuleErrors
ModuleErrors
Definition: ct_module.h:88
mcx::container::Module::getName
const char * getName() const
Returns the name of the module.
Definition: ct_module.cpp:246
mcx::container::Module::setType
void setType(const char *name)
Sets a type of the module.
Definition: ct_module.cpp:295
mcx::container::Module::createSubmodules
void createSubmodules(utils::span< T > module_array, const char *basename)
Creates and registers an array of submodules.
Definition: ct_module.h:351
mcx::container::Module::createSubmodule
void createSubmodule(Module *module, const char *name)
Creates and registers submodule.
Definition: ct_module.cpp:259
mcx::container::Module::iteratePreOp_
virtual bool iteratePreOp_(const TaskTime &system_time, UserTime *user_time)
User-defined callback which is called during Phase 2.
Definition: ct_module.h:311
mcx::container::Module::iterate
bool iterate(const TaskTime &task_time, UserTime *user_time)
Iterates an execution cycle of the module.
Definition: ct_module.cpp:159
mcx::container::Module::initPhase1
bool initPhase1()
Executes initialization of the parameter tree phase.
Definition: ct_module.cpp:91
mcx::parameter_server::ReqHandle
Definition: ps_handlers.h:134
mcx::container::Task
Event loop and concurrency primitive for Motorcortex modules.
Definition: ct_task.h:31
mcx::container::Module::setDtMicroSec
void setDtMicroSec(uint64_t micro_sec)
Sets a cycle time of module and its submodules in microseconds.
Definition: ct_module.h:571
mcx::container::Module::Module
Module()
Default constructor.
Definition: ct_module.cpp:13
mcx::container::TaskTime
Internal time source.
Definition: ct_time.h:25
mcx::container::Module::Module
Module(const Module &orig)=delete
Copy constructors are deleted.
mcx::container::Module::getParameterRoot
parameter_server::Parameter * getParameterRoot()
Returns the root of the parameter tree.
Definition: ct_module.h:567
mcx::container::Module::initPhase2
bool initPhase2()
Initialization, which require parameter tree to be complete and loaded.
Definition: ct_module.cpp:116
mcx::container::Module::getState
ModuleStates getState() const
Returns an actual state.
Definition: ct_module.cpp:248
mcx::container::Module::setName
void setName(const char *name)
Sets the name of the module.
Definition: ct_module.cpp:241
mcx::container::Module::~Module
virtual ~Module()=default
Default destructor.
mcx::container::Module::subscribe
parameter_server::SubHandle subscribe(const char *path)
Helper function to subscribe for the parameter's update.
Definition: ct_module.cpp:289
mcx::container::Module::getDtSec
double getDtSec() const
Definition: ct_module.h:582
mcx::container::Module::create
void create(const char *name, parameter_server::Parameter *parameter_server, uint64_t dt_micro_s=0)
Executes 'Create' phase of initialization.
Definition: ct_module.cpp:20
mcx::container::Module::operator=
Module & operator=(const Module &)=delete
Copy constructors are deleted.
mcx::container::Module::getError
ModuleErrors getError() const
Returns active error code.
Definition: ct_module.cpp:257
mcx::container::Module::startOp
bool startOp()
Final initialization before entering Operation mode.
Definition: ct_module.cpp:131
mcx::container::Module::create_
virtual void create_(const char *name, parameter_server::Parameter *parameter_server, uint64_t dt_micro_s)=0
User-defined callback, which is executed during 'Create' phase.
mcx::container::Module::ModuleEvents
ModuleEvents
Definition: ct_module.h:94
mcx::parameter_server::GroupHandle
Definition: ps_handlers.h:90
mcx::container::Module::getLocalBranch
parameter_server::Parameter * getLocalBranch()
Returns the root of the local branch.
Definition: ct_module.h:569
mcx::parameter_server::SubHandle
Definition: ps_handlers.h:182
mcx::container::UserTime
External time source.
Definition: ct_time.h:40
mcx::parameter_server::PubHandle
Definition: ps_handlers.h:208
mcx::container::Module
A building block of the Motorcortex components.
Definition: ct_module.h:64
mcx::container::Module::iterateOp_
virtual bool iterateOp_(const TaskTime &system_time, UserTime *user_time)=0
User-defined callback which is called during Operation mode.
mcx::container::Module::initPhase1_
virtual bool initPhase1_()=0
User-defined callback to register parameters in the tree.
mcx::container::Module::startOp_
virtual bool startOp_()=0
User-defined callback before entering Operation mode.
mcx::container::Module::setDtSec
void setDtSec(double sec)
Sets a cycle time of module and its submodules in seconds.
Definition: ct_module.h:580
mcx::container::Module::ModuleStates
ModuleStates
Definition: ct_module.h:70
mcx::parameter_server::ParamHandle
Definition: ps_handlers.h:43