SimpleStatechartExecutor.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @package ArmarXCore::ArmarXObjects::SimpleStatechartExecutor
17  * @author Stefan Reither ( stefan dot reither at kit dot edu )
18  * @date 2020
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
24 
30 
31 namespace armarx
32 {
33  void
35  const StateParameterMap& inputArguments,
36  const Ice::Current&)
37  {
38  for (const auto& arg : inputArguments)
39  {
40  ContainerTypePtr type = checkIfLibraryNeedsToBeLoaded(arg.second);
41  if (type)
42  {
43  ARMARX_DEBUG << "Loading lib for variant: " << type->typeId;
44  _loadedDynamicLibraries[type->typeId] =
45  variantInfo->loadLibraryOfVariant(type->typeId);
46  }
47  }
49  }
50 
51  bool
52  SimpleStatechartExecutor::startStatechart(const std::string& proxyName,
53  const std::string& stateName,
54  const StateParameterMap& inputArguments,
55  const Ice::Current&)
56  {
57  for (const auto& arg : inputArguments)
58  {
59  if (checkIfLibraryNeedsToBeLoaded(arg.second))
60  {
61  ARMARX_ERROR << "DynamicLibrary for argument '" << arg.first
62  << "' is not loaded! Statechart will not be started.";
63  return false;
64  }
65  }
66 
67  if (!_finished)
68  {
69  ARMARX_WARNING << "SimpleStatechartExecutor is not ready. Cannot start statechart";
70  return false;
71  }
72 
73  RemoteStateOffererIceBasePrx prx;
74  try
75  {
76  prx = getProxy<RemoteStateOffererIceBasePrx>(proxyName, false);
77  }
78  catch (::Ice::NotRegisteredException& e)
79  {
80  ARMARX_WARNING << "RemoteStateOfferer '" << proxyName << "' not available!";
81  return false;
82  }
83 
84  if (!prx)
85  {
86  ARMARX_WARNING << "RemoteStateOfferer '" << proxyName << "' not available!";
87  return false;
88  }
89 
90  StateBasePtr stateBasePtr = StateBasePtr::dynamicCast(prx->getStatechart(stateName));
91  if (!stateBasePtr)
92  {
93  ARMARX_WARNING << "RemoteStateOfferer '" << proxyName
94  << "' does not have an available state with name: '" << stateName
95  << "'!";
96  return false;
97  }
98 
99  _prx = RemoteStateOffererInterfacePrx::checkedCast(prx);
100  _currentStateId = _prx->createRemoteStateInstance(
101  stateName, nullptr, stateName, stateName + IceUtil::generateUUID());
102 
103  StringVariantContainerBaseMap input = StateUtilFunctions::getSetValues(inputArguments);
104  _prx->callRemoteState(_currentStateId, input);
105 
106  {
107  std::unique_lock lock(_finishedMutex);
108  _finished = false;
109  }
110  _aborted = false;
111 
112  if (_runningTask)
113  {
114  _runningTask->stop(false);
115  }
116  _runningTask = new RunningTask<SimpleStatechartExecutor>(
117  this, &SimpleStatechartExecutor::statechartTask, "StatechartManager");
118  _runningTask->start();
119  return true;
120  }
121 
122  void
124  {
125  std::unique_lock lock(_finishedMutex);
126  if (!_finished && _prx && isCurrentStateIdValid())
127  {
128  _prx->breakActiveSubstateRemotely(_currentStateId, nullptr);
129  _prx->breakRemoteState(_currentStateId, nullptr);
130  _aborted = true;
131  _finishedCondition.wait(lock);
132  }
133  else
134  {
135  _finished = true;
136  _finishedCondition.notify_all();
137  }
138  _currentStateId = -1;
139  }
140 
141  bool
143  {
144  return _finished;
145  }
146 
147  StatechartExecutionResult
149  {
150  std::unique_lock lock(_finishedMutex);
151 
152  while (!_finished)
153  {
154  _finishedCondition.wait(lock);
155  usleep(1000);
156  }
157  return _lastResult;
158  }
159 
160  StringVariantContainerBaseMap
162  {
163  std::unique_lock lock(_finishedMutex);
164  if (_finished)
165  {
166  return StateUtilFunctions::getSetValues(_lastOutputParameters);
167  }
168  else
169  {
170  return StringVariantContainerBaseMap();
171  }
172  }
173 
176  {
177  std::unique_lock lock(_finishedMutex);
178  if (_finished)
179  {
180  return _lastOutputParameters;
181  }
182  else
183  {
184  return StateParameterMap();
185  }
186  }
187 
188  void
190  const Ice::Current&)
191  {
192  for (const auto& typeName : typeNames)
193  {
194  ARMARX_INFO << "Loading library for type '" << typeName << "'";
195  _loadedDynamicLibraries[typeName] = variantInfo->loadLibraryOfVariant(typeName);
196  }
198  }
199 
200  void
202  {
203  std::string packagesString =
204  getProperty<std::string>("PackagesForVariantLibraries").getValue();
205  _packages = armarx::Split(packagesString, ",", true, true);
206  variantInfo = VariantInfo::ReadInfoFiles(_packages, true, false);
207  }
208 
209  void
211  {
212  _finished = true;
213  }
214 
215  void
217  {
218  ARMARX_DEBUG << "Unloading dynamicLibraries";
219  for (const auto& it : _loadedDynamicLibraries)
220  {
221  DynamicLibraryPtr lib = it.second;
222  lib->unload();
223  }
224 
225  if (!_finished)
226  {
227  stopImmediatly(Ice::emptyCurrent);
228  {
229  std::unique_lock lock(_finishedMutex);
230  _finished = true;
231  _finishedCondition.notify_all();
232  }
233  _runningTask->stop();
234  }
235  }
236 
239  {
242  }
243 
244  void
245  SimpleStatechartExecutor::statechartTask()
246  {
247  while (_prx && isCurrentStateIdValid() && !_prx->isRemoteStateFinished(_currentStateId))
248  {
249  usleep(1000);
250  }
251  if (_prx)
252  {
253  _lastResult = (_aborted ? eAborted : eSuccess);
254  // TODO find better way to solve the problem of not laoded libraries for outputParameter
255  _lastOutputParameters = _prx->getStatechartInstance(_currentStateId)->outputParameters;
256  ensureVariantLibrariesAreLoaded(_lastOutputParameters, Ice::emptyCurrent);
257  _lastOutputParameters = _prx->getStatechartInstance(_currentStateId)->outputParameters;
258  }
259  std::unique_lock lock(_finishedMutex);
260  _finished = true;
261  _finishedCondition.notify_all();
262 
263  ARMARX_INFO << "statechartTask finished";
264  }
265 
266  ContainerTypePtr
267  SimpleStatechartExecutor::checkIfLibraryNeedsToBeLoaded(
268  const StateParameterIceBasePtr parameter) const
269  {
270  bool loadLib = false;
271  ContainerTypePtr containerType = parameter->value->getContainerType();
272  if (containerType->typeId == "::armarx::SingleTypeVariantListBase" ||
273  containerType->typeId == "::armarx::StringValueMapBase")
274  {
275  while (containerType->subType)
276  {
277  containerType = containerType->subType;
278  }
279  loadLib = _loadedDynamicLibraries.count(containerType->typeId) == 0;
280  }
281  else
282  {
283  SingleVariantPtr variant = SingleVariantPtr::dynamicCast(parameter->value);
284  if (variant && variant->get()->data->ice_id() == "::armarx::VariantData")
285  {
286  loadLib = _loadedDynamicLibraries.count(containerType->typeId) == 0;
287  }
288  }
289 
290  return loadLib ? containerType : ContainerTypePtr();
291  }
292 
293  bool
294  SimpleStatechartExecutor::isCurrentStateIdValid() const
295  {
296  for (const auto& it : _prx->getAvailableStateInstances())
297  {
298  if (it.first == _currentStateId)
299  {
300  return true;
301  }
302  }
303  return false;
304  }
305 } // namespace armarx
armarx::ManagedIceObject::getIceManager
IceManagerPtr getIceManager() const
Returns the IceManager.
Definition: ManagedIceObject.cpp:366
armarx::SimpleStatechartExecutor::getSetOutputParameters
StringVariantContainerBaseMap getSetOutputParameters(const Ice::Current &) override
Definition: SimpleStatechartExecutor.cpp:161
armarx::DynamicLibraryPtr
std::shared_ptr< DynamicLibrary > DynamicLibraryPtr
Definition: DynamicLibrary.h:124
ArmarXManager.h
armarx::SimpleStatechartExecutor::ensureVariantLibrariesAreLoaded
void ensureVariantLibrariesAreLoaded(const StateParameterMap &inputArguments, const Ice::Current &) override
Definition: SimpleStatechartExecutor.cpp:34
DynamicLibrary.h
armarx::SimpleStatechartExecutor::hasExecutionFinished
bool hasExecutionFinished(const Ice::Current &) override
Definition: SimpleStatechartExecutor.cpp:142
armarx::Split
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelperTemplates.h:36
armarx::SimpleStatechartExecutor::stopImmediatly
void stopImmediatly(const Ice::Current &) override
Definition: SimpleStatechartExecutor.cpp:123
StateUtilFunctions.h
armarx::SimpleStatechartExecutor::startStatechart
bool startStatechart(const std::string &proxyName, const std::string &stateName, const StateParameterMap &inputArguments, const Ice::Current &) override
Definition: SimpleStatechartExecutor.cpp:52
armarx::RunningTask
Definition: ArmarXMultipleObjectsScheduler.h:36
IceInternal::Handle< StateBase >
armarx::SingleVariantPtr
IceInternal::Handle< SingleVariant > SingleVariantPtr
Definition: VariantContainer.h:50
StringValueMap.h
armarx::SimpleStatechartExecutor::preloadLibrariesFromHumanNames
void preloadLibrariesFromHumanNames(const StringList &typeNames, const Ice::Current &) override
Definition: SimpleStatechartExecutor.cpp:189
armarx::statechartmodel::StateParameterMap
QMap< QString, StateParameterPtr > StateParameterMap
Definition: StateParameter.h:46
armarx::SimpleStatechartExecutor::waitUntilStatechartExecutionIsFinished
StatechartExecutionResult waitUntilStatechartExecutionIsFinished(const Ice::Current &) override
Definition: SimpleStatechartExecutor.cpp:148
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:184
armarx::aron::input
ReaderT::InputType & input
Definition: rw.h:12
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:196
SimpleStatechartExecutor.h
armarx::VariantInfo::ReadInfoFiles
static VariantInfoPtr ReadInfoFiles(const std::vector< std::string > &packages, bool showErrors=true, bool throwOnError=true)
Definition: VariantInfo.cpp:453
armarx::SimpleStatechartExecutor::onExitComponent
void onExitComponent() override
Hook for subclass.
Definition: SimpleStatechartExecutor.cpp:216
armarx::SimpleStatechartExecutor::getOutputParameters
StateParameterMap getOutputParameters(const Ice::Current &) override
Definition: SimpleStatechartExecutor.cpp:175
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:79
StateBase.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::SimpleStatechartExecutor::onConnectComponent
void onConnectComponent() override
Pure virtual hook for the subclass.
Definition: SimpleStatechartExecutor.cpp:210
armarx::SimpleStatechartExecutor::onInitComponent
void onInitComponent() override
Pure virtual hook for the subclass.
Definition: SimpleStatechartExecutor.cpp:201
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
armarx::SimpleStatechartExecutor::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Creates the property definition container.
Definition: SimpleStatechartExecutor.cpp:238
armarx::SimpleStatechartExecutorPropertyDefinitions
Definition: SimpleStatechartExecutor.h:41
armarx::PropertyDefinitionsPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Definition: forward_declarations.h:35
armarx::ManagedIceObject::getCommunicator
Ice::CommunicatorPtr getCommunicator() const
Definition: ManagedIceObject.cpp:451
armarx::StateUtilFunctions::getSetValues
StringVariantContainerBaseMap getSetValues(const StateParameterMap &paramMap)
Definition: StateUtilFunctions.cpp:56
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::ArmarXManager::RegisterKnownObjectFactoriesWithIce
static void RegisterKnownObjectFactoriesWithIce(const Ice::CommunicatorPtr &ic)
Registers all object factories that are known with Ice.
Definition: ArmarXManager.cpp:1287
ScenarioManager::Parser::StringList
std::vector< std::string > StringList
Definition: PackageBuilder.h:35