XMLStateComponent.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 ArmarX::
19* @author Mirko Waechter ( mirko.waechter at kit dot edu)
20* @date 2014
21* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22* GNU General Public License
23*/
24
25#include "XMLStateComponent.h"
26
27#include <random>
28
29#include <Ice/Properties.h>
30#include <IceUtil/UUID.h>
31
32#include <SimoxUtility/algorithm/string/string_tools.h>
33
39
41#include "GroupXmlReader.h"
43
44namespace armarx
45{
46
48 {
49 uuid = IceUtil::generateUUID();
50 }
51
52 void
54 {
55 std::string groupFilepathString =
56 PropertyUser::getProperty<std::string>("XMLStatechartGroupDefinitionFile").getValue();
57 std::string profileName =
58 PropertyUser::getProperty<std::string>("XMLStatechartProfile").getValue();
59
60 //std::string profileDefinitionFilepath = PropertyUser::getProperty<std::string>("XMLStatechartProfile").getValue();
62 Application::getInstance()->getArmarXPackageNames());
63 selectedProfile = profiles->getProfileByName(profileName);
64
65 if (!selectedProfile)
66 {
67 throw LocalException("Could not find profile '" + profileName + "'");
68 }
69
70 ARMARX_IMPORTANT << "Using profile " << selectedProfile->getFullName();
71
72
73 Ice::StringSeq includePaths;
75 packages.push_back(Application::GetProjectName());
76
77 for (const std::string& projectName : packages)
78 {
79 if (projectName.empty())
80 {
81 continue;
82 }
83
84 CMakePackageFinder project(projectName);
85 auto pathsString = project.getIncludePaths();
86 Ice::StringSeq projectIncludePaths = simox::alg::split(pathsString, ";,");
87 includePaths.insert(
88 includePaths.end(), projectIncludePaths.begin(), projectIncludePaths.end());
89 }
90
92
93 ArmarXDataPath::getAbsolutePath(groupFilepathString, groupFilepathString, includePaths);
94 reader->readXml(std::filesystem::path(groupFilepathString));
95
96 auto extraProperties = reader->getConfigurationFileContent();
97 if (!extraProperties.empty())
98 {
99 auto props = Ice::createProperties();
100 std::filesystem::path temp =
101 std::filesystem::temp_directory_path() / std::to_string(std::random_device{}());
102 temp += ".cfg";
103 std::ofstream file(temp.string().c_str());
104 file << extraProperties;
105 file.close();
106 props->load(temp.string());
107 std::filesystem::remove(temp);
108 for (auto& prop : props->getPropertiesForPrefix(""))
109 {
110 tryAddProperty(prop.first, prop.second);
111 }
112 }
113 CMakePackageFinder pack(reader->getPackageName());
114
115 if (pack.packageFound())
116 {
117 std::string libPath = "lib" + reader->getGroupName() + ".so";
118
119 std::string libPaths = pack.getLibraryPaths();
120 std::vector<std::string> libpathList = simox::alg::split(libPaths, ";");
121
122 std::string libPathNextGen =
123 "lib" + reader->getPackageName() + "_" + reader->getGroupName() + ".so";
124
125 if (ArmarXDataPath::getAbsolutePath(libPath, libPath, libpathList, false))
126 {
127 loadLib(libPath);
130 }
132 libPathNextGen, libPathNextGen, libpathList, false))
133 {
134 loadLib(libPathNextGen);
137 }
138 else
139 {
140 ARMARX_ERROR << "Could not find state user code lib file `" << libPath << "` or `"
141 << libPathNextGen << "`";
142 }
143 }
144
145 offererName = reader->getGroupName() + STATEOFFERERSUFFIX;
147 reader);
148 if (!offerer)
149 {
150 ARMARX_WARNING << "Could not find XMLRemoteStateOfferer with name " << offererName
151 << "\nAvailable classes are:\n"
153 offerer = new XMLRemoteStateOfferer<>(reader);
154 }
155
156 if (PropertyUser::getProperty<std::string>("XMLRemoteStateOffererName").isSet())
157 {
159 PropertyUser::getProperty<std::string>("XMLRemoteStateOffererName").getValue();
160 }
161 }
162
163 void
165 {
166 ComponentPtr obj = ComponentPtr::dynamicCast(offerer);
167 obj->forceComponentCreatedByComponentCreateFunc();
168 StatechartContextPtr::dynamicCast(offerer)->setReportingTopic(
169 getProperty<std::string>("StateReportingTopic").getValue());
170 obj->initializeProperties(offererName, getIceProperties(), getConfigDomain());
171 if (getProperty<bool>("EnableProfiling").getValue() &&
172 !obj->getProperty<bool>("EnableProfiling").isSet())
173 {
174 obj->enableProfiler(true);
175 }
176
177 bool usePrx = false;
178 iceObjName = selectedProfile->getStatechartGroupPrefix() + obj->getName();
179 if (getArmarXManager()->getIceManager()->isObjectReachable(iceObjName))
180 {
181 ARMARX_INFO << "Using already running proxy: " << iceObjName;
182 usePrx = true;
183 }
184 else
185 {
186 getArmarXManager()->addObject(obj, false, iceObjName);
187 }
188
189 for (auto state :
190 Split(getProperty<std::string>("StatesToEnter").getValue(), ",", true, true))
191 {
192 simox::alg::trim(state);
193 if (state == "")
194 {
195 continue;
196 }
197 createAndEnterInstance(state, usePrx);
198 }
199 }
200
201 std::string
203 {
204 return "XMLStateComponent";
205 }
206
212
213 bool
214 XMLStateComponent::loadLib(std::string libPath)
215 {
216 if (!ArmarXDataPath::getAbsolutePath(libPath, libPath))
217 {
218 ARMARX_ERROR << "Could not find state user code lib file: " << libPath;
219 return false;
220 }
221
222 if (libraries.find(libPath) != libraries.end())
223 {
224 return true;
225 }
226
227 try
228 {
230 ARMARX_VERBOSE << "Loading lib: " << libPath;
231 lib->load(libPath);
232 libraries[libPath] = lib;
233 }
235 {
236 ARMARX_ERROR << "Library loading failed: " << e.what();
237 return false;
238 }
239
240 return true;
241 }
242
243 void
244 XMLStateComponent::createAndEnterInstance(const std::string& stateClassName,
245 bool useExisitingPrx)
246 {
247 if (useExisitingPrx)
248 {
249 RemoteStateOffererInterfacePrx off =
250 getArmarXManager()->getIceManager()->getProxy<RemoteStateOffererInterfacePrx>(
251 iceObjName);
252 auto stateId =
253 off->createRemoteStateInstance(stateClassName, nullptr, "TopLevel", stateClassName);
254 off->callRemoteState(stateId, StringVariantContainerBaseMap());
255 stateIDStartedUsingExisitingPrx = stateId;
256 }
257 else
258 {
259 StatechartContextPtr context = StatechartContextPtr::dynamicCast(offerer);
260 context->getObjectScheduler()->waitForObjectState(eManagedIceObjectStarted);
261 RemoteStateOffererIceBasePtr off = RemoteStateOffererIceBasePtr::dynamicCast(offerer);
262 auto stateId =
263 off->createRemoteStateInstance(stateClassName, nullptr, "TopLevel", stateClassName);
264 off->callRemoteState(stateId, StringVariantContainerBaseMap());
265 }
266 }
267
268 void
270 {
271 if (getArmarXManager()->getIceManager()->isObjectReachable(iceObjName))
272 {
273 RemoteStateOffererInterfacePrx off =
274 getArmarXManager()->getIceManager()->getProxy<RemoteStateOffererInterfacePrx>(
275 iceObjName);
276 if (stateIDStartedUsingExisitingPrx != -1 &&
277 off->getAvailableStateInstances().count(stateIDStartedUsingExisitingPrx) != 0)
278 {
279 ARMARX_DEBUG << "Exiting state with id: " << stateIDStartedUsingExisitingPrx
280 << " which has been started using already running proxy.";
281 off->breakActiveSubstateRemotely(stateIDStartedUsingExisitingPrx, nullptr);
282 off->breakRemoteState(stateIDStartedUsingExisitingPrx, nullptr);
283 off->removeInstance(stateIDStartedUsingExisitingPrx);
284 }
285 }
286 }
287} // namespace armarx
#define STATEOFFERERSUFFIX
static SharedPointerType fromName(const std::string &name, StatechartGroupXmlReaderPtr params)
static ApplicationPtr getInstance()
Retrieve shared pointer to the application object.
static const std::string & GetProjectName()
static const Ice::StringSeq & GetProjectDependencies()
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
static void RegisterKnownObjectFactoriesWithIce(const Ice::CommunicatorPtr &ic)
Registers all object factories that are known with Ice.
The CMakePackageFinder class provides an interface to the CMake Package finder capabilities.
std::string getLibraryPaths() const
Returns the library paths seperated by semi-colons.
bool packageFound() const
Returns whether or not this package was found with cmake.
std::string getConfigDomain()
Retrieve config domain for this component as set in constructor.
Definition Component.cpp:76
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
Property< PropertyType > getProperty(const std::string &name)
The DynamicLibrary class provides a mechanism to load libraries at runtime.
IceManagerPtr getIceManager() const
Returns the IceManager.
Ice::CommunicatorPtr getCommunicator() const
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
Ice::PropertiesPtr getIceProperties() const
Returns the set of Ice properties.
bool tryAddProperty(const std::string &propertyName, const std::string &value)
Property< PropertyType > getProperty(const std::string &name)
Property creation and retrieval.
static StatechartProfilesPtr ReadProfileFiles(const std::vector< std::string > &packages)
void onInitComponent() override
Pure virtual hook for the subclass.
StatechartProfilePtr selectedProfile
void createAndEnterInstance(const std::string &stateClassName, bool useExisitingPrx=false)
void onDisconnectComponent() override
Hook for subclass.
XMLStateOffererFactoryBasePtr offerer
std::map< std::string, DynamicLibraryPtr > libraries
void onConnectComponent() override
Pure virtual hook for the subclass.
PropertyDefinitionsPtr createPropertyDefinitions() override
StatechartProfilesPtr profiles
bool loadLib(std::string libPath)
std::string getDefaultName() const override
Retrieve default name of component.
This exception is thrown if an invalid value was specified for a property.
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
Ice::PropertiesPtr createProperties()
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< StatechartContext > StatechartContextPtr
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
std::shared_ptr< StatechartGroupXmlReader > StatechartGroupXmlReaderPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
IceInternal::Handle< Component > ComponentPtr
Component smart pointer type.
Definition ArmarXFwd.h:45
std::shared_ptr< DynamicLibrary > DynamicLibraryPtr