SMACC2
Loading...
Searching...
No Matches
smacc_signal_detector.hpp
Go to the documentation of this file.
1// Copyright 2021 RobosoftAI Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/*****************************************************************************************************************
16 *
17 * Authors: Pablo Inigo Blasco, Brett Aldrich
18 *
19 ******************************************************************************************************************/
20#pragma once
21
22#include <atomic>
23#include <boost/thread.hpp>
24#include <smacc2/common.hpp>
25#include <smacc2_msgs/msg/smacc_status.hpp>
26
27namespace smacc2
28{
34
35// Mostly define the state machine ros thread and receive events state machine components (clients, state elements)
36// This class also contains the event queue of the state machine
38{
39public:
43
45
46 void setProcessorHandle(SmaccFifoScheduler::processor_handle processorHandle);
47
48 // Runs the polling loop into a thread...
49 void runThread();
50
51 // Waits for the polling thread to end...
52 void join();
53
54 void stop();
55
56 void pollingLoop();
57
58 template <typename EventType>
60 {
61 boost::intrusive_ptr<EventType> weakPtrEvent = ev;
62 this->scheduler_->queue_event(processorHandle_, weakPtrEvent);
63 }
64
65 rclcpp::Node::SharedPtr getNode();
66 inline rclcpp::Logger getLogger() { return getNode()->get_logger(); }
67
68 void notifyStateConfigured(ISmaccState * currentState);
69
70 void notifyStateExited(ISmaccState * currentState);
71
72private:
73 void pollOnce();
74
76
77 std::vector<ISmaccUpdatable *> updatableClients_;
78
79 std::vector<std::vector<ISmaccUpdatable *>> updatableStateElements_;
80 std::atomic<int64_t> lastState_;
81
83
84 void findUpdatableStateElements(ISmaccState * currentState);
85
86 // Loop frequency of the signal detector (to check answers from actionservers)
88
89 std::atomic<bool> end_;
90
91 std::atomic<bool> initialized_;
92
93 rclcpp::Publisher<smacc2_msgs::msg::SmaccStatus>::SharedPtr statusPub_;
94
95 // ---- boost statechart related ----
96
98
99 SmaccFifoScheduler::processor_handle processorHandle_;
100
102
104};
105
106void onSigQuit(int sig);
107
108// Main entry point for any SMACC state machine
109// It instantiates and starts the specified state machine type
110// it uses two threads: a new thread and the current one.
111// The created thread is for the state machine process
112// it locks the current thread to handle events of the state machine
113template <typename StateMachineType>
115{
116 ::signal(SIGQUIT, onSigQuit);
117
118 // create the asynchronous state machine scheduler
119 SmaccFifoScheduler scheduler1(true);
120
121 // create the signalDetector component
122 SignalDetector signalDetector(&scheduler1, executionModel);
123
124 // create the asynchronous state machine processor
125 SmaccFifoScheduler::processor_handle sm =
126 scheduler1.create_processor<StateMachineType>(&signalDetector);
127
128 // initialize the asynchronous state machine processor
129 signalDetector.setProcessorHandle(sm);
130
131 scheduler1.initiate_processor(sm);
132
133 //create a thread for the asynchronous state machine processor execution
134 boost::thread schedulerThread(boost::bind(&sc::fifo_scheduler<>::operator(), &scheduler1, 0));
135
136 // use the main thread for the signal detector component (waiting actionclient requests)
137 signalDetector.pollingLoop();
138}
139
141{
142 boost::thread * schedulerThread;
143 boost::thread * signalDetectorLoop;
146 SmaccFifoScheduler::processor_handle sm;
147};
148
149template <typename StateMachineType>
151{
152 ::signal(SIGQUIT, onSigQuit);
153
154 SmExecution * ret = new SmExecution();
155
156 // create the asynchronous state machine scheduler
157 ret->scheduler1 = new SmaccFifoScheduler(true);
158
159 // create the signalDetector component
160 ret->signalDetector = new SignalDetector(ret->scheduler1);
161
162 // create the asynchronous state machine processor
163 ret->sm = ret->scheduler1->create_processor<StateMachineType>(ret->signalDetector);
164
165 // initialize the asynchronous state machine processor
166 ret->signalDetector->setProcessorHandle(ret->sm);
167
168 ret->scheduler1->initiate_processor(ret->sm);
169
170 //create a thread for the asynchronous state machine processor execution
171 ret->schedulerThread =
172 new boost::thread(boost::bind(&sc::fifo_scheduler<>::operator(), ret->scheduler1, NULL));
173 ret->signalDetectorLoop =
174 new boost::thread(boost::bind(&SignalDetector::pollingLoop, ret->signalDetector));
175
176 return ret;
177}
178
179} // namespace smacc2
SmaccFifoScheduler * scheduler_
void notifyStateExited(ISmaccState *currentState)
void initialize(ISmaccStateMachine *stateMachine)
std::vector< std::vector< ISmaccUpdatable * > > updatableStateElements_
rclcpp::Node::SharedPtr getNode()
SmaccFifoScheduler::processor_handle processorHandle_
std::atomic< int64_t > lastState_
std::vector< ISmaccUpdatable * > updatableClients_
void setProcessorHandle(SmaccFifoScheduler::processor_handle processorHandle)
rclcpp::Publisher< smacc2_msgs::msg::SmaccStatus >::SharedPtr statusPub_
void findUpdatableStateElements(ISmaccState *currentState)
ISmaccStateMachine * smaccStateMachine_
void notifyStateConfigured(ISmaccState *currentState)
std::atomic< bool > initialized_
void onSigQuit(int sig)
SmExecution * run_async()
void run(ExecutionModel executionModel=ExecutionModel::SINGLE_THREAD_SPINNER)
boost::statechart::fifo_scheduler< SmaccFifoWorker, SmaccAllocator > SmaccFifoScheduler
SmaccFifoScheduler::processor_handle sm
SmaccFifoScheduler * scheduler1