StateUtil.cpp
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5*
6* ArmarX is free software; you can redistribute it and/or modify
7* it under the terms of the GNU General Public License version 2 as
8* published by the Free Software Foundation.
9*
10* ArmarX is distributed in the hope that it will be useful, but
11* WITHOUT ANY WARRANTY; without even the implied warranty of
12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13* GNU General Public License for more details.
14*
15* You should have received a copy of the GNU General Public License
16* along with this program. If not, see <http://www.gnu.org/licenses/>.
17*
18* @package ArmarXCore::Statechart
19* @author Mirko Waechter( mirko.waechter at kit dot edu)
20* @date 2012
21* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22* GNU General Public License
23*/
24#include "StateUtil.h"
25
26#include <sstream>
27
30
31#include "StateBaseImpl.h"
32#include "StateParameter.h"
33#include "StatechartContext.h"
35#include "StatechartManager.h"
36
37namespace armarx
38{
39 void
40 StateUtility::sendEvent(const EventPtr event, StateBasePtr eventProcessor)
41 {
42 // __checkPhaseMin(eEntering, __PRETTY_FUNCTION__);
43
44 if (!eventProcessor._ptr)
45 {
46 eventProcessor = impl->__parentState;
47 }
48
49 // if sendEvent was called and this state is not active anymore, omit event
50 if ((eventProcessor.get() == impl->__parentState &&
52 (impl->__parentState && impl->__parentState->activeSubstate.get() != this))
53 {
54 ARMARX_VERBOSE << "The state " << stateName << " is not active anymore - event '"
55 << event->eventName << "' omitted" << std::endl;
56
57 if (impl->__parentState->activeSubstate)
58 {
60 << "Active state is now: "
61 << StateBasePtr::dynamicCast(impl->__parentState->activeSubstate)->stateName;
62 }
63
64 return;
65 }
66
67 // if(!checkEventIsHandled(event))
68 // {
69 // throw exceptions::local::eStatechartLogicError("The event " + event->eventName + " is not handled by the parent state. Please insert a transition for this event in the parent state of state '" + getGlobalHierarchyString() + "'");
70 // }
71 StateControllerPtr eventController =
72 StateControllerPtr::dynamicCast(eventProcessor); // cast here to make sure cast works
73
74 if (eventController._ptr)
75 {
76 if (impl->manager)
77 {
78 impl->manager->addEvent(event, eventController);
79 }
80
81 // ScopedRecursiveLock lock(__eventBufferMutex);
82 // ARMARX_VERBOSE << "NEW event inserted";
83 // __eventBuffer.push_back(pair<StateControllerPtr, EventPtr>(eventController, event));
84 }
85
86 // if(__stateMutex.try_lock()){// if locked, this function was called from onEnter()
87 // __stateMutex.unlock();
88 // if(functionPhase != eRunning)
89 // __processEvents();
90 // }
91 }
92
93 // std::string StateUtility::getScope() const
94 // {
95 // std::stringstream str;
96 // str << context->getName() << "_" << stateName << "_" << localUniqueId;
97 // return str.str();
98 // }
99
100
101 ConditionIdentifier
103 const EventPtr evt,
104 const std::string& desc)
105 {
106 __checkPhase({eEntering, eEntered}, __PRETTY_FUNCTION__);
108 if (!context)
109 {
111 }
112
113 if (!impl->__parentState)
114 {
116 }
117
118 // if (!checkEventIsHandled(evt))
119 // {
120 // throw exceptions::local::eStatechartLogicError("The event " + evt->eventName + " is not handled by the parent state. Please insert a transition for this event in the parent state of state '" + getGlobalHierarchyString() + "'");
121 // }
122
123 StateBasePtr eventProcessor = impl->__parentState;
124 ConditionHandlerInterfacePrx conditionHandlerPrx = context->conditionHandlerPrx;
125
126 std::string uniqueEventIdentifier =
127 context->eventDistributor->registerEvent(evt, eventProcessor, impl->visitCounter);
128
129 EventPtr sentEvent = new Event(*evt);
130 sentEvent->eventName = uniqueEventIdentifier;
131
132 ARMARX_DEBUG << "registered event: " << sentEvent->eventName
133 << ", EventRecv:" << sentEvent->eventReceiverName << flush;
134 installedConditions.push_back(condition.getImpl());
135 ConditionIdentifier condId = conditionHandlerPrx->installConditionWithDescription(
136 context->eventDistributor->getListener(),
137 condition.getImpl(),
138 sentEvent,
139 desc,
140 true,
141 false,
142 {});
143 __installedConditionIdentifiers.push_back(condId);
144 return condId;
145 }
146
147 void
148 StateUtility::removeCondition(ConditionIdentifier conditionId)
149 {
150 auto context = getContext<StatechartContext>();
151 if (!context)
152 {
154 }
155
156 // remove from eventmap?
157 ARMARX_DEBUG << "removing condition with Id: " << conditionId.uniqueId << flush;
158 context->conditionHandlerPrx->begin_removeCondition(conditionId);
159 }
160
162 StateUtility::setTimeoutEvent(int timeoutDurationMs, const EventPtr& evt)
163 {
164 __checkPhase(eEntering, __PRETTY_FUNCTION__);
165
167 ARMARX_INFO << "Installing Timeout Event (Timeout: " << timeoutDurationMs << "ms)" << flush;
168
169 if (!context)
170 {
171 throw exceptions::local::eNullPointerException("context pointer is NULL");
172 }
173
174 if (!context->eventDistributor->getProxy())
175 {
176 throw exceptions::local::eNullPointerException("eventWrapper->myproxy was not set");
177 }
178
179 if (!impl->__parentState)
180 {
181 throw exceptions::local::eNullPointerException("parent pointer is NULL");
182 }
183
184
185 std::stringstream timerName;
186 timerName << "Timer_" << context->getName() << "_" << stateName << "_"
187 << impl->localUniqueId << "_" << evt->eventName << "_" << timeoutDurationMs
188 << "ms";
189
191 result.actionId =
192 ChannelRefPtr::dynamicCast(context->systemObserverPrx->startTimer(timerName.str()));
193 __installedTimerChannelRefs.push_back(result.actionId);
194 Literal expression(
195 ChannelRefPtr::dynamicCast(result.actionId)->getDataFieldIdentifier("elapsedMs"),
196 "larger",
197 Literal::createParameterList(timeoutDurationMs));
198 result.conditionId = installCondition(expression, evt, "Timeout condition");
199 return result;
200 }
201
202 void
204 {
206 if (!context)
207 {
209 }
210
211 context->systemObserverPrx->begin_removeTimer(id.actionId);
212 removeCondition(id.conditionId);
213 }
214
216 StateUtility::setCounterEvent(int counterThreshold, const EventPtr& evt, int initialValue)
217 {
218 __checkPhaseMin(eEntering, __PRETTY_FUNCTION__);
220 ARMARX_INFO << "Installing Counter Event (Counter Threshold: " << counterThreshold
221 << ", InitialValue: " << initialValue << ")" << flush;
222
223 if (!context)
224 {
225 throw exceptions::local::eNullPointerException("context pointer is NULL");
226 }
227
228 if (!context->eventDistributor->getListener())
229 {
230 throw exceptions::local::eNullPointerException("eventWrapper->myproxy was not set");
231 }
232
233 if (!impl->__parentState)
234 {
235 throw exceptions::local::eNullPointerException("parentState pointer is NULL");
236 }
237
238
239 std::stringstream counterName;
240 counterName << "Counter_" << stateName << "_" << impl->localUniqueId << "_"
241 << evt->eventName;
242
244
245 result.actionId = ChannelRefPtr::dynamicCast(
246 context->systemObserverPrx->startCounter(initialValue, counterName.str()));
247 __installedCounterChannelRefs.push_back(result.actionId);
248 Literal expression(
249 ChannelRefPtr::dynamicCast(result.actionId)->getDataFieldIdentifier("value"),
250 "equals",
251 Literal::createParameterList(counterThreshold));
252 result.conditionId = installCondition(expression, evt, "Counter condition");
253 return result;
254 }
255
256 void
258 {
260 if (!context)
261 {
263 }
264
265 context->systemObserverPrx->begin_removeCounter(id.actionId);
266 removeCondition(id.conditionId);
267 }
268
269 bool
270 StateUtility::checkEventIsHandled(const EventPtr& event) const
271 {
272 __checkPhaseMin(eDefined, __PRETTY_FUNCTION__);
273
274 if (!impl->__parentState)
275 {
276 throw exceptions::local::eNullPointerException("parentState pointer is NULL");
277 }
278
279 for (unsigned int i = 0; i < impl->__parentState->transitions.size(); ++i)
280 {
281 TransitionIceBase& t = impl->__parentState->transitions.at(i);
282
283 if (t.evt->eventName == event->eventName)
284 {
285 return true;
286 }
287 }
288
289 return false;
290 }
291
293 StateUtility::createEvent(const std::string& eventName,
294 const StringVariantContainerBaseMap& properties)
295 {
296 EventPtr evt = new Event(this->stateName, eventName);
297 evt->properties = properties;
298 return evt;
299 }
300
301 void
302 StateUtility::_removeInstalledConditions()
303 {
304 StatechartContext* context = dynamic_cast<StatechartContext*>(getContext(false));
305 if (!context)
306 {
307 ARMARX_INFO << "Statechart Context is NULL - cannot clear installed conditions";
308 return;
309 }
310 for (auto c : __installedConditionIdentifiers)
311 {
313 }
314
315 __installedConditionIdentifiers.clear();
316
317 for (auto c : __installedTimerChannelRefs)
318 {
319 context->systemObserverPrx->removeTimer(c);
320 }
321
322 __installedTimerChannelRefs.clear();
323
324 for (auto c : __installedCounterChannelRefs)
325 {
326 context->systemObserverPrx->begin_removeCounter(c);
327 }
328
329 __installedCounterChannelRefs.clear();
330 }
331
332
333} // namespace armarx
constexpr T c
An Event is used to communicate between e.g.
Definition Event.h:51
Literals are part of the user front end of the ArmarX condition mechanism.
Definition Term.h:209
static VarList createParameterList()
Static helper method to create an empty parameterlist.
Definition Term.cpp:142
std::string getName() const
Retrieve name of object.
void __checkPhase(StatePhase allowedType, const char *functionName) const
Helper function for checking if a function was called in valid position of the statechart.
void __checkPhaseMin(StatePhase allowedType, const char *functionName) const
std::unique_ptr< Impl > impl
Definition StateBase.h:289
StatePhase getStatePhase() const
ContextType * getContext() const
Definition StateBase.h:71
void removeCondition(ConditionIdentifier conditionId)
Utility function to remove an installed condition on the distributed conditionhandler.
void removeCounterEvent(const ActionEventIdentifier &id)
void removeTimeoutEvent(const ActionEventIdentifier &id)
ActionEventIdentifier setTimeoutEvent(int timeoutDurationMs, const EventPtr &evt)
Utility function to start a timer on the systemObserver and register an event on the conditionHandler...
EventPtr createEvent()
Utility function to create a new Event.
Definition StateUtil.h:63
ActionEventIdentifier setCounterEvent(int counterThreshold, const EventPtr &evt, int initialValue=0)
ConditionIdentifier installCondition(const Term &condition, const EventPtr evt, const std::string &desc="")
Utility function to install a condition on the distributed conditionhandler.
void sendEvent(const EventPtr event, StateBasePtr eventProcessor=nullptr)
Function to send an event to a specific state from an onEnter()-function. Must not be called anywhere...
Definition StateUtil.cpp:40
This class contains a statechart and provides the interfaces to distributed components.
StatechartEventDistributorPtr eventDistributor
The EventListenerInterface instance, that receives events from observers and redirects them to the co...
SystemObserverInterfacePrx systemObserverPrx
Terms are part of the user front end of the ArmarX condition mechanism.
Definition Term.h:112
TermImplPtr getImpl() const
Retrieve term implementation object as used in the ArmarX Framework in order to build distributed exp...
Definition Term.cpp:108
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
This file offers overloads of toIce() and fromIce() functions for STL container types.
const LogSender::manipulator flush
Definition LogSender.h:251
IceInternal::Handle< Event > EventPtr
Typedef of EventPtr as IceInternal::Handle<Event> for convenience.
Definition Event.h:40
IceInternal::Handle< StateBase > StateBasePtr
Definition StateBase.h:49
IceInternal::Handle< StateController > StateControllerPtr
Struct for the return value of setCounter/TimerEvent.
Definition StateUtil.h:55