Manager.cpp
Go to the documentation of this file.
1 // signal handler
5 #include <utility>
6 
7 namespace rokubimini
8 {
9 RokubiminiManager::RokubiminiManager(const bool standalone, const bool installSignalHandler, const double timeStep,
10  NodeHandlePtr nh)
11  : rokubiminis_(), busManagers_(), standalone_(standalone), timeStep_(timeStep), nh_(std::move(nh))
12 {
13  if (installSignalHandler)
14  {
16  }
17 }
18 std::shared_ptr<Rokubimini> RokubiminiManager::getRokubimini(const std::string& name) const
19 {
20  for (auto& rokubimini : rokubiminis_)
21  {
22  if (rokubimini->getName() == name)
23  {
24  return rokubimini;
25  }
26  }
27  ROS_ERROR_STREAM("Could not find Rokubimini with the name: " << name);
28  return nullptr;
29 }
30 std::vector<std::shared_ptr<Rokubimini>> RokubiminiManager::getRokubiminis() const
31 {
32  std::vector<std::shared_ptr<Rokubimini>> rokubimini_out;
33  rokubimini_out.reserve(rokubiminis_.size());
34  for (const auto& rokubimini : rokubiminis_)
35  {
36  rokubimini_out.emplace_back(rokubimini);
37  }
38  return rokubimini_out;
39 }
41 {
43  if (setup == nullptr)
44  {
45  ROS_ERROR("Could not load Bus Setup");
46  return false;
47  }
49 }
51 {
52  rokubiminis_.clear();
53  for (const auto& rokubimini_setup : setup->rokubiminis_)
54  {
55  if (!createAndConfigureRokubimini(rokubimini_setup))
56  {
57  return false;
58  }
59  }
60  return loadBusManagersSetup();
61 }
62 
64 {
65  for (const auto& bus_manager_ptr : busManagers_)
66  {
67  if (!bus_manager_ptr->loadSetup(rokubiminis_))
68  return false;
69  }
70  return true;
71 }
72 bool RokubiminiManager::RokubiminiManager::createAndConfigureRokubimini(
73  const std::shared_ptr<rokubimini::setup::Rokubimini>& rokubiminiSetup)
74 {
75  auto rokubimini = rokubimini::createRokubiminiFactory(rokubiminiSetup, nh_);
76  if (!rokubimini->loadRokubiminiSetup(rokubiminiSetup))
77  {
78  return false;
79  }
81  {
82  return false;
83  }
84  return true;
85 }
86 
87 bool RokubiminiManager::addRokubimini(const std::shared_ptr<Rokubimini>& rokubimini)
88 {
89  const std::string name = rokubimini->getName();
90  if (rokubiminiExists(name))
91  {
92  ROS_ERROR_STREAM("Cannot add Rokubimini with name '" << name << "', because it already exists.");
93  return false;
94  }
95  rokubiminis_.push_back(rokubimini);
96  return true;
97 }
98 bool RokubiminiManager::rokubiminiExists(const std::string& name) const
99 {
100  for (const auto& rokubimini : rokubiminis_)
101  {
102  if (rokubimini->getName() == name)
103  {
104  return true;
105  }
106  }
107  return false;
108 }
109 
110 void RokubiminiManager::setNodeHandle(const std::shared_ptr<ros::NodeHandle>& nh) const
111 {
112  for (const auto& rokubimini : rokubiminis_)
113  {
114  rokubimini->setNodeHandle(nh);
115  }
116 }
118 {
119  for (const auto& rokubimini : rokubiminis_)
120  {
121  rokubimini->createRosPublishers();
122  }
123 }
125 {
126  for (const auto& rokubimini : rokubiminis_)
127  {
128  rokubimini->createRosServices();
129  }
130 }
132 {
133  for (const auto& rokubimini : rokubiminis_)
134  {
135  rokubimini->publishRosMessages();
136  }
137 }
138 
140 {
141  if (isRunning_)
142  {
143  ROS_WARN_STREAM("Cannot start up, Rokubimini Manager is already running.");
144  return false;
145  }
146  ROS_DEBUG_STREAM("Starting up Rokubimini Manager ...");
147  if (busManagers_.empty())
148  {
149  throw ros::Exception("Cannot start up, a communication manager has not been set.");
150  }
151  for (const auto& rokubimini : rokubiminis_)
152  {
153  rokubimini->startupWithoutCommunication();
154  }
155  for (const auto& bus_manager_ptr : busManagers_)
156  {
157  if (!bus_manager_ptr->startupCommunication())
158  {
159  // auto rokubiminis = mapOfRokubiminisToBusManagers_.find(move(busManagerPtr))->second;
160  // search for the rokubiminis of the failed busManager
161  for (const auto& rokubimini_setup : bus_manager_ptr->getRokubiminiSetups())
162  {
163  auto rokubimini = getRokubimini(rokubimini_setup->name_);
164  rokubimini->shutdownWithoutCommunication();
165  }
166  return false;
167  }
168  }
169  for (const auto& bus_manager_ptr : busManagers_)
170  {
171  bus_manager_ptr->setConfigMode();
172  }
173  for (const auto& rokubimini : rokubiminis_)
174  {
175  rokubimini->startupWithCommunication();
176  }
177  for (const auto& bus_manager_ptr : busManagers_)
178  {
179  bus_manager_ptr->setRunMode();
180  }
181  if (standalone_)
182  {
183  bota_worker::WorkerOptions update_worker_options;
184  update_worker_options.callback_ = std::bind(&RokubiminiManager::updateWorkerCb, this, std::placeholders::_1);
185  update_worker_options.defaultPriority_ = 90;
186  update_worker_options.name_ = "RokubiminiManager::updateWorker";
187  update_worker_options.timeStep_ = timeStep_;
188  update_worker_options.enforceRate_ = true;
189  updateWorker_.reset(new bota_worker::Worker(update_worker_options));
190  if (!updateWorker_->start())
191  {
192  throw ros::Exception("Update worker could not be started.");
193  }
194  }
195  isRunning_ = true;
196  return true;
197 }
199 {
203  return true;
204 }
206 {
207  for (const auto& bus_manager_ptr : busManagers_)
208  {
209  bus_manager_ptr->readAllBuses();
210  }
211 }
213 {
214  for (const auto& rokubimini : rokubiminis_)
215  {
216  rokubimini->updateProcessReading();
217  }
218 }
219 
221 {
222  for (const auto& bus_manager_ptr : busManagers_)
223  {
224  bus_manager_ptr->writeToAllBuses();
225  }
226 }
228 {
229  if (!isRunning_)
230  {
231  ROS_WARN_STREAM("Cannot shut down, Rokubimini Manager is not running.");
232  return;
233  }
234  // If not in standalone mode, the exterior worker is already shutdown at this point.
235  // For this reason, a temporary worker has to take over the job.
236  if (!standalone_)
237  {
238  bota_worker::WorkerOptions update_worker_options;
239  update_worker_options.callback_ = std::bind(&RokubiminiManager::updateWorkerCb, this, std::placeholders::_1);
240  update_worker_options.defaultPriority_ = 90;
241  update_worker_options.name_ = "RokubiminiManager::updateWorker (shutdown)";
242  update_worker_options.timeStep_ = timeStep_;
243  update_worker_options.enforceRate_ = true;
244  updateWorker_.reset(new bota_worker::Worker(update_worker_options));
245  if (!updateWorker_->start())
246  {
247  ROS_ERROR_STREAM("Update worker (shutdown) could not be started.");
248  }
249  }
250  for (const auto& rokubimini : rokubiminis_)
251  {
252  rokubimini->shutdownWithCommunication();
253  }
254  // Stop the worker here (in both modes, standalone and not).
255  updateWorker_->stop(true);
256  for (const auto& bus_manager_ptr : busManagers_)
257  {
258  bus_manager_ptr->shutdownAllBuses();
259  }
260  for (const auto& rokubimini : rokubiminis_)
261  {
262  rokubimini->shutdownWithoutCommunication();
263  }
264  isRunning_ = false;
265 }
266 
268 {
269  return update();
270 }
272 {
273  shutdownRequested_ = true;
274  // shutdown processes which take a longer period of time
275 }
276 void RokubiminiManager::handleSignal(const int signum)
277 {
278  ROS_INFO_STREAM("Received signal (" << signum << "), requesting shutdown ...");
279  requestShutdown();
280  if (signum == SIGSEGV)
281  {
282  signal(signum, SIG_DFL);
283  kill(getpid(), signum);
284  }
285 }
286 } // namespace rokubimini
std::shared_ptr< bota_worker::Worker > updateWorker_
A Worker instance that handles the update process.
Definition: Manager.hpp:377
void updateCommunicationManagerReadMessages()
Instructs each BusManager to read the messages.
Definition: Manager.cpp:205
bool addRokubimini(const std::shared_ptr< Rokubimini > &rokubimini)
Adds a Rokubimini instance to the list.
Definition: Manager.cpp:87
void createRokubiminiRosPublishers() const
Creates ROS Publishers for each attached rokubimini.
Definition: Manager.cpp:117
bool createRokubiminisFromSetup(const rokubimini::setup::SetupPtr &setup)
Creates the Rokubimini instances from a Setup.
Definition: Manager.cpp:50
void updateProcessReadings()
Gets the Readings from each Rokubimini device.
Definition: Manager.cpp:212
bool startup() override
Starts the communication with all the Rokubimini devices.
Definition: Manager.cpp:139
bool loadSetup() override
Loads the Setup from the parameter server.
Definition: Manager.cpp:40
std::vector< std::unique_ptr< RokubiminiBusManager > > busManagers_
Definition: Manager.hpp:418
void createRokubiminiRosServices() const
Creates ROS Services for each attached rokubimini.
Definition: Manager.cpp:124
std::atomic< bool > shutdownRequested_
Boolean that specifies if shutdown has been requested.
Definition: Manager.hpp:397
std::atomic< double > timeStep_
bool updateWorkerCb(const bota_worker::WorkerEvent &event)
Callback method which when triggered calls the update() method.
Definition: Manager.cpp:267
void updateCommunicationManagerWriteMessages()
Instructs each BusManager to write the messages.
Definition: Manager.cpp:220
std::vector< std::shared_ptr< Rokubimini > > rokubiminis_
Definition: Manager.hpp:407
void handleSignal(const int signum)
Handles the signal received. Specifically requests shuts down if the signum is SIGSEGV.
Definition: Manager.cpp:276
std::shared_ptr< Setup > SetupPtr
std::shared_ptr< Rokubimini > getRokubimini(const std::string &name) const
Returns the Rokubimini instance with name name.
Definition: Manager.cpp:18
bool loadBusManagersSetup()
Calls the loadSetup() of each Bus Manager.
Definition: Manager.cpp:63
std::shared_ptr< ros::NodeHandle > NodeHandlePtr
void requestShutdown()
Sets a flag that represents that shutdown has been requested.
Definition: Manager.cpp:271
#define ROS_WARN_STREAM(args)
#define ROS_DEBUG_STREAM(args)
bool createAndConfigureRokubimini(const std::shared_ptr< rokubimini::setup::Rokubimini > &rokubiminiSetup)
Creates an implementation-specific Rokubimini instance (through the rokubimini_factory), loads the RokubiminiSetup to it and adds the new instance to the list.
std::atomic< bool > enforceRate_
bool update() override
Updates with new values from/to the Rokubiminis.
Definition: Manager.cpp:198
#define ROS_INFO_STREAM(args)
std::atomic< bool > isRunning_
Boolean that specifies if the Manager is already running.
Definition: Manager.hpp:387
bool rokubiminiExists(const std::string &name) const
Decides if a specific Rokubimini instance exists in the list.
Definition: Manager.cpp:98
void setNodeHandle(const std::shared_ptr< ros::NodeHandle > &nh) const
Sets the ROS NodeHandle to each rokubimini.
Definition: Manager.cpp:110
#define ROS_ERROR_STREAM(args)
std::vector< std::shared_ptr< Rokubimini > > getRokubiminis() const
Definition: Manager.cpp:30
std::shared_ptr< rokubimini::Rokubimini > createRokubiminiFactory(const std::shared_ptr< rokubimini::setup::Rokubimini > &rokubiminiSetup, const NodeHandlePtr &nh)
void publishRosMessages() const
Publishes the ROS messages for each attached rokubimini.
Definition: Manager.cpp:131
static void bindAll(void(T::*fp)(int), T *object)
#define ROS_ERROR(...)
rokubimini::setup::SetupPtr loadBusSetup(std::vector< std::unique_ptr< RokubiminiBusManager >> &busManagers, const NodeHandlePtr &nh)
void shutdown() override
Shuts down everything.
Definition: Manager.cpp:227


rokubimini_manager
Author(s):
autogenerated on Wed Mar 3 2021 03:09:21