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
29
30#include <cmath>
31
32#include <Eigen/Geometry>
33
34#include <VirtualRobot/EndEffector/EndEffector.h>
35#include <VirtualRobot/ManipulationObject.h>
36#include <VirtualRobot/RobotConfig.h>
37
39
40#include <RobotAPI/interface/objectpose/ObjectPoseStorageInterface.h>
45
50
51
52using namespace armarx;
53
54void
56{
57 ARMARX_INFO << "Init hand unit" << flush;
58 simulatorPrxName = getProperty<std::string>("SimulatorProxyName").getValue();
60
61 kinematicUnitName = getProperty<std::string>("KinematicUnitName").getValue();
63
64 robotStateComponentName = getProperty<std::string>("RobotStateComponentName").getValue();
66
67 if (getProperty<bool>("UseLegacyWorkingMemory").getValue())
68 {
69 usingProxy("WorkingMemory");
70 }
71}
72
73void
86
87void
91
92/*
93void HandUnitDynamicSimulation::open(const Ice::Current &c)
94{
95 ARMARX_INFO << "Open Hand: setting all hand joint value targets to zero" << flush;
96 NameValueMap targetJointAngles;
97
98 // set all joints to zero
99
100 std::map<std::string, float>::iterator it = handJoints.begin();
101 while (it != handJoints.end())
102 {
103 targetJointAngles[it->first] = 0.0f;
104 it++;
105 }
106 ARMARX_DEBUG << "targetJointAngles:" << targetJointAngles << flush;
107 simulatorPrx->begin_actuateRobotJointsPos(robotName,targetJointAngles);
108}*/
109
110
113{
114 auto defs = PropertyDefinitionsPtr(
116
117 defs->optional(objectPoseStorageName,
118 "cmp.ObjectPoseStorageName",
119 "Name of the object pose storage (only used if necessary).");
120
121 return defs;
122}
123
124void
125HandUnitDynamicSimulation::setObjectGrasped(const std::string& objectName, const Ice::Current&)
126{
127 ARMARX_INFO << "Object grasped " << objectName << flush;
128 graspedObject = objectName;
129
130 // inform simulator
131 if (simulatorPrx)
132 {
133 ARMARX_INFO << "Simulator call objectGrasped: " << robotName << "," << tcpName << ","
134 << objectName << flush;
135 simulatorPrx->objectGrasped(robotName, tcpName, objectName);
136 }
137 else
138 {
139 ARMARX_WARNING << "No Simulator..." << flush;
140 }
141}
142
143void
144HandUnitDynamicSimulation::setObjectReleased(const std::string& objectName, const Ice::Current&)
145{
146 ARMARX_INFO << "Object released " << objectName << flush;
147 graspedObject = "";
148
149 // inform simulator
150 if (simulatorPrx)
151 {
152 simulatorPrx->objectReleased(robotName, tcpName, objectName);
153 }
154 else
155 {
156 ARMARX_WARNING << "No Simulator..." << flush;
157 }
158}
159
160NameValueMap
162{
163 NameValueMap result;
164
165 try
166 {
167 for (const auto& j : handJoints)
168 {
169 result[j.first] = simulatorPrx->getRobotJointAngle(robotName, j.first);
170 }
171 }
172 catch (...)
173 {
174 ARMARX_WARNING << "Could not get joint angles fvrom simulator...";
175 }
176
177 return result;
178}
179
180void
181armarx::HandUnitDynamicSimulation::setShape(const std::string& shapeName, const Ice::Current&)
182{
183 std::string myShapeName = shapeName;
184 ARMARX_INFO << "Setting shape " << myShapeName;
185
186 if (!eef)
187 {
188 ARMARX_WARNING << "No EEF";
189 return;
190 }
191
192
193 if (!eef->hasPreshape(myShapeName))
194 {
195 ARMARX_INFO << "Shape with name " << myShapeName << " not known in eef " << eef->getName()
196 << ". Looking for partial match";
197
198 bool foundMatch = false;
199
200 for (const std::string& name : eef->getPreshapes())
201 {
202 if (name.find(myShapeName) != std::string::npos)
203 {
204 foundMatch = true;
205 myShapeName = name;
206 ARMARX_INFO << "Using matching shape: " << name;
207 break;
208 }
209 }
210
211 if (!foundMatch)
212 {
213 ARMARX_WARNING << "No match found for " << myShapeName << " in eef " << eef->getName()
214 << " available shapes: " << eef->getPreshapes();
215 return;
216 }
217 }
218
219 VirtualRobot::RobotConfigPtr config = eef->getPreshape(myShapeName);
220 std::map<std::string, float> jointAngles = config->getRobotNodeJointValueMap();
221
222 NameControlModeMap controlModes;
223
224 for (std::pair<std::string, float> pair : jointAngles)
225 {
226 controlModes.insert(std::make_pair(pair.first, ePositionControl));
227 }
228
229 kinematicUnitPrx->switchControlMode(controlModes);
230 kinematicUnitPrx->setJointAngles(jointAngles);
231}
232
233void
235 const std::string& objectInstanceName,
236 const Ice::Current& c)
237{
238 std::string myShapeName = shapeName;
239 ARMARX_INFO << "Setting shape " << myShapeName << " while checking for collision with "
240 << objectInstanceName;
241
242 if (!eef)
243 {
244 ARMARX_WARNING << "No EEF";
245 return;
246 }
247
248 if (!eef->hasPreshape(myShapeName))
249 {
250 ARMARX_INFO << "Shape with name " << myShapeName << " not known in eef " << eef->getName()
251 << ". Looking for partial match";
252
253 bool foundMatch = false;
254 for (const std::string& name : eef->getPreshapes())
255 {
256 if (name.find(myShapeName) != std::string::npos)
257 {
258 foundMatch = true;
259 myShapeName = name;
260 ARMARX_INFO << "Using matching shape: " << name;
261 break;
262 }
263 }
264
265 if (!foundMatch)
266 {
267 ARMARX_WARNING << "No match found for " << myShapeName << " in eef " << eef->getName()
268 << " available shapes: " << eef->getPreshapes();
269 return;
270 }
271 }
272
273 VirtualRobot::EndEffectorPtr endeffector = robot->getEndEffector(eef->getName());
274 ARMARX_CHECK_EQUAL(endeffector.get(), eef.get()); // Is this really always the same??
275
276 auto loadFromObjectPoseStorage = [this,
277 &objectInstanceName]() -> VirtualRobot::ManipulationObjectPtr
278 {
279 const armarx::ObjectID objectID(objectInstanceName);
280
282 auto fetchObjectPose = [this, &objectID, &client]() -> std::optional<Eigen::Matrix4f>
283 {
284 getProxy(client.objectPoseStorage, objectPoseStorageName, false, "", false);
285 if (client.objectPoseStorage)
286 {
287 const objpose::ObjectPoseMap objectPoses = client.fetchObjectPosesAsMap();
288 if (auto it = objectPoses.find(objectID); it != objectPoses.end())
289 {
290 return it->second.objectPoseGlobal;
291 }
292 }
293 return std::nullopt;
294 };
295 if (auto objectPose = fetchObjectPose())
296 {
297 if (std::optional<armarx::ObjectInfo> info =
298 client.getObjectFinder().findObject(objectID))
299 {
300 VirtualRobot::ManipulationObjectPtr object =
302 object->setGlobalPose(objectPose.value());
303 return object;
304 }
305 }
306 return nullptr;
307 };
308
309 auto loadFromWorkingMemory = [this,
310 &objectInstanceName]() -> VirtualRobot::ManipulationObjectPtr
311 {
312 memoryx::ObjectInstancePtr objInstance = memoryx::ObjectInstancePtr::dynamicCast(
313 workingMemoryPrx->getObjectInstancesSegment()->getObjectInstanceByName(
314 objectInstanceName));
315
317 robotStateComponentPrx, VirtualRobot::RobotIO::eCollisionModel);
319
320 const std::string objectClassName = objInstance->getMostProbableClass();
321 // Assure complete ontology tree is in object classes segment
322 auto classes = workingMemoryPrx->getObjectClassesSegment()->addPriorClassWithSubclasses(
323 objectClassName);
324 if (classes.empty())
325 {
326 ARMARX_WARNING << "Class '" << objectClassName << "' not found ";
327 return nullptr;
328 }
329
330 memoryx::ObjectClassPtr objclass =
331 memoryx::ObjectClassPtr::dynamicCast(workingMemoryPrx->getObjectClassesSegment()
332 ->getEntityByName(objectClassName)
333 ->ice_clone());
334 ARMARX_CHECK_NOT_NULL(objclass);
335
336 memoryx::GridFileManagerPtr fileManager(
337 new memoryx::GridFileManager(workingMemoryPrx->getCommonStorage()));
339 objclass->addWrapper(new memoryx::EntityWrappers::SimoxObjectWrapper(fileManager));
340
341 objInstance->setPose(objInstance->getPose()->toGlobal(robot));
342 simoxObject->updateFromEntity(objInstance);
343
344 return simoxObject->getManipulationObject();
345 };
346
347 VirtualRobot::ManipulationObjectPtr manipulationObject = nullptr;
348 if (not manipulationObject)
349 {
350 manipulationObject = loadFromObjectPoseStorage();
351 }
352 if (not manipulationObject and workingMemoryPrx)
353 {
354 manipulationObject = loadFromWorkingMemory();
355 }
356
357 if (manipulationObject)
358 {
359 endeffector->closeActors(manipulationObject);
360
361 const std::map<std::string, float> jointAngles =
362 endeffector->getConfiguration()->getRobotNodeJointValueMap();
363
364 NameControlModeMap controlModes;
365 for (const auto& [name, value] : jointAngles)
366 {
367 controlModes.emplace(name, ePositionControl);
368 }
369
370 kinematicUnitPrx->switchControlMode(controlModes);
371 kinematicUnitPrx->setJointAngles(jointAngles);
372 }
373 else
374 {
375 ARMARX_WARNING << "Could not load object '" << objectInstanceName << "'. "
376 << "Cannot set shape '" << shapeName << "' with collision check. "
377 << "Setting shape '" << shapeName << "' without collision check instead.";
378 setShape(shapeName, c);
379 return;
380 }
381}
382
383void
385 const Ice::Current&)
386{
387 NameControlModeMap controlModes;
388
389 for (std::pair<std::string, float> pair : jointAngles)
390 {
391 controlModes.insert(std::make_pair(pair.first, ePositionControl));
392 }
393
394 kinematicUnitPrx->switchControlMode(controlModes);
395 kinematicUnitPrx->setJointAngles(jointAngles);
396 simulatorPrx->actuateRobotJointsPos(getRobotNameFromHandUnitName(),
397 handUnitJointsToRobotJoints(jointAngles));
398}
399
400armarx::NameValueMap
402{
405 ARMARX_VERBOSE << joints;
406 std::map<std::string, std::vector<std::string>> conversion_dict;
407 conversion_dict["Fingers"] = {"Index", "Middle", "Ring", "Pinky"};
408 conversion_dict["Thumb"] = {"Thumb"};
409 auto robot_joints = armarx::NameValueMap();
410 std::string side = getHandSideFromHandUnitName();
411 for (const auto& joint : joints)
412 {
413 if (conversion_dict.find(joint.first) != conversion_dict.end())
414 {
415 auto correspondences = conversion_dict.at(joint.first);
416 for (const auto& correspondence : correspondences)
417 {
418 for (int i = 1; i < 4; i++)
419 {
420 std::stringstream joint_id;
421 joint_id << correspondence << " " << side << " " << i << " Joint";
422 robot_joints[joint_id.str()] = joint.second * M_PI_2;
423 }
424 }
425 }
426 else
427 {
428 ARMARX_WARNING << "No corresponding finger joint found for " << joint.first;
429 }
430 }
431 return robot_joints;
432}
433
434std::string
439
440std::string
442{
443 auto side = armarx::split(robotName, " ").back();
444 std::stringstream stream;
445 stream << side.front();
446 return stream.str();
447}
448
449std::string
451{
452 return "HandUnitDynamicSimulation";
453}
454
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
Definition Decoupled.h:29
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)
This unit connects to the physics simulator topic (default: "Simulator") and implements a HandUnit.
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