SelectArm.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2014-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 RobotSkillTemplates::BringObjectGroup
19 * @author Mirko Waechter ( mirko dot waechter at kit dot edu )
20 * @date 2015
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
25#include "SelectArm.h"
26
27#include <cmath>
28
29#include <VirtualRobot/Grasping/Grasp.h>
30#include <VirtualRobot/Grasping/GraspSet.h>
31#include <VirtualRobot/Robot.h>
32#include <VirtualRobot/RobotNodeSet.h>
33
35
36#include <RobotAPI/interface/core/FramedPoseBase.h>
38
40
45
46using namespace armarx;
47using namespace BringObjectGroup;
48
49// DO NOT EDIT NEXT LINE
50SelectArm::SubClassRegistry SelectArm::Registry(SelectArm::GetName(), &SelectArm::CreateInstance);
51
53 XMLStateTemplate<SelectArm>(stateData), SelectArmGeneratedBase<SelectArm>(stateData)
54{
55}
56
57bool
59{
60 // use simox for collision check
61 // BringObjectGroupStatechartContext* c = getContext<BringObjectGroupStatechartContext>();
62 // c->getPathPlanner()->
63 return true;
64}
65
66int
69 const std::vector<std::string>& memoryNames,
70 const std::vector<std::string>& chains)
71{
72 int closestChainId = -1;
73 float minDistance = std::numeric_limits<float>::max();
74 ARMARX_CHECK_EXPRESSION(chains.size() == memoryNames.size());
75
76 for (size_t i = 0; i < chains.size(); i++)
77 {
78 std::string chain = chains[i];
79 auto set = c->getRobot()->getRobotNodeSet(chain);
80 auto distance =
81 (set->getTCP()->getPositionInRootFrame() - localObjectPose->toEigen().block<3, 1>(0, 3))
82 .norm();
83 ARMARX_VERBOSE_S << VAROUT(distance) << VAROUT(minDistance) << VAROUT(i);
84
85 if (distance < minDistance)
86 {
87 minDistance = distance;
88 closestChainId = i;
89 }
90 }
91
92 return closestChainId;
93}
94
95void
97{
98
99 // put your user code for the enter-point here
100 // execution time should be short (<100ms)
101 BringObjectGroupStatechartContext* c = getContext<BringObjectGroupStatechartContext>();
102
103 auto instance = in.getObjectInstanceToGraspChannel();
104 FramedPositionPtr position = instance->get<FramedPosition>("position");
105 FramedOrientationPtr orientation = instance->get<FramedOrientation>("orientation");
106 FramedPosePtr globalObjectPose = new FramedPose(
107 orientation->toEigen(), position->toEigen(), position->getFrame(), position->agent);
108
109 FramedPosePtr objectPoseRootFrame;
110
111 objectPoseRootFrame = FramedPosePtr::dynamicCast(globalObjectPose->clone());
112 objectPoseRootFrame->changeFrame(c->getRobot(), c->getRobot()->getRootNode()->getName());
113
114 // memoryx::ChannelRefBaseSequence instances = c->getObjectMemoryObserverProxy()->getObjectInstances(in.getObjectToGraspChannel());
115 if (in.isPreselectedKinematicChainSet() && in.isPreselectedMemoryHandNameSet())
116 {
117 out.setSelectedKinematicChain(in.getPreselectedKinematicChain());
118 out.setSelectedMemoryHandName(in.getPreselectedMemoryHandName());
119 }
120 else if (in.isKinematicChainsSet() && in.isMemoryHandNamesSet())
121 {
122
123
124 ARMARX_IMPORTANT << VAROUT(*objectPoseRootFrame);
125 auto chains = in.getKinematicChains();
126 auto memoryNames = in.getMemoryHandNames();
127 int closestChainId = getClosestTCP(objectPoseRootFrame, c, memoryNames, chains);
128
129 out.setSelectedKinematicChain(chains.at(closestChainId));
130 out.setSelectedMemoryHandName(memoryNames.at(closestChainId));
131 }
132 else
133 {
134 ARMARX_ERROR << "Either PreselectedKinematicChainSet and PreselectedMemoryHandNameSet or "
135 "KinematicChainsSet and MemoryHandNamesSet parameter must be set.";
136 emitFailure();
137 return;
138 }
139
140 ARMARX_IMPORTANT << "Selected Memory Name is: " << out.getSelectedMemoryHandName();
141 out.setSelectedTCP(
142 c->getRobot()->getRobotNodeSet(out.getSelectedKinematicChain())->getTCP()->getName());
143 ARMARX_IMPORTANT << "Selected TCP is: " << out.getSelectedTCP();
144 // get grasp definition
145 std::string objectName =
146 in.getObjectInstanceToGraspChannel()->getDataField("className")->getString();
147
148 memoryx::PersistentObjectClassSegmentBasePrx classesSegmentPrx =
149 c->getPriorKnowledgeProxy()->getObjectClassesSegment();
150 memoryx::CommonStorageInterfacePrx databasePrx =
151 c->getPriorKnowledgeProxy()->getCommonStorage();
152 memoryx::GridFileManagerPtr fileManager(new memoryx::GridFileManager(databasePrx));
153 memoryx::EntityBasePtr entity = classesSegmentPrx->getEntityByName(objectName);
154 memoryx::ObjectClassPtr objectClass = memoryx::ObjectClassPtr::dynamicCast(entity);
156 objectClass->addWrapper(new memoryx::EntityWrappers::SimoxObjectWrapper(fileManager));
157 VirtualRobot::ManipulationObjectPtr mo = simoxWrapper->getManipulationObject();
158
159 VirtualRobot::GraspSetPtr graspSet = mo->getGraspSet(out.getSelectedTCP());
160
161 auto findGrasp = [](VirtualRobot::GraspSetPtr graspSet,
162 const Ice::StringSeq& requiredInfixes,
163 const Ice::StringSeq& exludedInfixes)
164 {
165 if (graspSet)
166 {
167 auto grasps = graspSet->getGrasps();
168
169 for (VirtualRobot::GraspPtr grasp : grasps)
170 {
171 std::string graspName = grasp->getName();
172 bool found = true;
173 for (const auto& infix : requiredInfixes)
174 {
175 found &= Contains(graspName, infix, true);
176 }
177 for (const auto& infix : exludedInfixes)
178 {
179 found &= !Contains(graspName, infix, true);
180 }
181 if (found)
182 {
183 return graspName;
184 }
185 }
186 }
187 return std::string("");
188 };
189
190 if (graspSet)
191 {
192
193 std::string preposeName;
194 Ice::StringSeq infixes;
195 if (in.isGraspNameInfixSet())
196 {
197 infixes.push_back(in.getGraspNameInfix());
198 }
199 infixes.push_back({"pre"});
200
201 preposeName = findGrasp(graspSet, infixes, Ice::StringSeq());
202 if (!preposeName.empty())
203 {
204 out.setGraspPreposeName(preposeName);
205 }
206 else
207 {
208 infixes.clear();
209 infixes.push_back({"pre"}); // now without infix..
210 preposeName = findGrasp(graspSet, infixes, Ice::StringSeq());
211 if (!preposeName.empty())
212 {
213 out.setGraspPreposeName(preposeName);
214 }
215 }
216
217 infixes.clear();
218 if (in.isGraspNameInfixSet())
219 {
220 infixes.push_back(in.getGraspNameInfix());
221 }
222 infixes.push_back({"grasp"});
223 std::string graspName = findGrasp(graspSet, infixes, {"pre"});
224 if (!graspName.empty())
225 {
226 out.setGraspName(graspName);
227 }
228 else
229 {
230 infixes.clear();
231 infixes.push_back({"grasp"}); // now without infix..
232 graspName = findGrasp(graspSet, infixes, {"pre"});
233 if (!graspName.empty())
234 {
235 out.setGraspName(graspName);
236 }
237 }
238
239
240 auto getGraspNames = [](VirtualRobot::GraspSetPtr graspSet)
241 {
242 Ice::StringSeq graspNames;
243 for (VirtualRobot::GraspPtr& g : graspSet->getGrasps())
244 {
245 graspNames.push_back(g->getName());
246 };
247 return graspNames;
248 };
249
250 if (!out.isGraspPreposeNameSet())
251 {
252
253 ARMARX_ERROR << "could not find any matching pre pose for " << out.getSelectedTCP()
254 << " for object " << objectName
255 << " - Found Grasps are: " << getGraspNames(graspSet);
256 out.setGraspPreposeName("");
257 out.setGraspName("");
258 emitFailure();
259 return;
260 }
261
262 if (!out.isGraspNameSet())
263 {
264 ARMARX_ERROR << "could not find any matching grasp pose for " << out.getSelectedTCP()
265 << " for object " << objectName
266 << " - Found Grasps are: " << getGraspNames(graspSet);
267 out.setGraspPreposeName("");
268 out.setGraspName("");
269 emitFailure();
270 return;
271 }
272 }
273 else
274 {
275 ARMARX_ERROR << "graspSet Ptr NULL - Could not find grasp set for tcp "
276 << out.getSelectedTCP() << " for object " << objectName;
277 emitFailure();
278 return;
279 }
280
281
282 Eigen::Vector3f tcpPosition = c->getRobot()
283 ->getRobotNodeSet(out.getSelectedKinematicChain())
284 ->getTCP()
285 ->getPositionInRootFrame();
286 if (tcpPosition[0] < 0) // Left Hand
287 {
288 out.setPregraspArmConfig(in.getPregraspArmConfigLeft());
289 }
290 else
291 {
292 out.setPregraspArmConfig(in.getPregraspArmConfigRight());
293 }
294
295
296 if (in.getUsePlatform())
297 {
298
299 Eigen::Vector3f objPosRootFrame =
300 Vector3Ptr::dynamicCast(objectPoseRootFrame->position)->toEigen();
301
302 ARMARX_INFO << VAROUT(*objectPoseRootFrame);
303 Eigen::Vector3f newPlatformPos = objPosRootFrame;
304 Vector3Ptr offset;
305
306 if (tcpPosition[0] < 0) // Left Hand
307 {
308 offset = in.getPlatformToObjectOffsetLeft();
309 }
310 else
311 {
312 offset = in.getPlatformToObjectOffsetRight();
313 }
314
315 newPlatformPos[0] += offset->x;
316 newPlatformPos[1] += offset->y;
317
318 if (fabs(newPlatformPos[1]) > 500)
319 {
320 ARMARX_ERROR << "Target platform pose is too far away: " << newPlatformPos;
321 }
322
323 ARMARX_INFO << VAROUT(newPlatformPos);
324 ARMARX_INFO << "rootnode pose: " << c->getRobot()->getRootNode()->getGlobalPose();
325 Eigen::Vector3f newGlobalPlatformPos =
326 c->getRobot()->getRootNode()->toGlobalCoordinateSystemVec(newPlatformPos);
327 Eigen::Matrix3f rotMat = c->getRobot()->getRootNode()->getGlobalPose().block<3, 3>(0, 0);
328
329 ARMARX_INFO << "Root Node: " << c->getRobot()->getRootNode()->getName();
330 ARMARX_INFO << c->getRobot()->getRootNode()->getGlobalPose().block<3, 3>(0, 0);
331
332 Eigen::Vector3f x = rotMat * Eigen::Vector3f::UnitX();
333 newGlobalPlatformPos[2] = atan2(x[1], x[0]);
334 std::vector<Vector3Ptr> pose;
335
336 // If necessary, clamp the platform motion to the defined constraints
337 Eigen::Vector3f platformPos =
338 c->getRobot()->getRootNode()->getGlobalPose().block<3, 1>(0, 3);
339
340 if (in.isMaxPlatformMotionXSet() &&
341 fabs(newGlobalPlatformPos[0] - platformPos[0]) > in.getMaxPlatformMotionX())
342 {
343 newGlobalPlatformPos[0] =
344 platformPos[0] +
345 std::copysign(in.getMaxPlatformMotionX(), newGlobalPlatformPos[0] - platformPos[0]);
346 ARMARX_WARNING << "Platform motion clamped to maximum in X direction: "
347 << newGlobalPlatformPos[0];
348 }
349
350 if (in.isMaxPlatformMotionYSet() &&
351 fabs(newGlobalPlatformPos[1] - platformPos[1]) > in.getMaxPlatformMotionY())
352 {
353 newGlobalPlatformPos[1] =
354 platformPos[1] +
355 std::copysign(in.getMaxPlatformMotionY(), newGlobalPlatformPos[1] - platformPos[1]);
356 ARMARX_WARNING << "Platform motion clamped to maximum in Y direction: "
357 << newGlobalPlatformPos[1];
358 }
359
360 Vector3Ptr newPlatformVec = new Vector3(newGlobalPlatformPos);
361
362 if (!checkForCollision(newPlatformVec))
363 {
364 ARMARX_ERROR << "Collision detected";
365 emitFailure();
366 return;
367 }
368 else
369 {
370 pose.push_back(newPlatformVec);
371 ARMARX_INFO << VAROUT(*newPlatformVec);
372 out.setPlatformTargetPose(pose);
373 emitArmSelectedMovePlatform();
374 }
375 }
376 else
377 {
378 emitArmSelected();
379 }
380}
381
382void
384{
385 // put your user code for the exit point here
386 // execution time should be short (<100ms)
387}
388
389// DO NOT EDIT NEXT FUNCTION
int getClosestTCP(FramedPosePtr localObjectPose, BringObjectGroupStatechartContext *c, const std::vector< std::string > &memoryNames, const std::vector< std::string > &chains)
Definition SelectArm.cpp:67
#define VAROUT(x)
constexpr T c
custom implementation of the StatechartContext for a statechart
SelectArm(XMLStateConstructorParams stateData)
Definition SelectArm.cpp:52
static SubClassRegistry Registry
Definition SelectArm.h:44
bool checkForCollision(Vector3Ptr targetPlatformPose)
Definition SelectArm.cpp:58
static XMLStateFactoryBasePtr CreateInstance(XMLStateConstructorParams stateData)
The FramedOrientation class.
Definition FramedPose.h:216
The FramedPose class.
Definition FramedPose.h:281
The FramedPosition class.
Definition FramedPose.h:158
The Vector3 class.
Definition Pose.h:113
Class for legacy to stay compatible with old statecharts.
Definition XMLState.h:147
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_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#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_VERBOSE_S
Definition Logging.h:207
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< Vector3 > Vector3Ptr
Definition Pose.h:165
IceInternal::Handle< FramedPosition > FramedPositionPtr
Definition FramedPose.h:149
bool Contains(const ContainerType &container, const ElementType &searchElement)
Definition algorithm.h:330
IceInternal::Handle< FramedOrientation > FramedOrientationPtr
Definition FramedPose.h:207
IceInternal::Handle< XMLStateFactoryBase > XMLStateFactoryBasePtr
Definition XMLState.h:64
IceInternal::Handle< FramedPose > FramedPosePtr
Definition FramedPose.h:272
IceInternal::Handle< SimoxObjectWrapper > SimoxObjectWrapperPtr
IceInternal::Handle< ObjectClass > ObjectClassPtr
Definition ObjectClass.h:35
std::shared_ptr< GridFileManager > GridFileManagerPtr
double distance(const Point &a, const Point &b)
Definition point.hpp:95