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 
29 
30 namespace armarx
31 {
32  void SimpleStatechartExecutor::ensureVariantLibrariesAreLoaded(const StateParameterMap& inputArguments, const Ice::Current&)
33  {
34  for (const auto& arg : inputArguments)
35  {
36  ContainerTypePtr type = checkIfLibraryNeedsToBeLoaded(arg.second);
37  if (type)
38  {
39  ARMARX_DEBUG << "Loading lib for variant: " << type->typeId;
40  _loadedDynamicLibraries[type->typeId] = variantInfo->loadLibraryOfVariant(type->typeId);
41  }
42  }
44  }
45 
46  bool SimpleStatechartExecutor::startStatechart(const std::string& proxyName, const std::string& stateName, const StateParameterMap& inputArguments, const Ice::Current&)
47  {
48  for (const auto& arg : inputArguments)
49  {
50  if (checkIfLibraryNeedsToBeLoaded(arg.second))
51  {
52  ARMARX_ERROR << "DynamicLibrary for argument '" << arg.first << "' is not loaded! Statechart will not be started.";
53  return false;
54  }
55  }
56 
57  if (!_finished)
58  {
59  ARMARX_WARNING << "SimpleStatechartExecutor is not ready. Cannot start statechart";
60  return false;
61  }
62 
63  RemoteStateOffererIceBasePrx prx;
64  try
65  {
66  prx = getProxy<RemoteStateOffererIceBasePrx>(proxyName, false);
67  }
68  catch (::Ice::NotRegisteredException& e)
69  {
70  ARMARX_WARNING << "RemoteStateOfferer '" << proxyName << "' not available!";
71  return false;
72  }
73 
74  if (!prx)
75  {
76  ARMARX_WARNING << "RemoteStateOfferer '" << proxyName << "' not available!";
77  return false;
78  }
79 
80  StateBasePtr stateBasePtr = StateBasePtr::dynamicCast(prx->getStatechart(stateName));
81  if (!stateBasePtr)
82  {
83  ARMARX_WARNING << "RemoteStateOfferer '" << proxyName << "' does not have an available state with name: '" << stateName << "'!";
84  return false;
85  }
86 
87  _prx = RemoteStateOffererInterfacePrx::checkedCast(prx);
88  _currentStateId = _prx->createRemoteStateInstance(stateName, nullptr, stateName, stateName + IceUtil::generateUUID());
89 
90  StringVariantContainerBaseMap input = StateUtilFunctions::getSetValues(inputArguments);
91  _prx->callRemoteState(_currentStateId, input);
92 
93  {
94  std::unique_lock lock(_finishedMutex);
95  _finished = false;
96  }
97  _aborted = false;
98 
99  if (_runningTask)
100  {
101  _runningTask->stop(false);
102  }
103  _runningTask = new RunningTask<SimpleStatechartExecutor>(this, &SimpleStatechartExecutor::statechartTask, "StatechartManager");
104  _runningTask->start();
105  return true;
106  }
107 
109  {
110  std::unique_lock lock(_finishedMutex);
111  if (!_finished && _prx && isCurrentStateIdValid())
112  {
113  _prx->breakActiveSubstateRemotely(_currentStateId, nullptr);
114  _prx->breakRemoteState(_currentStateId, nullptr);
115  _aborted = true;
116  _finishedCondition.wait(lock);
117  }
118  else
119  {
120  _finished = true;
121  _finishedCondition.notify_all();
122  }
123  _currentStateId = -1;
124  }
125 
127  {
128  return _finished;
129  }
130 
131  StatechartExecutionResult SimpleStatechartExecutor::waitUntilStatechartExecutionIsFinished(const Ice::Current&)
132  {
133  std::unique_lock lock(_finishedMutex);
134 
135  while (!_finished)
136  {
137  _finishedCondition.wait(lock);
138  usleep(1000);
139  }
140  return _lastResult;
141  }
142 
143  StringVariantContainerBaseMap SimpleStatechartExecutor::getSetOutputParameters(const Ice::Current&)
144  {
145  std::unique_lock lock(_finishedMutex);
146  if (_finished)
147  {
148  return StateUtilFunctions::getSetValues(_lastOutputParameters);
149  }
150  else
151  {
152  return StringVariantContainerBaseMap();
153  }
154  }
155 
157  {
158  std::unique_lock lock(_finishedMutex);
159  if (_finished)
160  {
161  return _lastOutputParameters;
162  }
163  else
164  {
165  return StateParameterMap();
166  }
167  }
168 
169  void SimpleStatechartExecutor::preloadLibrariesFromHumanNames(const StringList& typeNames, const Ice::Current&)
170  {
171  for (const auto& typeName : typeNames)
172  {
173  ARMARX_INFO << "Loading library for type '" << typeName << "'";
174  _loadedDynamicLibraries[typeName] = variantInfo->loadLibraryOfVariant(typeName);
175  }
177  }
178 
180  {
181  std::string packagesString = getProperty<std::string>("PackagesForVariantLibraries").getValue();
182  _packages = armarx::Split(packagesString, ",", true, true);
183  variantInfo = VariantInfo::ReadInfoFiles(_packages, true, false);
184  }
185 
187  {
188  _finished = true;
189  }
190 
192  {
193  ARMARX_DEBUG << "Unloading dynamicLibraries";
194  for (const auto& it : _loadedDynamicLibraries)
195  {
196  DynamicLibraryPtr lib = it.second;
197  lib->unload();
198  }
199 
200  if (!_finished)
201  {
202  stopImmediatly(Ice::emptyCurrent);
203  {
204  std::unique_lock lock(_finishedMutex);
205  _finished = true;
206  _finishedCondition.notify_all();
207  }
208  _runningTask->stop();
209  }
210  }
211 
213  {
216  }
217 
218 
219  void SimpleStatechartExecutor::statechartTask()
220  {
221  while (_prx && isCurrentStateIdValid() && !_prx->isRemoteStateFinished(_currentStateId))
222  {
223  usleep(1000);
224  }
225  if (_prx)
226  {
227  _lastResult = (_aborted ? eAborted : eSuccess);
228  // TODO find better way to solve the problem of not laoded libraries for outputParameter
229  _lastOutputParameters = _prx->getStatechartInstance(_currentStateId)->outputParameters;
230  ensureVariantLibrariesAreLoaded(_lastOutputParameters, Ice::emptyCurrent);
231  _lastOutputParameters = _prx->getStatechartInstance(_currentStateId)->outputParameters;
232  }
233  std::unique_lock lock(_finishedMutex);
234  _finished = true;
235  _finishedCondition.notify_all();
236 
237  ARMARX_INFO << "statechartTask finished";
238  }
239 
240  ContainerTypePtr SimpleStatechartExecutor::checkIfLibraryNeedsToBeLoaded(const StateParameterIceBasePtr parameter) const
241  {
242  bool loadLib = false;
243  ContainerTypePtr containerType = parameter->value->getContainerType();
244  if (containerType->typeId == "::armarx::SingleTypeVariantListBase" || containerType->typeId == "::armarx::StringValueMapBase")
245  {
246  while (containerType->subType)
247  {
248  containerType = containerType->subType;
249  }
250  loadLib = _loadedDynamicLibraries.count(containerType->typeId) == 0;
251  }
252  else
253  {
254  SingleVariantPtr variant = SingleVariantPtr::dynamicCast(parameter->value);
255  if (variant && variant->get()->data->ice_id() == "::armarx::VariantData")
256  {
257  loadLib = _loadedDynamicLibraries.count(containerType->typeId) == 0;
258  }
259  }
260 
261  return loadLib ? containerType : ContainerTypePtr();
262  }
263 
264  bool SimpleStatechartExecutor::isCurrentStateIdValid() const
265  {
266  for (const auto& it : _prx->getAvailableStateInstances())
267  {
268  if (it.first == _currentStateId)
269  {
270  return true;
271  }
272  }
273  return false;
274  }
275 }
armarx::ManagedIceObject::getIceManager
IceManagerPtr getIceManager() const
Returns the IceManager.
Definition: ManagedIceObject.cpp:353
armarx::SimpleStatechartExecutor::getSetOutputParameters
StringVariantContainerBaseMap getSetOutputParameters(const Ice::Current &) override
Definition: SimpleStatechartExecutor.cpp:143
armarx::DynamicLibraryPtr
std::shared_ptr< DynamicLibrary > DynamicLibraryPtr
Definition: DynamicLibrary.h:123
ArmarXManager.h
armarx::SimpleStatechartExecutor::ensureVariantLibrariesAreLoaded
void ensureVariantLibrariesAreLoaded(const StateParameterMap &inputArguments, const Ice::Current &) override
Definition: SimpleStatechartExecutor.cpp:32
DynamicLibrary.h
armarx::SimpleStatechartExecutor::hasExecutionFinished
bool hasExecutionFinished(const Ice::Current &) override
Definition: SimpleStatechartExecutor.cpp:126
armarx::Split
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelperTemplates.h:35
armarx::SimpleStatechartExecutor::stopImmediatly
void stopImmediatly(const Ice::Current &) override
Definition: SimpleStatechartExecutor.cpp:108
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:46
armarx::RunningTask
Definition: ArmarXMultipleObjectsScheduler.h:35
IceInternal::Handle< StateBase >
armarx::SingleVariantPtr
IceInternal::Handle< SingleVariant > SingleVariantPtr
Definition: VariantContainer.h:51
StringValueMap.h
armarx::SimpleStatechartExecutor::preloadLibrariesFromHumanNames
void preloadLibrariesFromHumanNames(const StringList &typeNames, const Ice::Current &) override
Definition: SimpleStatechartExecutor.cpp:169
armarx::statechartmodel::StateParameterMap
QMap< QString, StateParameterPtr > StateParameterMap
Definition: StateParameter.h:46
armarx::SimpleStatechartExecutor::waitUntilStatechartExecutionIsFinished
StatechartExecutionResult waitUntilStatechartExecutionIsFinished(const Ice::Current &) override
Definition: SimpleStatechartExecutor.cpp:131
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::aron::input
ReaderT::InputType & input
Definition: rw.h:19
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
SimpleStatechartExecutor.h
armarx::VariantInfo::ReadInfoFiles
static VariantInfoPtr ReadInfoFiles(const std::vector< std::string > &packages, bool showErrors=true, bool throwOnError=true)
Definition: VariantInfo.cpp:414
armarx::SimpleStatechartExecutor::onExitComponent
void onExitComponent() override
Hook for subclass.
Definition: SimpleStatechartExecutor.cpp:191
armarx::SimpleStatechartExecutor::getOutputParameters
StateParameterMap getOutputParameters(const Ice::Current &) override
Definition: SimpleStatechartExecutor.cpp:156
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:74
StateBase.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::SimpleStatechartExecutor::onConnectComponent
void onConnectComponent() override
Pure virtual hook for the subclass.
Definition: SimpleStatechartExecutor.cpp:186
armarx::SimpleStatechartExecutor::onInitComponent
void onInitComponent() override
Pure virtual hook for the subclass.
Definition: SimpleStatechartExecutor.cpp:179
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::SimpleStatechartExecutor::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Creates the property definition container.
Definition: SimpleStatechartExecutor.cpp:212
armarx::SimpleStatechartExecutorPropertyDefinitions
Definition: SimpleStatechartExecutor.h:43
armarx::PropertyDefinitionsPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Definition: forward_declarations.h:34
armarx::ManagedIceObject::getCommunicator
Ice::CommunicatorPtr getCommunicator() const
Definition: ManagedIceObject.cpp:431
armarx::StateUtilFunctions::getSetValues
StringVariantContainerBaseMap getSetValues(const StateParameterMap &paramMap)
Definition: StateUtilFunctions.cpp:54
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::ArmarXManager::RegisterKnownObjectFactoriesWithIce
static void RegisterKnownObjectFactoriesWithIce(const Ice::CommunicatorPtr &ic)
Registers all object factories that are known with Ice.
Definition: ArmarXManager.cpp:1204
ScenarioManager::Parser::StringList
std::vector< std::string > StringList
Definition: PackageBuilder.h:34