SMACC
Loading...
Searching...
No Matches
smacc_state_impl.h
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 ******************************************************************************************************************/
6
7#pragma once
8#include <smacc/smacc_state.h>
13//#include <smacc/smacc_event_generator.h>
17
18namespace smacc
19{
20 using namespace smacc::introspection;
21 //-------------------------------------------------------------------------------------------------------
22 // Delegates to ROS param access with the current NodeHandle
23 template <typename T>
24 bool ISmaccState::getParam(std::string param_name, T &param_storage)
25 {
26 return nh.getParam(param_name, param_storage);
27 }
28 //-------------------------------------------------------------------------------------------------------
29
30 // Delegates to ROS param access with the current NodeHandle
31 template <typename T>
32 void ISmaccState::setParam(std::string param_name, T param_val)
33 {
34 return nh.setParam(param_name, param_val);
35 }
36 //-------------------------------------------------------------------------------------------------------
37
38 //Delegates to ROS param access with the current NodeHandle
39 template <typename T>
40 bool ISmaccState::param(std::string param_name, T &param_val, const T &default_val) const
41 {
42 return nh.param(param_name, param_val, default_val);
43 }
44 //-------------------------------------------------------------------------------------------------------
45
46#define THIS_STATE_NAME ((demangleSymbol(typeid(*this).name()).c_str()))
47 template <typename TOrthogonal, typename TBehavior, typename... Args>
48 std::shared_ptr<TBehavior> ISmaccState::configure(Args &&... args)
49 {
50 std::string orthogonalkey = demangledTypeName<TOrthogonal>();
51 ROS_INFO("[%s] Configuring orthogonal: %s", THIS_STATE_NAME, orthogonalkey.c_str());
52
53 TOrthogonal *orthogonal = this->getOrthogonal<TOrthogonal>();
54 if (orthogonal != nullptr)
55 {
56 auto clientBehavior = std::shared_ptr<TBehavior>(new TBehavior(args...));
57 clientBehavior->currentState = this;
58 orthogonal->addClientBehavior(clientBehavior);
59 clientBehavior->template onOrthogonalAllocation<TOrthogonal, TBehavior>();
60 return clientBehavior;
61 }
62 else
63 {
64 ROS_ERROR("[%s] Skipping client behavior creation in orthogonal [%s]. It does not exist.", THIS_STATE_NAME, orthogonalkey.c_str());
65 return nullptr;
66 }
67 }
68 //-------------------------------------------------------------------------------------------------------
69
70 template <typename SmaccComponentType>
71 void ISmaccState::requiresComponent(SmaccComponentType *&storage)
72 {
73 this->getStateMachine().requiresComponent(storage);
74 }
75 //-------------------------------------------------------------------------------------------------------
76
77 template <typename SmaccClientType>
78 void ISmaccState::requiresClient(SmaccClientType *&storage)
79 {
80 const char *sname = (demangleSymbol(typeid(*this).name()).c_str());
81 storage = nullptr;
82 auto &orthogonals = this->getStateMachine().getOrthogonals();
83 for (auto &ortho : orthogonals)
84 {
85 ortho.second->requiresClient(storage);
86 if (storage != nullptr)
87 return;
88 }
89
90 ROS_ERROR("[%s] Client of type '%s' not found in any orthogonal of the current state machine. This may produce a segmentation fault if the returned reference is used.", sname, demangleSymbol<SmaccClientType>().c_str());
91 }
92 //-------------------------------------------------------------------------------------------------------
93
94 template <typename T>
95 bool ISmaccState::getGlobalSMData(std::string name, T &ret)
96 {
97 return this->getStateMachine().getGlobalSMData(name, ret);
98 }
99 //-------------------------------------------------------------------------------------------------------
100
101 // Store globally in this state machine. (By value parameter )
102 template <typename T>
103 void ISmaccState::setGlobalSMData(std::string name, T value)
104 {
105 this->getStateMachine().setGlobalSMData(name, value);
106 }
107 //-------------------------------------------------------------------------------------------------------
108
109 template <typename TStateReactor, typename... TEvArgs>
110 std::shared_ptr<TStateReactor> ISmaccState::createStateReactor(TEvArgs... args)
111 {
112 auto sr = std::make_shared<TStateReactor>(args...);
113 //sb->initialize(this, mock);
114 //sb->setOutputEvent(typelist<TTriggerEvent>());
115 stateReactors_.push_back(sr);
116 return sr;
117 }
118
119 template <typename TEventGenerator, typename... TEvArgs>
120 std::shared_ptr<TEventGenerator> ISmaccState::createEventGenerator(TEvArgs... args)
121 {
122 auto eg = std::make_shared<TEventGenerator>(args...);
123 eventGenerators_.push_back(eg);
124 return eg;
125 }
126
127 template <typename TEventList>
129 {
132 {
133 }
134
135 template <typename T>
137 {
138 sr_->addInputEvent<T>();
139 }
140 };
141
142 template <typename TStateReactor, typename TTriggerEvent, typename TEventList, typename... TEvArgs>
143 std::shared_ptr<TStateReactor> ISmaccState::createStateReactor(TEvArgs... args)
144 {
145 auto sr = std::make_shared<TStateReactor>(args...);
146 TEventList *mock;
147 sr->initialize(this);
148 sr->template setOutputEvent<TTriggerEvent>();
149
150 using boost::mpl::_1;
151 using wrappedList = typename boost::mpl::transform<TEventList, _1>::type;
152 AddTEventType<TEventList> op(sr.get());
153 boost::mpl::for_each<wrappedList>(op);
154
155 stateReactors_.push_back(sr);
156 return sr;
157 }
158
159
160 template <typename TOrthogonal>
162 {
163 //static_assert(boost::type_traits::is_base_of<ISmaccOrthogonal,TOrthogonal>::value);
164 return this->getStateMachine().getOrthogonal<TOrthogonal>();
165 }
166
167 template <typename TEventGenerator>
169 {
170 TEventGenerator* ret = nullptr;
171 for(auto& evg: this->eventGenerators_)
172 {
173 ret = dynamic_cast<TEventGenerator *>(evg.get());
174 if(ret!=nullptr)
175 break;
176 }
177 return ret;
178 }
179
180 template <typename TStateReactor>
182 {
183 TStateReactor* ret = nullptr;
184 for(auto& sr: this->stateReactors_)
185 {
186 ret = dynamic_cast<TStateReactor *>(sr.get());
187 if(ret!=nullptr)
188 break;
189 }
190 return ret;
191 }
192
193 // template <typename TStateReactor, typename TTriggerEvent, typename... TEvArgs>
194 // std::shared_ptr<TStateReactor> ISmaccState::createStateReactor(TEvArgs... args)
195 // {
196 // auto sb = std::make_shared<TStateReactor>(std::forward(args...));
197 // sb->initialize(this, typelist<TEvArgs...>());
198 // sb->setOutputEvent(typelist<TTriggerEvent>());
199 // stateReactors_.push_back(sb);
200
201 // return sb;
202 // }
203 //-------------------------------------------------------------------------------------------------------
204
205 template <typename EventType>
206 void ISmaccState::postEvent(const EventType &ev)
207 {
209 }
210
211 template <typename EventType>
213 {
214 getStateMachine().postEvent<EventType>();
215 }
216 //-------------------------------------------------------------------------------------------------------
217
218 template <typename TransitionType>
220 {
221 auto transitionType = TypeInfo::getTypeInfoFromType<TransitionType>();
222 this->notifyTransitionFromTransitionTypeInfo(transitionType);
223 }
224
225 //-------------------------------------------------------------------------------------------------------------------
226
227} // namespace smacc
228
229// implementation depends on state definition
const std::map< std::string, std::shared_ptr< smacc::ISmaccOrthogonal > > & getOrthogonals() const
void setGlobalSMData(std::string name, T value)
void requiresComponent(SmaccComponentType *&storage)
bool getGlobalSMData(std::string name, T &ret)
void postEvent(EventType *ev, EventLifeTime evlifetime=EventLifeTime::ABSOLUTE)
void setParam(std::string param_name, T param_val)
TEventGenerator * getEventGenerator()
void setGlobalSMData(std::string name, T value)
ros::NodeHandle nh
Definition: smacc_state.h:89
bool param(std::string param_name, T &param_val, const T &default_val) const
std::shared_ptr< TStateReactor > createStateReactor(TEvArgs... args)
TStateReactor * getStateReactor()
std::vector< std::shared_ptr< StateReactor > > stateReactors_
Definition: smacc_state.h:86
void requiresClient(SmaccClientType *&storage)
virtual ISmaccStateMachine & getStateMachine()=0
std::vector< std::shared_ptr< smacc::SmaccEventGenerator > > eventGenerators_
Definition: smacc_state.h:87
std::shared_ptr< TEventGenerator > createEventGenerator(TEvArgs... args)
bool getParam(std::string param_name, T &param_storage)
void notifyTransitionFromTransitionTypeInfo(std::shared_ptr< smacc::introspection::TypeInfo > &transitionTypeInfo)
Definition: smacc_state.cpp:11
std::shared_ptr< TBehavior > configure(Args &&... args)
bool getGlobalSMData(std::string name, T &ret)
TOrthogonal * getOrthogonal()
void requiresComponent(SmaccComponentType *&storage)
std::string demangleSymbol()
Definition: introspection.h:75
#define THIS_STATE_NAME
AddTEventType(smacc::StateReactor *sr)
smacc::StateReactor * sr_