HandUnitDynamicSimulation.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2013-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::units
19 * @author Nikolaus Vahrenkamp (vahrenkamp 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
27
28#include <cmath>
29
30#include <Eigen/Geometry>
31
32#include <VirtualRobot/EndEffector/EndEffector.h>
33#include <VirtualRobot/RobotConfig.h>
34
36
37#include <RobotAPI/interface/objectpose/ObjectPoseStorageInterface.h>
42
47
48
49using namespace armarx;
50
51void
53{
54 ARMARX_INFO << "Init hand unit" << flush;
55 simulatorPrxName = getProperty<std::string>("SimulatorProxyName").getValue();
57
58 kinematicUnitName = getProperty<std::string>("KinematicUnitName").getValue();
60
61 robotStateComponentName = getProperty<std::string>("RobotStateComponentName").getValue();
63
64 if (getProperty<bool>("UseLegacyWorkingMemory").getValue())
65 {
66 usingProxy("WorkingMemory");
67 }
68}
69
70void
83
84void
88
89/*
90void HandUnitDynamicSimulation::open(const Ice::Current &c)
91{
92 ARMARX_INFO << "Open Hand: setting all hand joint value targets to zero" << flush;
93 NameValueMap targetJointAngles;
94
95 // set all joints to zero
96
97 std::map<std::string, float>::iterator it = handJoints.begin();
98 while (it != handJoints.end())
99 {
100 targetJointAngles[it->first] = 0.0f;
101 it++;
102 }
103 ARMARX_DEBUG << "targetJointAngles:" << targetJointAngles << flush;
104 simulatorPrx->begin_actuateRobotJointsPos(robotName,targetJointAngles);
105}*/
106
107
110{
111 auto defs = PropertyDefinitionsPtr(
113
114 defs->optional(objectPoseStorageName,
115 "cmp.ObjectPoseStorageName",
116 "Name of the object pose storage (only used if necessary).");
117
118 return defs;
119}
120
121void
122HandUnitDynamicSimulation::setObjectGrasped(const std::string& objectName, const Ice::Current&)
123{
124 ARMARX_INFO << "Object grasped " << objectName << flush;
125 graspedObject = objectName;
126
127 // inform simulator
128 if (simulatorPrx)
129 {
130 ARMARX_INFO << "Simulator call objectGrasped: " << robotName << "," << tcpName << ","
131 << objectName << flush;
132 simulatorPrx->objectGrasped(robotName, tcpName, objectName);
133 }
134 else
135 {
136 ARMARX_WARNING << "No Simulator..." << flush;
137 }
138}
139
140void
141HandUnitDynamicSimulation::setObjectReleased(const std::string& objectName, const Ice::Current&)
142{
143 ARMARX_INFO << "Object released " << objectName << flush;
144 graspedObject = "";
145
146 // inform simulator
147 if (simulatorPrx)
148 {
149 simulatorPrx->objectReleased(robotName, tcpName, objectName);
150 }
151 else
152 {
153 ARMARX_WARNING << "No Simulator..." << flush;
154 }
155}
156
157NameValueMap
159{
160 NameValueMap result;
161
162 try
163 {
164 for (const auto& j : handJoints)
165 {
166 result[j.first] = simulatorPrx->getRobotJointAngle(robotName, j.first);
167 }
168 }
169 catch (...)
170 {
171 ARMARX_WARNING << "Could not get joint angles fvrom simulator...";
172 }
173
174 return result;
175}
176
177void
178armarx::HandUnitDynamicSimulation::setShape(const std::string& shapeName, const Ice::Current&)
179{
180 std::string myShapeName = shapeName;
181 ARMARX_INFO << "Setting shape " << myShapeName;
182
183 if (!eef)
184 {
185 ARMARX_WARNING << "No EEF";
186 return;
187 }
188
189
190 if (!eef->hasPreshape(myShapeName))
191 {
192 ARMARX_INFO << "Shape with name " << myShapeName << " not known in eef " << eef->getName()
193 << ". Looking for partial match";
194
195 bool foundMatch = false;
196
197 for (const std::string& name : eef->getPreshapes())
198 {
199 if (name.find(myShapeName) != std::string::npos)
200 {
201 foundMatch = true;
202 myShapeName = name;
203 ARMARX_INFO << "Using matching shape: " << name;
204 break;
205 }
206 }
207
208 if (!foundMatch)
209 {
210 ARMARX_WARNING << "No match found for " << myShapeName << " in eef " << eef->getName()
211 << " available shapes: " << eef->getPreshapes();
212 return;
213 }
214 }
215
216 VirtualRobot::RobotConfigPtr config = eef->getPreshape(myShapeName);
217 std::map<std::string, float> jointAngles = config->getRobotNodeJointValueMap();
218
219 NameControlModeMap controlModes;
220
221 for (std::pair<std::string, float> pair : jointAngles)
222 {
223 controlModes.insert(std::make_pair(pair.first, ePositionControl));
224 }
225
226 kinematicUnitPrx->switchControlMode(controlModes);
227 kinematicUnitPrx->setJointAngles(jointAngles);
228}
229
230void
232 const std::string& objectInstanceName,
233 const Ice::Current& c)
234{
235 std::string myShapeName = shapeName;
236 ARMARX_INFO << "Setting shape " << myShapeName << " while checking for collision with "
237 << objectInstanceName;
238
239 if (!eef)
240 {
241 ARMARX_WARNING << "No EEF";
242 return;
243 }
244
245 if (!eef->hasPreshape(myShapeName))
246 {
247 ARMARX_INFO << "Shape with name " << myShapeName << " not known in eef " << eef->getName()
248 << ". Looking for partial match";
249
250 bool foundMatch = false;
251 for (const std::string& name : eef->getPreshapes())
252 {
253 if (name.find(myShapeName) != std::string::npos)
254 {
255 foundMatch = true;
256 myShapeName = name;
257 ARMARX_INFO << "Using matching shape: " << name;
258 break;
259 }
260 }
261
262 if (!foundMatch)
263 {
264 ARMARX_WARNING << "No match found for " << myShapeName << " in eef " << eef->getName()
265 << " available shapes: " << eef->getPreshapes();
266 return;
267 }
268 }
269
270 VirtualRobot::EndEffectorPtr endeffector = robot->getEndEffector(eef->getName());
271 ARMARX_CHECK_EQUAL(endeffector.get(), eef.get()); // Is this really always the same??
272
273 auto loadFromObjectPoseStorage = [this,
274 &objectInstanceName]() -> VirtualRobot::ManipulationObjectPtr
275 {
276 const armarx::ObjectID objectID(objectInstanceName);
277
279 auto fetchObjectPose = [this, &objectID, &client]() -> std::optional<Eigen::Matrix4f>
280 {
281 getProxy(client.objectPoseStorage, objectPoseStorageName, false, "", false);
282 if (client.objectPoseStorage)
283 {
284 const objpose::ObjectPoseMap objectPoses = client.fetchObjectPosesAsMap();
285 if (auto it = objectPoses.find(objectID); it != objectPoses.end())
286 {
287 return it->second.objectPoseGlobal;
288 }
289 }
290 return std::nullopt;
291 };
292 if (auto objectPose = fetchObjectPose())
293 {
294 if (std::optional<armarx::ObjectInfo> info =
295 client.getObjectFinder().findObject(objectID))
296 {
297 VirtualRobot::ManipulationObjectPtr object =
299 object->setGlobalPose(objectPose.value());
300 return object;
301 }
302 }
303 return nullptr;
304 };
305
306 auto loadFromWorkingMemory = [this,
307 &objectInstanceName]() -> VirtualRobot::ManipulationObjectPtr
308 {
309 memoryx::ObjectInstancePtr objInstance = memoryx::ObjectInstancePtr::dynamicCast(
310 workingMemoryPrx->getObjectInstancesSegment()->getObjectInstanceByName(
311 objectInstanceName));
312
314 robotStateComponentPrx, VirtualRobot::RobotIO::eCollisionModel);
316
317 const std::string objectClassName = objInstance->getMostProbableClass();
318 // Assure complete ontology tree is in object classes segment
319 auto classes = workingMemoryPrx->getObjectClassesSegment()->addPriorClassWithSubclasses(
320 objectClassName);
321 if (classes.empty())
322 {
323 ARMARX_WARNING << "Class '" << objectClassName << "' not found ";
324 return nullptr;
325 }
326
327 memoryx::ObjectClassPtr objclass =
328 memoryx::ObjectClassPtr::dynamicCast(workingMemoryPrx->getObjectClassesSegment()
329 ->getEntityByName(objectClassName)
330 ->ice_clone());
331 ARMARX_CHECK_NOT_NULL(objclass);
332
333 memoryx::GridFileManagerPtr fileManager(
334 new memoryx::GridFileManager(workingMemoryPrx->getCommonStorage()));
336 objclass->addWrapper(new memoryx::EntityWrappers::SimoxObjectWrapper(fileManager));
337
338 objInstance->setPose(objInstance->getPose()->toGlobal(robot));
339 simoxObject->updateFromEntity(objInstance);
340
341 return simoxObject->getManipulationObject();
342 };
343
344 VirtualRobot::ManipulationObjectPtr manipulationObject = nullptr;
345 if (not manipulationObject)
346 {
347 manipulationObject = loadFromObjectPoseStorage();
348 }
349 if (not manipulationObject and workingMemoryPrx)
350 {
351 manipulationObject = loadFromWorkingMemory();
352 }
353
354 if (manipulationObject)
355 {
356 endeffector->closeActors(manipulationObject);
357
358 const std::map<std::string, float> jointAngles =
359 endeffector->getConfiguration()->getRobotNodeJointValueMap();
360
361 NameControlModeMap controlModes;
362 for (const auto& [name, value] : jointAngles)
363 {
364 controlModes.emplace(name, ePositionControl);
365 }
366
367 kinematicUnitPrx->switchControlMode(controlModes);
368 kinematicUnitPrx->setJointAngles(jointAngles);
369 }
370 else
371 {
372 ARMARX_WARNING << "Could not load object '" << objectInstanceName << "'. "
373 << "Cannot set shape '" << shapeName << "' with collision check. "
374 << "Setting shape '" << shapeName << "' without collision check instead.";
375 setShape(shapeName, c);
376 return;
377 }
378}
379
380void
382 const Ice::Current&)
383{
384 NameControlModeMap controlModes;
385
386 for (std::pair<std::string, float> pair : jointAngles)
387 {
388 controlModes.insert(std::make_pair(pair.first, ePositionControl));
389 }
390
391 kinematicUnitPrx->switchControlMode(controlModes);
392 kinematicUnitPrx->setJointAngles(jointAngles);
393 simulatorPrx->actuateRobotJointsPos(getRobotNameFromHandUnitName(),
394 handUnitJointsToRobotJoints(jointAngles));
395}
396
397armarx::NameValueMap
399{
402 ARMARX_VERBOSE << joints;
403 std::map<std::string, std::vector<std::string>> conversion_dict;
404 conversion_dict["Fingers"] = {"Index", "Middle", "Ring", "Pinky"};
405 conversion_dict["Thumb"] = {"Thumb"};
406 auto robot_joints = armarx::NameValueMap();
407 std::string side = getHandSideFromHandUnitName();
408 for (const auto& joint : joints)
409 {
410 if (conversion_dict.find(joint.first) != conversion_dict.end())
411 {
412 auto correspondences = conversion_dict.at(joint.first);
413 for (const auto& correspondence : correspondences)
414 {
415 for (int i = 1; i < 4; i++)
416 {
417 std::stringstream joint_id;
418 joint_id << correspondence << " " << side << " " << i << " Joint";
419 robot_joints[joint_id.str()] = joint.second * M_PI_2;
420 }
421 }
422 }
423 else
424 {
425 ARMARX_WARNING << "No corresponding finger joint found for " << joint.first;
426 }
427 }
428 return robot_joints;
429}
430
431std::string
436
437std::string
439{
440 auto side = armarx::split(robotName, " ").back();
441 std::stringstream stream;
442 stream << side.front();
443 return stream.str();
444}
constexpr T c
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
Property< PropertyType > getProperty(const std::string &name)
armarx::NameValueMap handUnitJointsToRobotJoints(const armarx::NameValueMap &joints)
memoryx::WorkingMemoryInterfacePrx workingMemoryPrx
void setObjectReleased(const std::string &objectName, const Ice::Current &) override
void setShape(const std::string &shapeName, const Ice::Current &) override
void setObjectGrasped(const std::string &objectName, const Ice::Current &) override
NameValueMap getCurrentJointValues(const Ice::Current &c=Ice::emptyCurrent) override
PropertyDefinitionsPtr createPropertyDefinitions() override
Send command to the hand to open all fingers.
RobotStateComponentInterfacePrx robotStateComponentPrx
void setJointAngles(const NameValueMap &jointAngles, const Ice::Current &) override
void setShapeWithObjectInstance(const std::string &shapeName, const std::string &objectInstanceName, const Ice::Current &c=Ice::emptyCurrent) override
VirtualRobot::RobotPtr robot
Definition HandUnit.h:173
VirtualRobot::EndEffectorPtr eef
Definition HandUnit.h:174
std::string kinematicUnitName
Definition HandUnit.h:171
std::map< std::string, float > handJoints
Definition HandUnit.h:179
std::string graspedObject
Definition HandUnit.h:181
std::string tcpName
Definition HandUnit.h:177
std::string robotName
Definition HandUnit.h:176
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)
static VirtualRobot::ManipulationObjectPtr loadManipulationObject(const std::optional< ObjectInfo > &ts, VirtualRobot::ObjectIO::ObjectDescription loadMode=VirtualRobot::ObjectIO::ObjectDescription::eFull)
std::optional< ObjectInfo > findObject(const std::string &dataset, const std::string &name) const
A known object ID of the form "Dataset/ClassName" or "Dataset/ClassName/InstanceName".
Definition ObjectID.h:11
static VirtualRobot::RobotPtr createLocalCloneFromFile(RobotStateComponentInterfacePrx robotStatePrx, VirtualRobot::RobotIO::RobotDescription loadMode=VirtualRobot::RobotIO::eFull)
This is a convenience function for createLocalClone, which automatically gets the filename from the R...
static bool synchronizeLocalClone(VirtualRobot::RobotPtr robot, RobotStateComponentInterfacePrx robotStatePrx)
Provides access to the armarx::objpose::ObjectPoseStorageInterface (aka the object memory).
const ObjectFinder & getObjectFinder() const
Get the internal object finder.
ObjectPoseMap fetchObjectPosesAsMap() const
Fetch all known object poses.
ObjectPoseStorageInterfacePrx objectPoseStorage
SimoxObjectWrapper offers a simplified access to the Simox ManipulationObject (i.e visualization,...
GridFileManager provides utility functions for working with files in Mongo GridFS and links to them s...
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#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
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
std::map< ObjectID, ObjectPose > ObjectPoseMap
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::vector< std::string > split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
const LogSender::manipulator flush
Definition LogSender.h:251
IceInternal::Handle< SimoxObjectWrapper > SimoxObjectWrapperPtr
IceInternal::Handle< ObjectInstance > ObjectInstancePtr
IceInternal::Handle< ObjectClass > ObjectClassPtr
Definition ObjectClass.h:35
std::shared_ptr< GridFileManager > GridFileManagerPtr