7 this->
mimicNLRelMap = parserMoveIt->getMimicNLFatherOfJointMap();
15 std::map < std::pair <std::string, std::string> ,
ActionPinchTight > mapOfPinches = checkCollisions();
17 fillNotCollidingTips(&mapOfLoosePinches, &mapOfPinches);
19 checkWhichTipsCollideWithoutBounds ( &mapOfLoosePinches ) ;
21 if (mapOfLoosePinches.size() != 0 ){
22 checkDistances (&mapOfLoosePinches) ;
26 if (mapOfPinches.size() == 0 ) {
27 std::cout <<
"[FINDACTIONS::" << __func__ <<
"]: I found no collisions between tips. Are you sure your hand"
28 <<
" has some fingertips that can collide? If yes, check your urdf/srdf, or be sure to"
29 <<
" have set the mesh or some collision geometry for the links, or"
30 <<
" set a bigger value in N_EXP_COLLISION" << std::endl;
37 for (
auto& it : mapOfPinches) {
40 std::set < std::string > keys ;
41 keys.insert (it.first.first) ;
42 keys.insert (it.first.second) ;
43 mapForWorker.insert (std::make_pair ( keys, pointer ) );
46 yamlWorker.
createYamlFile(mapForWorker,
"pinchTight", path2saveYaml);
49 if (mapOfLoosePinches.size() == 0 ) {
50 std::cout <<
"[FINDACTIONS::" << __func__ <<
"]: I found no loose pinches. This mean that some error happened or that" <<
51 " all the tips pairs collide with each other for at least one hand configuration." << std::endl;
58 for (
auto& it : mapOfLoosePinches) {
61 std::set < std::string > keys ;
62 keys.insert (it.first.first) ;
63 keys.insert (it.first.second) ;
64 mapForWorker.insert (std::make_pair ( keys, pointer ) );
67 yamlWorker.
createYamlFile(mapForWorker,
"pinchLoose", path2saveYaml);
70 return std::make_pair(mapOfPinches, mapOfLoosePinches);
74 std::string path2saveYaml) {
77 std::map <std::string, ActionTrig> trigMap;
80 case ROSEE::ActionPrimitive::Type::Trig : {
84 case ROSEE::ActionPrimitive::Type::TipFlex : {
88 case ROSEE::ActionPrimitive::Type::FingFlex : {
93 std::cout <<
"[ERROR FINDACTIONS::" << __func__ <<
"]: Passing as argument a action type which is not a type of trig. " << std::endl
94 <<
"I am returing an empty map" << std::endl;
99 if (trigMap.size() == 0 ) {
105 for (
auto & mapEl : trigMap) {
108 for (
auto joint : mapEl.second.getJointPos() ) {
109 jointsInvolvedCount.insert (std::make_pair(joint.first, 0));
110 for (
auto dof : joint.second) {
112 jointsInvolvedCount.at(joint.first) = 1;
117 mapEl.second.setJointsInvolvedCount (jointsInvolvedCount);
122 for (
auto& it : trigMap) {
125 std::set < std::string > keys ;
126 keys.insert (it.first) ;
127 mapForWorker.insert (std::make_pair ( keys, pointer ) );
131 yamlWorker.
createYamlFile(mapForWorker, trigMap.begin()->second.getName(), path2saveYaml);
139 std::map <std::string, ROSEE::ActionSingleJointMultipleTips> mapOfSingleJointMultipleTips;
142 std::cout <<
"[ERROR FINDACTIONS::" << __func__ <<
"] please pass a positive number " <<
143 " as number of fingers. You passed " << nFinger <<
" ! " << std::endl;
144 return mapOfSingleJointMultipleTips;
148 std::cout <<
"[ERROR FINDACTIONS::" << __func__ <<
"] with 1 finger, you are looking for a ActionTrig, "
149 <<
"and not a ActionSingleJointMultipleTips. Returning an empty map" << std::endl;
150 return mapOfSingleJointMultipleTips;
153 if (nFinger > parserMoveIt->getNFingers() ) {
154 std::cout <<
"[ERROR FINDACTIONS::" << __func__ <<
"] I can not find an action which moves " << nFinger <<
155 " fingers if the hand has only " << parserMoveIt->getNFingers() <<
" fingers. Returning an empty map" << std::endl;
156 return mapOfSingleJointMultipleTips;
159 std::string actionName =
"singleJointMultipleTips_" + std::to_string(nFinger);
161 for (
auto mapEl : parserMoveIt->getFingertipsOfJointMap() ) {
163 if (mapEl.second.size() != nFinger ) {
167 std::vector<double> furtherPos = parserMoveIt->getBiggerBoundFromZero(mapEl.first);
168 std::vector<double> nearerPos = parserMoveIt->getSmallerBoundFromZero(mapEl.first);
172 for (
auto it : parserMoveIt->getActiveJointModels()){
174 jpFar.insert ( std::make_pair ( it->getName(), jPos ));
178 jpFar.at ( mapEl.first ) = furtherPos;
179 jpNear.at ( mapEl.first ) = nearerPos;
181 std::vector<std::string> fingersInvolved;
182 for (
auto tip : mapEl.second){
183 fingersInvolved.push_back(parserMoveIt->getFingerOfFingertip (tip) );
188 mapOfSingleJointMultipleTips.insert (std::make_pair(mapEl.first, action));
192 if (mapOfSingleJointMultipleTips.size() == 0 ) {
193 std::cout <<
"[FINDACTIONS::" << __func__ <<
"] no singleJointMultipleTips with " << nFinger <<
" found" << std::endl;
194 return mapOfSingleJointMultipleTips;
199 for (
auto& it : mapOfSingleJointMultipleTips) {
202 std::set<std::string>
set;
203 set.insert (it.first);
204 mapForWorker.insert (std::make_pair (
set, pointer ) );
208 yamlWorker.
createYamlFile(mapForWorker, actionName, path2saveYaml);
210 return mapOfSingleJointMultipleTips;
219 std::cerr <<
"[ERROR " << __func__ <<
"] for this find pass at least 3 as number " <<
220 " of fingertips for the pinch" << std::endl;
221 return multiplePinchMap;
224 multiplePinchMap = checkCollisionsForMultiplePinch(nFinger, strict);
227 if (multiplePinchMap.size() == 0 ) {
228 return multiplePinchMap;
232 for (
auto& it : multiplePinchMap) {
235 mapForWorker.insert (std::make_pair ( it.first, pointer ) );
239 yamlWorker.
createYamlFile(mapForWorker, multiplePinchMap.begin()->second.getName(), path2saveYaml);
241 return multiplePinchMap;
270 acm.
setEntry(parserMoveIt->getRobotModel()->getLinkModelNames(),
271 parserMoveIt->getRobotModel()->getLinkModelNames(),
true);
272 acm.
setEntry(parserMoveIt->getFingertipNames(),
273 parserMoveIt->getFingertipNames(),
false);
275 robot_state::RobotState kinematic_state(parserMoveIt->getRobotModel());
279 std::stringstream logCollision;
280 collision_result.
clear();
282 setToRandomPositions(&kinematic_state);
284 planning_scene.checkSelfCollision(collision_request, collision_result, kinematic_state, acm);
289 for (
auto cont : collision_result.
contacts){
292 JointPos jointPos = getConvertedJointPos(&kinematic_state);
295 logCollision <<
"[FINDACTIONS::" << __func__ <<
"] Collision between " << cont.first.first <<
" and " <<
296 cont.first.second << std::endl;
298 for (
auto contInfo : cont.second){
299 logCollision <<
"\tWith a depth of contact: " << contInfo.depth;
307 auto fingerPair = getFingersPair(cont.first);
311 auto itFind = mapOfPinches.find ( fingerPair );
312 if ( itFind == mapOfPinches.end() ) {
314 mapOfPinches.insert ( std::make_pair (fingerPair, pinch) );
315 logCollision <<
", NEW INSERTION";
318 if (itFind->second.insertActionState( jointPos, cont.second.at(0)) ) {
319 logCollision <<
", NEW INSERTION";
322 logCollision << std::endl;
323 logCollision << jointPos;
336 robot_state::RobotState kinematic_state(parserMoveIt->getRobotModel());
340 setToRandomPositions(&kinematic_state);
343 for (
auto &mapEl : *mapOfLoosePinches) {
346 JointPos jointPosLoose = getConvertedJointPos(&kinematic_state);
348 auto tips = getFingertipsPair(mapEl.first);
352 Eigen::Affine3d tip1Trasf = kinematic_state.getGlobalLinkTransform(tips.first);
353 Eigen::Affine3d tip2Trasf = kinematic_state.getGlobalLinkTransform(tips.second);
354 double distance = (tip1Trasf.translation() - tip2Trasf.translation() ) .norm() ;
356 mapEl.second.insertActionState( jointPosLoose,
distance ) ;
357 mapEl.second.setJointsInvolvedCount ( jointsInvolvedCount );
365 robot_model::RobotModelPtr kinematic_model_noBound) {
367 for (
auto mapEl : *mapOfLoosePinches ) {
370 auto tips = getFingertipsPair(mapEl.first);
372 auto joints = parserMoveIt->getJointsOfFingertipMap().at (tips.first);
373 for ( std::string joint : joints ) {
374 auto jointModel = kinematic_model_noBound ->getJointModel(joint);
376 auto type = jointModel->getType() ;
379 auto bound = jointModel->getVariableBounds().at(0);
380 bound.max_position_ = EIGEN_PI;
381 bound.min_position_ = -EIGEN_PI;
383 jointModel->setVariableBounds ( jointModel->getVariableNames().at(0),
bound );
387 std::cout <<
"[WARNING FINDACTIONS::" << __func__ <<
"] I am doubling the bounds for your prismatic joint "
388 <<
"but I am not sure it is enough to make the tips colliding to find the loose pinches " <<
390 auto bound = jointModel->getVariableBounds().at(0);
391 bound.max_position_ *= 2;
392 bound.min_position_ *= 2;
394 jointModel->setVariableBounds ( jointModel->getVariableNames().at(0),
bound );
398 std::cout <<
"[FINDACTIONS::" << __func__ <<
"] Why are you using a type "
399 << kinematic_model_noBound ->getJointModel(joint)->getType()
400 <<
" joint? Code not ready to temporarily delete the multiple dof bounds"
401 <<
" in the job done to find the loose pinches " << std::endl << std::endl;
408 auto joints2 = parserMoveIt->getJointsOfFingertipMap().at (tips.second);
409 for (
auto joint : joints2 ) {
411 auto jointModel = kinematic_model_noBound ->getJointModel(joint);
412 auto type = jointModel->getType() ;
415 auto bound = jointModel->getVariableBounds().at(0);
416 bound.max_position_ = EIGEN_PI;
417 bound.min_position_ = -EIGEN_PI;
419 jointModel->setVariableBounds ( jointModel->getVariableNames().at(0),
bound );
423 std::cout <<
"[WARNING FINDACTIONS::" << __func__ <<
"] I am doubling the bounds for your prismatic joint "
424 <<
"but I am not sure it is enough to make the tips colliding to find the loose pinches " << std::endl;
425 auto bound = jointModel->getVariableBounds().at(0);
426 bound.max_position_ *= 2;
427 bound.min_position_ *= 2;
429 jointModel->setVariableBounds ( jointModel->getVariableNames().at(0),
bound );
433 std::cout <<
"[FINDACTIONS::" << __func__ <<
"] Why are you using a type "
434 << kinematic_model_noBound ->getJointModel(joint)->getType()
435 <<
" joint? Code not ready to temporarily delete the multiple dof bounds"
436 <<
" in the working done to find the loose pinches " << std::endl << std::endl;
448 robot_model::RobotModelPtr kinematic_model_noBound = parserMoveIt->getCopyModel();
450 removeBoundsOfNotCollidingTips (mapOfLoosePinches, kinematic_model_noBound );
453 acm.
setEntry(kinematic_model_noBound->getLinkModelNames(),
454 kinematic_model_noBound->getLinkModelNames(),
true);
456 for(
auto it : *mapOfLoosePinches) {
459 std::string tip1 = parserMoveIt->getFingertipOfFinger(it.first.first);
460 std::string tip2 = parserMoveIt->getFingertipOfFinger(it.first.second);
471 robot_state::RobotState kinematic_state(kinematic_model_noBound);
474 std::set < std::pair<std::string, std::string> > collidingFingers ;
476 collision_result.
clear();
477 setToRandomPositions(&kinematic_state);
479 planning_scene.checkSelfCollision(collision_request, collision_result, kinematic_state, acm);
481 for (
auto cont : collision_result.
contacts){
483 collidingFingers.insert ( getFingersPair (cont.first) );
488 for (
auto mapEl = mapOfLoosePinches->cbegin(); mapEl != mapOfLoosePinches->cend() ; ) {
490 if (collidingFingers.count(mapEl->first) == 0 ) {
491 mapOfLoosePinches->erase(mapEl++);
503 unsigned int nMinCollision = strict ?
516 acm.
setEntry(parserMoveIt->getRobotModel()->getLinkModelNames(),
517 parserMoveIt->getRobotModel()->getLinkModelNames(),
true);
518 acm.
setEntry(parserMoveIt->getFingertipNames(),
519 parserMoveIt->getFingertipNames(),
false);
521 robot_state::RobotState kinematic_state(parserMoveIt->getRobotModel());
525 collision_result.
clear();
526 setToRandomPositions(&kinematic_state);
528 planning_scene.checkSelfCollision(collision_request, collision_result, kinematic_state, acm);
530 if (collision_result.
contacts.size() >= nMinCollision ) {
533 std::set <std::string> tipsColliding;
534 for (
auto cont : collision_result.
contacts){
536 tipsColliding.insert(cont.first.first);
537 tipsColliding.insert(cont.first.second);
538 depthSum += std::abs(cont.second.at(0).depth);
543 if (tipsColliding.size() != nFinger) {
548 JointPos jointPos = getConvertedJointPos(&kinematic_state);
549 JointsInvolvedCount jointsInvolvedCount = setOnlyDependentJoints(tipsColliding, &jointPos);
551 auto fingerColliding = getFingersSet(tipsColliding);
555 auto itFind = mapOfMultPinches.find ( fingerColliding );
556 if ( itFind == mapOfMultPinches.end() ) {
558 mapOfMultPinches.insert ( std::make_pair (fingerColliding, pinch) );
561 if (itFind->second.insertActionState( jointPos, depthSum ) ) {
569 return mapOfMultPinches;
579 std::map <std::string, ActionTrig> trigMap;
581 for (
auto mapEl : parserMoveIt->getFingertipsOfJointMap()) {
583 if (mapEl.second.size() != 1) {
587 if ( parserMoveIt->checkIfContinuosJoint(mapEl.first) ==
true ) {
592 double trigMax = parserMoveIt->getBiggerBoundFromZero(mapEl.first).at(0) ;
594 ActionTrig action (
"trig", ActionPrimitive::Type::Trig);
595 action.
setFingerInvolved ( parserMoveIt->getFingerOfFingertip( mapEl.second.at(0)) ) ;
598 insertJointPosForTrigInMap(trigMap, action, mapEl.first, trigMax);
607 std::map <std::string, ROSEE::ActionTrig> tipFlexMap;
609 for (
auto tipName : parserMoveIt->getFingertipNames() ) {
611 if (parserMoveIt->getNExclusiveJointsOfTip ( tipName,
false ) < 2 ) {
616 std::string theInterestingJoint = parserMoveIt->getFirstActuatedParentJoint ( tipName,
false );
617 double tipFlexMax = parserMoveIt->getBiggerBoundFromZero ( theInterestingJoint ).at(0) ;
620 ActionTrig action (
"tipFlex", ActionPrimitive::Type::TipFlex);
623 if (! insertJointPosForTrigInMap(tipFlexMap, action, theInterestingJoint, tipFlexMax) ) {
627 std::cout <<
"[FATAL ERROR FINDACTIONS::" << __func__ <<
"]: Inserting in tipFlexMap a tip already present??" << std::endl
628 <<
"I am returning a not completely filled map" << std::endl;
639 std::map <std::string, ROSEE::ActionTrig> fingFlexMap;
641 for (
auto tipName : parserMoveIt->getFingertipNames() ) {
643 if (parserMoveIt->getNExclusiveJointsOfTip ( tipName,
false ) < 2 ) {
648 std::string theInterestingJoint = parserMoveIt->getFirstActuatedJointInFinger ( tipName );
649 double fingFlexMax = parserMoveIt->getBiggerBoundFromZero ( theInterestingJoint ).at(0) ;
651 ActionTrig action (
"fingFlex", ActionPrimitive::Type::FingFlex);
653 if (! insertJointPosForTrigInMap(fingFlexMap, action, theInterestingJoint, fingFlexMax) ) {
658 std::cout <<
"[FATAL ERROR FINDACTIONS::" << __func__ <<
"]: Inserting in fingFlexMap a tip already present??n" << std::endl
659 <<
"I am returning a not completely filled map" << std::endl;
671 if ( itMap == trigMap.end() ) {
675 for (
auto it : parserMoveIt->getActiveJointModels()){
677 jp.insert ( std::make_pair ( it->getName(), jPos ));
681 jp.at ( jointName ).at(0) = trigValue;
691 JointPos jp = itMap->second.getJointPos();
693 jp.at (jointName).at(0) = trigValue;
694 itMap->second.setJointPos(jp);
708 for (
auto actJ : parserMoveIt->getActiveJointModels()) {
710 const double* pos = kinematic_state->getJointPositions(actJ);
711 unsigned posSize =
sizeof(pos) /
sizeof(
double);
712 std::vector <double> vecPos(pos, pos + posSize);
713 jp.insert(std::make_pair(actJ->getName(), vecPos));
724 for (
auto fingerEl1 : parserMoveIt->getFingertipOfFingerMap() ) {
725 for (
auto fingerEl2 : parserMoveIt->getFingertipOfFingerMap() ) {
728 if (fingerEl1.first < fingerEl2.first) {
729 mapOfLoosePinches->insert (std::make_pair (std::make_pair (fingerEl1.first, fingerEl2.first),
ActionPinchLoose(fingerEl1.first, fingerEl2.first)));
731 }
else if (fingerEl1.first > fingerEl2.first) {
732 mapOfLoosePinches->insert (std::make_pair (std::make_pair (fingerEl2.first, fingerEl1.first),
ActionPinchLoose(fingerEl2.first, fingerEl1.first)));
738 for (
const auto mapEl : *mapOfPinches){
739 mapOfLoosePinches->erase(mapEl.first);
747 std::pair < std::string, std::string > tipsNames,
JointPos *jPos) {
751 for (
auto &jp : *jPos) {
753 jointsInvolvedCount.insert ( std::make_pair (jp.first, 1) );
770 std::vector < std::string> tips = parserMoveIt->getFingertipsOfJointMap().at(jp.first);
773 if (std::find (tips.begin(), tips.end(), tipsNames.first) == tips.end() &&
774 std::find (tips.begin(), tips.end(), tipsNames.second) == tips.end() ) {
777 jointsInvolvedCount.at ( jp.first ) = 0;
781 return jointsInvolvedCount;
786 std::set< std::string > tipsNames,
JointPos *jPos) {
790 for (
auto &jp : *jPos) {
792 jointsInvolvedCount.insert ( std::make_pair (jp.first, 0) );
795 std::vector < std::string> tips = parserMoveIt->getFingertipsOfJointMap().at(jp.first);
801 for (
auto fingInv : tipsNames ) {
802 if (std::find (tips.begin(), tips.end(), fingInv) != tips.end()) {
803 jointsInvolvedCount.at ( jp.first ) = 1 ;
808 if (jointsInvolvedCount.at ( jp.first ) == 0 ) {
814 return jointsInvolvedCount;
820 for (
auto joint : parserMoveIt->getPassiveJointNames()){
839 if (mimicNLRelMap.size() > 0 ) {
841 for (
auto el : mimicNLRelMap) {
851 p.DefineVar(
"x", &fatherPos);
852 p.SetExpr(el.second.second);
856 catch (mu::Parser::exception_type &e)
858 std::cout << e.GetMsg() << std::endl;
859 std::cout <<
"[FINDACTIONS " << __func__ <<
"] Parsing of non linear function for mimic joint "
860 <<
"'" << el.first <<
"'. Please be sure to put characther 'x' as (unique) variable for father position"
861 <<
"in the expression. Have you used syntax valid for muparser?. Expression found: '"
862 << el.second.second <<
"'" << std::endl;
869 std::vector<double> one_dof ;
870 one_dof.push_back(mimPos);
883 setToDefaultPositionPassiveJoints(kinematic_state);
889 std::pair <std::string, std::string> fingersPair = std::make_pair (
890 parserMoveIt->getFingerOfFingertip(tipsPair.first),
891 parserMoveIt->getFingerOfFingertip(tipsPair.second) );
894 if ( fingersPair.first.compare (fingersPair.second) > 0 ) {
895 auto temp = fingersPair.first;
896 fingersPair.first = fingersPair.second;
897 fingersPair.second = temp;
899 }
else if (fingersPair.first.compare (fingersPair.second) == 0 ) {
900 std::cout <<
"[FINDACTIONS " << __func__ <<
"] STRANGE ERROR: '" << tipsPair.first <<
901 "' and '" << tipsPair.second <<
"' are in the same finger '" << fingersPair.first <<
902 "' so this pair can't perform a pinch" << std::endl;
903 return std::pair<std::string, std::string>();
911 std::set <std::string> fingersSet;
912 for (
auto it : tipsSet) {
914 fingersSet.insert ( parserMoveIt->getFingerOfFingertip ( it ) );
918 if ( fingersSet.size() < tipsSet.size() ) {
919 std::cout <<
"[FINDACTIONS " << __func__ <<
"] STRANGE ERROR: " <<
920 "the tipsSet passed has some fingertips that belong to the same finger."
921 <<
" I will return an empty set " << std::endl;
923 return std::set <std::string>();
931 std::pair <std::string, std::string> tipsPair = std::make_pair (
932 parserMoveIt->getFingertipOfFinger(fingersPair.first),
933 parserMoveIt->getFingertipOfFinger(fingersPair.second) );
936 if ( tipsPair.first.compare (tipsPair.second) > 0 ) {
937 auto temp = tipsPair.first;
938 tipsPair.first = tipsPair.second;
939 tipsPair.second = temp;
941 }
else if (tipsPair.first.compare (tipsPair.second) == 0 ) {
942 std::cout <<
"[FINDACTIONS " << __func__ <<
"] STRANGE ERROR: '" << fingersPair.first <<
943 "' and '" << fingersPair.second <<
"' have the same fingertip '" << tipsPair.first <<
944 "' so this pair can't perform a pinch" << std::endl;
945 return std::pair<std::string, std::string>();