SceneModifier.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
19 * @author
20 * @date
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
25
26#include "SceneModifier.h"
27
28#include <signal.h>
29
30#include <Eigen/Core>
31
32#include <VirtualRobot/MathTools.h>
33
39
40#include <RobotAPI/interface/components/ViewSelectionInterface.h>
41
43#include <MemoryX/interface/memorytypes/MemoryEntities.h>
47
48using namespace armarx;
49using namespace memoryx;
50
51void
53{
54 usingProxy(getProperty<std::string>("WorkingMemoryName").getValue());
55 usingProxy(getProperty<std::string>("PriorKnowledgeName").getValue());
56 usingProxy(getProperty<std::string>("SimulatorName").getValue());
57
58 if (getProperty<bool>("LocalizeObject").getValue())
59 {
60 usingProxy("ObjectMemoryObserver");
61 usingProxy("ConditionHandler");
62 }
63}
64
65void
67{
68 ARMARX_INFO << "Exiting SceneModifier";
69 // how do we terminate the session correctly?
70 //this->getArmarXManager()->shutdown();
71 //raise(SIGTERM);
72}
73
74void
76{
78 {
79 ARMARX_INFO << "Releasing obj class ";
80 memoryObserver->releaseObjectClass(classChannel1);
81 classChannel1 = NULL;
82 }
83}
84
85bool
86SceneModifier::checkForConfigs(const std::string& suffix)
87{
88 std::stringstream strStr;
89
90 strStr << "SceneModificationType";
91
92 if (!suffix.empty())
93 {
94 strStr << suffix;
95 }
96
97 ARMARX_DEBUG << "Checking for property " << strStr.str() << "...";
98
99 ///////////////// add/move/remove objects
100 std::string mode;
101
102 try
103 {
104 mode = getProperty<std::string>(strStr.str()).getValue();
105 }
106 catch (...)
107 {
108 ARMARX_DEBUG << "Failed to get property " << strStr.str() << "...";
109 return false;
110 }
111
112 if (mode.empty())
113 {
114 return false;
115 }
116
117 if (mode == "addObject")
118 {
119 addObject(suffix);
120 }
121 else if (mode == "removeObject")
122 {
123 removeObject(suffix);
124 }
125 else if (mode == "moveObject")
126 {
127 moveObject(suffix);
128 }
129 else if (mode != "none")
130 {
131 ARMARX_ERROR << "Unknown mode: " << mode << std::endl;
132 }
133
134 return true;
135}
136
137void
139{
140 ARMARX_INFO << "Starting SceneModifier";
141
143 getProperty<std::string>("WorkingMemoryName").getValue());
145 getProperty<std::string>("PriorKnowledgeName").getValue());
148
149 checkForConfigs("");
150
151 for (int i = 0; i < 10; i++)
152 {
153 std::stringstream strStr;
154 strStr << "_" << i;
155 checkForConfigs(strStr.str());
156 }
157
158
159 ////////////// start object localizer
160 if (getProperty<bool>("LocalizeObject").getValue())
161 {
162 std::string objClassName = getProperty<std::string>("ObjectClassName").getValue();
163 ARMARX_VERBOSE << "localizing object " << objClassName;
164
165 // retrieve proxies
169 int timeS = getProperty<int>("LocalizeObject_seconds").getValue();
170 localizeSingleObject(objClassName, timeS);
171 }
172
173
174 /////////////// modify robot
175 std::string attachObjectName =
176 getProperty<std::string>("AttachObjectToRobot.ObjectName").getValue();
177 std::string attachRobotName =
178 getProperty<std::string>("AttachObjectToRobot.RobotName").getValue();
179 std::string attachRobotNodeName =
180 getProperty<std::string>("AttachObjectToRobot.RobotNodeName").getValue();
181
182 if (!attachObjectName.empty() && !attachRobotName.empty() && !attachRobotNodeName.empty())
183 {
184 ARMARX_VERBOSE << "Attaching " << attachObjectName << "to robot " << attachRobotName
185 << " at robot node " << attachRobotNodeName;
186 attachObject(attachObjectName, attachRobotName, attachRobotNodeName);
187 }
188
189
190 // that's it, we can shut down
191 // todo: how to shutdown correctly?!
192 //this->terminate();
193 //raise(SIGTERM);
194}
195
196Eigen::Matrix4f
197SceneModifier::getGlobalPose(const std::string& suffix)
198{
199 std::stringstream ss1, ss2, ss3, ss4, ss5, ss6;
200 ss1 << "PositionX";
201 ss2 << "PositionY";
202 ss3 << "PositionZ";
203 ss4 << "OrientationRoll";
204 ss5 << "OrientationPitch";
205 ss6 << "OrientationYaw";
206
207 if (!suffix.empty())
208 {
209 ss1 << suffix;
210 ss2 << suffix;
211 ss3 << suffix;
212 ss4 << suffix;
213 ss5 << suffix;
214 ss6 << suffix;
215 }
216
217 float x = getProperty<float>(ss1.str()).getValue();
218 float y = getProperty<float>(ss2.str()).getValue();
219 float z = getProperty<float>(ss3.str()).getValue();
220 float ro = getProperty<float>(ss4.str()).getValue();
221 float pi = getProperty<float>(ss5.str()).getValue();
222 float ya = getProperty<float>(ss6.str()).getValue();
223
224 Eigen::Vector3f pos = {x, y, z};
225 Eigen::Matrix4f globalPose;
226 VirtualRobot::MathTools::rpy2eigen4f(ro, pi, ya, globalPose);
227 globalPose.block<3, 1>(0, 3) = pos;
228 return globalPose;
229}
230
231bool
232SceneModifier::getStatic(const std::string& suffix)
233{
234 std::stringstream ss1;
235 ss1 << "StaticObject";
236
237
238 if (!suffix.empty())
239 {
240 ss1 << suffix;
241 }
242
243 bool x = getProperty<bool>(ss1.str()).getValue();
244
245 return x;
246}
247
248void
249SceneModifier::attachObject(const std::string& objName,
250 const std::string& robotName,
251 const std::string& robotNodeName)
252{
253 if (!simulatorPrx->hasObject(objName))
254 {
255 ARMARX_ERROR << "Object " << objName << " is not present in simulator...";
256 return;
257 }
258
259 if (!simulatorPrx->hasRobot(robotName))
260 {
261 ARMARX_ERROR << "Robot " << robotName << " is not present in simulator...";
262 return;
263 }
264
265 if (!simulatorPrx->hasRobotNode(robotName, robotNodeName))
266 {
267 ARMARX_ERROR << "Robot node " << robotNodeName << " is not present in simulator...";
268 return;
269 }
270
271 simulatorPrx->objectGrasped(robotName, robotNodeName, objName);
272}
273
274void
275SceneModifier::addObject(const std::string& suffix)
276{
277 std::stringstream ss1, ss2;
278 ss1 << "ObjectClassName";
279 ss2 << "ObjectInstanceName";
280
281 if (!suffix.empty())
282 {
283 ss1 << suffix;
284 ss2 << suffix;
285 }
286
287 ARMARX_DEBUG << "checking for object class property: " << ss1.str()
288 << ", and instance name:" << ss2.str();
289
290 std::string objClassName = getProperty<std::string>(ss1.str()).getValue();
291 std::string objInstanceName = getProperty<std::string>(ss2.str()).getValue();
292 ARMARX_DEBUG << "adding object class " << objClassName << ", instance name:" << objInstanceName;
293
294
295 memoryx::PersistentObjectClassSegmentBasePrx classesSegmentPrx =
296 priorKnowledgeProxy->getObjectClassesSegment();
297
298 //memoryx::EntityIdList list = classesSegmentPrx->getAllEntityIds();
299 //for (size_t i=0;i<list.size();i++)
300 //{
301 // memoryx::EntityPtr e = memoryx::EntityPtr::dynamicCast(classesSegmentPrx->getEntityById(list.at(i)));
302 // ARMARX_IMPORTANT_S << "i:" << i << ", id:" << e->getId() << ", name:" << e->getName();
303 //}
304 memoryx::EntityBasePtr classesEntity = classesSegmentPrx->getEntityByName(objClassName);
305
306 if (!classesEntity)
307 {
308 ARMARX_ERROR << "No memory entity found with class name " << objClassName;
309 return;
310 }
311
312 memoryx::ObjectClassPtr objectClass = memoryx::ObjectClassPtr::dynamicCast(classesEntity);
313
314 if (!objectClass)
315 {
316 ARMARX_ERROR << "Could not cast entitiy to object class, name: " << objClassName;
317 return;
318 }
319
320 Eigen::Matrix4f globalPose = getGlobalPose(suffix);
321 PosePtr pose = new Pose(globalPose);
322
323 bool isStatic = getStatic(suffix);
324
325 if (simulatorPrx->hasObject(objInstanceName))
326 {
327 ARMARX_ERROR << "Object " << objInstanceName << " is already present...";
328 return;
329 }
330
331 ARMARX_IMPORTANT << "Adding Object " << objInstanceName << " at :\n" << pose;
332 simulatorPrx->addObject(objectClass, objInstanceName, pose, isStatic);
333}
334
335void
336SceneModifier::removeObject(const std::string& suffix)
337{
338 /*std::stringstream ss1,ss2;
339 ss1 << "ObjectClassName";
340 ss2 << "ObjectInstanceName";
341 if (!suffix.empty())
342 {
343 ss1 << _ << suffix;
344 ss2 << _ << suffix;
345 }
346 std::string objClassName = getProperty<std::string>(ss1).getValue();
347 std::string objInstanceName = getProperty<std::string>(ss2).getValue();*/
348
349 ARMARX_WARNING << " NYI....";
350}
351
352void
353SceneModifier::moveObject(const std::string& suffix)
354{
355 //std::string objClassName = getProperty<std::string>("ObjectClassName").getValue();
356 std::stringstream ss1, ss2;
357 ss1 << "ObjectClassName";
358 ss2 << "ObjectInstanceName";
359
360 if (!suffix.empty())
361 {
362 ss1 << suffix;
363 ss2 << suffix;
364 }
365
366 std::string objInstanceName = getProperty<std::string>(ss2.str()).getValue();
367 ARMARX_DEBUG << "moving object instance :" << objInstanceName;
368
369 Eigen::Matrix4f globalPose = getGlobalPose(suffix);
370 PosePtr pose = new Pose(globalPose);
371
372 if (!simulatorPrx->hasObject(objInstanceName))
373 {
374 ARMARX_ERROR << "Object " << objInstanceName << " is not present in simulator...";
375 return;
376 }
377
378 ARMARX_VERBOSE << "Moving object " << objInstanceName << " to :\n" << pose;
379 simulatorPrx->setObjectPose(objInstanceName, pose);
380}
381
382void
383SceneModifier::localizeSingleObject(const std::string& objClass, int sleepS)
384{
385 /////////////////////////////////////////////////////////////////////////////////////////////////
386 // USECASE I: query a specific object and wait until localization finished
387 /////////////////////////////////////////////////////////////////////////////////////////////////
388
389 ARMARX_VERBOSE << "Initiating localization of " << objClass << " for " << sleepS << " seconds";
390
391 // 1. request the object class (corresponding to the classes in prior knowledge see PriorMemoryEditorGui)
392 classChannel1 = memoryObserver->requestObjectClassRepeated(
393 objClass, 50, armarx::DEFAULT_VIEWTARGET_PRIORITY);
394
395 if (!classChannel1)
396 {
397 ARMARX_ERROR << "Could not find class " << objClass << " in prior knowledge";
398 return;
399 }
400
401
402 // 2. install condition on the localizationFinished datafield
403 Literal objectLocalizationFinished1(
404 ChannelRefPtr::dynamicCast(classChannel1)->getDataFieldIdentifier("localizationFinished"),
405 "equals",
407 EventBasePtr e1 = new EventBase();
408 ConditionIdentifier id1 =
409 conditionHandler->installCondition(EventListenerInterfacePrx::uncheckedCast(getProxy()),
410 objectLocalizationFinished1.getImpl(),
411 e1,
412 true,
413 false,
414 {});
415
416 ARMARX_VERBOSE << "Sleeping " << sleepS << " seconds";
417 TimeUtil::MSSleep(sleepS * 1000);
418
419 // 3. fetch object instances for the requested object class
420 ChannelRefBaseSequence channelRefs = memoryObserver->getObjectInstances(classChannel1);
421 ChannelRefBaseSequence::iterator iter = channelRefs.begin();
422 ARMARX_INFO_S << "Found the following instance:";
423
424 while (iter != channelRefs.end())
425 {
426 ChannelRefPtr channelRef = ChannelRefPtr::dynamicCast(*iter);
427 ARMARX_INFO << channelRef->getDataField("instanceName");
428 iter++;
429 }
430
431 // 4. release object class (do not forget)
432 memoryObserver->releaseObjectClass(classChannel1);
433 classChannel1 = NULL;
434
435 conditionHandler->removeCondition(id1);
436}
#define pi
Property< PropertyType > getProperty(const std::string &name)
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
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
The Pose class.
Definition Pose.h:243
bool checkForConfigs(const std::string &suffix)
void onInitComponent() override
Pure virtual hook for the subclass.
void removeObject(const std::string &suffix)
armarx::ConditionHandlerInterfacePrx conditionHandler
memoryx::WorkingMemoryInterfacePrx workingMemoryProxy
void onDisconnectComponent() override
Hook for subclass.
void addObject(const std::string &suffix)
void moveObject(const std::string &suffix)
memoryx::ObjectMemoryObserverInterfacePrx memoryObserver
SimulatorInterfacePrx simulatorPrx
armarx::ChannelRefBasePtr classChannel1
Eigen::Matrix4f getGlobalPose(const std::string &suffix)
void onConnectComponent() override
Pure virtual hook for the subclass.
void localizeSingleObject(const std::string &objClass, int sleepS)
void attachObject(const std::string &objName, const std::string &robotName, const std::string &robotNodeName)
void onExitComponent() override
Hook for subclass.
bool getStatic(const std::string &suffix)
memoryx::PriorKnowledgeInterfacePrx priorKnowledgeProxy
TermImplPtr getImpl() const
Retrieve term implementation object as used in the ArmarX Framework in order to build distributed exp...
Definition Term.cpp:108
static void MSSleep(int durationMS)
lock the calling thread for a given duration (like usleep(...) but using Timeserver time)
Definition TimeUtil.cpp:100
#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_INFO_S
Definition Logging.h:202
#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
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< Pose > PosePtr
Definition Pose.h:306
IceInternal::Handle< ChannelRef > ChannelRefPtr
Definition ChannelRef.h:40
VirtualRobot headers.
IceInternal::Handle< ObjectClass > ObjectClassPtr
Definition ObjectClass.h:35