SMACC
Loading...
Searching...
No Matches
signal_detector.cpp
Go to the documentation of this file.
1/*****************************************************************************************************************
2 * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018
3 * Authors: Pablo Inigo Blasco, Brett Aldrich
4 *
5 ******************************************************************************************************************/
9#include <thread>
10
11namespace smacc
12{
19 : end_(false),
20 initialized_(false),
21 executionModel_(executionModel)
22{
23 scheduler_ = scheduler;
24 loop_rate_hz = 20.0;
25}
26
33{
34 smaccStateMachine_ = stateMachine;
35 lastState_ = std::numeric_limits<uint64_t>::quiet_NaN();
37 initialized_ = true;
38}
39
46{
47 this->updatableClients_.clear();
48 for (auto pair : this->smaccStateMachine_->getOrthogonals())
49 {
50 auto &orthogonal = pair.second;
51 auto &clients = orthogonal->getClients();
52
53 for (auto &client : clients)
54 {
55 // updatable client components
56 auto updatableClient = dynamic_cast<ISmaccUpdatable *>(client.get());
57
58 if (updatableClient != nullptr)
59 {
60 ROS_DEBUG_STREAM("Adding updatable client: " << demangleType(typeid(updatableClient)));
61 this->updatableClients_.push_back(updatableClient);
62 }
63
64 // updatable client components
65 std::vector<std::shared_ptr<ISmaccComponent>> components;
66 client->getComponents(components);
67 for (auto &componententry : components)
68 {
69 auto updatableComponent = dynamic_cast<ISmaccUpdatable *>(componententry.get());
70 if (updatableComponent != nullptr)
71 {
72 ROS_DEBUG_STREAM("Adding updatable component: " << demangleType(typeid(*updatableComponent)));
73 this->updatableClients_.push_back(updatableComponent);
74 }
75 }
76 }
77 }
78}
79
86{
87 updatableStateElements_.push_back(std::vector<ISmaccUpdatable *>());
88
89 auto& updatableElements = updatableStateElements_.back();
90
91 for (auto pair : this->smaccStateMachine_->getOrthogonals())
92 {
93 auto &orthogonal = pair.second;
94 auto &behaviors = orthogonal->getClientBehaviors().back();
95
96 for (auto &currentBehavior : behaviors)
97 {
98 ISmaccUpdatable *updatableClientBehavior = dynamic_cast<ISmaccUpdatable *>(currentBehavior.get());
99
100 if (updatableClientBehavior != nullptr)
101 {
102 ROS_DEBUG_STREAM("Adding updatable behavior: " << demangleType(typeid(updatableClientBehavior)));
103 updatableElements.push_back(updatableClientBehavior);
104 }
105 }
106 }
107
108 auto updatableState = dynamic_cast<ISmaccUpdatable *>(currentState);
109 if (updatableState != nullptr)
110 {
111 updatableElements.push_back(updatableState);
112 }
113
114 auto statereactors = currentState->getStateReactors();
115 for (auto &sr : statereactors)
116 {
117 ISmaccUpdatable *updatableStateReactor = dynamic_cast<ISmaccUpdatable *>(sr.get());
118 if (updatableStateReactor != nullptr)
119 {
120 ROS_DEBUG_STREAM("Adding updatable stateReactorr: " << demangleType(typeid(updatableStateReactor)));
121 updatableElements.push_back(updatableStateReactor);
122 }
123 }
124
125 auto eventgenerators = currentState->getEventGenerators();
126 for (auto &eg : eventgenerators)
127 {
128 ISmaccUpdatable *updatableEventGenerator = dynamic_cast<ISmaccUpdatable *>(eg.get());
129 if (updatableEventGenerator != nullptr)
130 {
131 ROS_DEBUG_STREAM("Adding updatable eventGenerator: " << demangleType(typeid(updatableEventGenerator)));
132 updatableElements.push_back(updatableEventGenerator);
133 }
134 }
135}
136
142void SignalDetector::setProcessorHandle(SmaccFifoScheduler::processor_handle processorHandle)
143{
144 processorHandle_ = processorHandle;
145}
146
153{
154 signalDetectorThread_ = boost::thread(boost::bind(&SignalDetector::pollingLoop, this));
155}
156
163{
165}
166
173{
174 end_ = true;
175}
176
178{
179 this->findUpdatableStateElements(currentState);
180}
181
183{
184 this->updatableStateElements_.pop_back();
185}
186
187
194{
195 // precondition: smaccStateMachine_ != nullptr
196
197 try
198 {
199 smaccStateMachine_->lockStateMachine("update behaviors");
200
201 this->findUpdatableClients();
202 ROS_DEBUG_STREAM("updatable clients: " << this->updatableClients_.size());
203
204 if (this->updatableClients_.size())
205 {
206 for (auto *updatableClient : this->updatableClients_)
207 {
208 ROS_DEBUG_STREAM("[PollOnce] update client call: " << demangleType(typeid(updatableClient)));
209 updatableClient->executeUpdate();
210 }
211 }
212
213 // STATE UPDATABLE ELEMENTS
215 this->smaccStateMachine_->stateMachineCurrentAction != StateMachineInternalAction::STATE_CONFIGURING &&
216 this->smaccStateMachine_->stateMachineCurrentAction != StateMachineInternalAction::STATE_EXITING &&
217 this->smaccStateMachine_->stateMachineCurrentAction != StateMachineInternalAction::STATE_ENTERING)
218 {
219
220 // // we do not update updatable elements during trasitioning or configuration of states
221 // long currentStateIndex = smaccStateMachine_->getCurrentStateCounter();
222
223 // ROS_DEBUG_STREAM("[PollOnce] update behaviors. checking current state");
224
225 // auto currentState = smaccStateMachine_->getCurrentState();
226 // if (currentState != nullptr)
227 // {
228 // ROS_DEBUG_STREAM("[PollOnce] current state: " << currentStateIndex);
229 // ROS_DEBUG_STREAM("[PollOnce] last state: " << this->lastState_);
230
231 // if (currentStateIndex != 0)
232 // {
233 // if (currentStateIndex != this->lastState_)
234 // {
235 // ROS_DEBUG_STREAM("[PollOnce] detected new state, refreshing updatable client behavior table");
236 // // we are in a new state, refresh the updatable client behaviors table
237 // this->lastState_ = currentStateIndex;
238 // }
239
240 ROS_DEBUG_STREAM("updatable states: " << this->updatableStateElements_.size());
241
242 for (auto stateElement : this->updatableStateElements_)
243 {
244 for (auto *udpatableStateElement : stateElement)
245 {
246 ROS_DEBUG_STREAM("pollOnce update client behavior call: " << demangleType(typeid(*udpatableStateElement)));
247 udpatableStateElement->executeUpdate();
248 }
249 }
250 // }
251 //}
252 }
253 }
254 catch (std::exception &ex)
255 {
256 ROS_ERROR("Exception during Signal Detector update loop. %s", ex.what());
257 }
258
259 smaccStateMachine_->unlockStateMachine("update behaviors");
260}
261
268{
269 // ros::NodeHandle nh("~"); // use node name as root of the parameter server
270
271 ros::NodeHandle _;
272 ros::Rate r0(20);
273 while (!initialized_)
274 {
275 r0.sleep();
276 }
277
278 ros::NodeHandle nh(smacc::utils::cleanShortTypeName(typeid(*this->smaccStateMachine_)));
279
280 if (!nh.getParam("signal_detector_loop_freq", this->loop_rate_hz))
281 {
282 ROS_WARN("Signal detector frequency (ros param ~signal_detector_loop_freq) was not set, using default frequency: "
283 "%lf",
284 this->loop_rate_hz);
285 }
286 else
287 {
288 ROS_WARN("Signal detector frequency (ros param ~signal_detector_loop_freq): %lf", this->loop_rate_hz);
289 }
290
291 nh.setParam("signal_detector_loop_freq", this->loop_rate_hz);
292
293 ROS_INFO_STREAM("[SignalDetector] loop rate hz:" << loop_rate_hz);
294
296 {
297 ROS_INFO_STREAM("[SignalDetector] running in single threaded mode");
298
299 ros::Rate r(loop_rate_hz);
300 while (ros::ok() && !end_)
301 {
302 ROS_INFO_STREAM_THROTTLE(10, "[SignalDetector] heartbeat");
303 pollOnce();
304 ros::spinOnce();
305 r.sleep();
306 }
307 }
308 else
309 {
310 ROS_INFO_STREAM("[SignalDetector] running in multi threaded mode");
311 ros::AsyncSpinner spinner(1);
312 spinner.start();
313 ros::waitForShutdown();
314 }
315
316}
317} // namespace smacc
void lockStateMachine(std::string msg)
StateMachineInternalAction stateMachineCurrentAction
const std::map< std::string, std::shared_ptr< smacc::ISmaccOrthogonal > > & getOrthogonals() const
void unlockStateMachine(std::string msg)
std::vector< std::shared_ptr< SmaccEventGenerator > > & getEventGenerators()
Definition: smacc_state.h:62
std::vector< std::shared_ptr< StateReactor > > & getStateReactors()
Definition: smacc_state.h:60
std::atomic< bool > initialized_
std::vector< std::vector< ISmaccUpdatable * > > updatableStateElements_
std::vector< ISmaccUpdatable * > updatableClients_
std::atomic< uint64_t > lastState_
void notifyStateConfigured(ISmaccState *currentState)
SignalDetector(SmaccFifoScheduler *scheduler, ExecutionModel executionModel=ExecutionModel::SINGLE_THREAD_SPINNER)
boost::thread signalDetectorThread_
void findUpdatableStateElements(ISmaccState *currentState)
ISmaccStateMachine * smaccStateMachine_
void initialize(ISmaccStateMachine *stateMachine)
SmaccFifoScheduler::processor_handle processorHandle_
std::atomic< bool > end_
void setProcessorHandle(SmaccFifoScheduler::processor_handle processorHandle)
void notifyStateExited(ISmaccState *currentState)
SmaccFifoScheduler * scheduler_
std::string demangleType(const std::type_info *tinfo)
Definition: introspection.h:86
std::string cleanShortTypeName(const std::type_info &tinfo)
Definition: common.cpp:14
boost::statechart::fifo_scheduler< SmaccFifoWorker, SmaccAllocator > SmaccFifoScheduler