From 71c7044ffef6a15b924825f2317bfd8d76c7b234 Mon Sep 17 00:00:00 2001 From: stevet <stevetonneau@gotmail.fr> Date: Fri, 28 Jun 2019 18:33:55 +0100 Subject: [PATCH] generate one contact --- idl/hpp/corbaserver/rbprm/rbprmbuilder.idl | 7 ++ .../sandbox/ANYmal/anymal_flatGround.py | 6 +- script/scenarios/sandbox/run.sh | 4 +- src/hpp/corbaserver/rbprm/rbprmfullbody.py | 6 +- src/hpp/corbaserver/rbprm/rbprmstate.py | 13 ++++ .../rbprm/tools/affordance_centroids.py | 67 ++++++++++++++++ src/rbprmbuilder.impl.cc | 77 +++++++++++++++++++ src/rbprmbuilder.impl.hh | 3 + 8 files changed, 175 insertions(+), 8 deletions(-) create mode 100644 src/hpp/corbaserver/rbprm/tools/affordance_centroids.py diff --git a/idl/hpp/corbaserver/rbprm/rbprmbuilder.idl b/idl/hpp/corbaserver/rbprm/rbprmbuilder.idl index 3c0dfae5..bd6ce9e9 100644 --- a/idl/hpp/corbaserver/rbprm/rbprmbuilder.idl +++ b/idl/hpp/corbaserver/rbprm/rbprmbuilder.idl @@ -255,6 +255,13 @@ module hpp floatSeqSeq getContactSamplesProjected(in string name, in floatSeq dofArray, in floatSeq direction, in unsigned short numSamples) raises (Error); + /// Given a contact state and a limb, tries to generate a new contact, and returns the id of the new State if successful + /// \param currentState Id of the considered state + /// \param name name of the limb used to create a contact + /// \param direction desired direction of motion for the robot + /// \return transformed configuration for which all possible contacts have been created + short generateContactState(in unsigned short currentState, in string name, in floatSeq direction) raises (Error); + /// get Ids of limb in an octree cell /// \param name name of the considered limb /// \param octreeNodeId considered configuration of the robot diff --git a/script/scenarios/sandbox/ANYmal/anymal_flatGround.py b/script/scenarios/sandbox/ANYmal/anymal_flatGround.py index 1cb8c56c..defa4a33 100644 --- a/script/scenarios/sandbox/ANYmal/anymal_flatGround.py +++ b/script/scenarios/sandbox/ANYmal/anymal_flatGround.py @@ -75,10 +75,10 @@ v(q_goal) v.addLandmark('anymal/base',0.3) v(q_init) - +z = [0.,0.,1] # specify the full body configurations as start and goal state of the problem -fullBody.setStartState(q_init,fullBody.limbs_names) -fullBody.setEndState(q_goal,fullBody.limbs_names) +fullBody.setStartState(q_init,fullBody.limbs_names, [z for _ in range(4)]) +fullBody.setEndState(q_goal,fullBody.limbs_names, [z for _ in range(4)]) print "Generate contact plan ..." diff --git a/script/scenarios/sandbox/run.sh b/script/scenarios/sandbox/run.sh index c249455b..6c19fae8 100755 --- a/script/scenarios/sandbox/run.sh +++ b/script/scenarios/sandbox/run.sh @@ -1,8 +1,8 @@ #!/bin/bash -gepetto-viewer-server & +gepetto-gui & hpp-rbprm-server & ipython -i --no-confirm-exit ./$1 -pkill -f 'gepetto-viewer-server' +pkill -f 'gepetto-gui' pkill -f 'hpp-rbprm-server' diff --git a/src/hpp/corbaserver/rbprm/rbprmfullbody.py b/src/hpp/corbaserver/rbprm/rbprmfullbody.py index 07e43a6a..6b955495 100755 --- a/src/hpp/corbaserver/rbprm/rbprmfullbody.py +++ b/src/hpp/corbaserver/rbprm/rbprmfullbody.py @@ -224,7 +224,7 @@ class FullBody (Robot): num_max_sample = 1 for (limbName, normal) in zip(contacts, normals): p = cl.getEffectorPosition(limbName,configuration)[0] - cl.addNewContact(sId, limbName, p, normal, num_max_sample) + cl.addNewContact(sId, limbName, p, normal, num_max_sample, False) return sId ## Retrieves the contact candidates configurations given a configuration and a limb @@ -285,7 +285,7 @@ class FullBody (Robot): num_max_sample = 1 for (limbName, normal) in zip(contacts, normals): p = cl.getEffectorPosition(limbName,configuration)[0] - cl.addNewContact(sId, limbName, p, normal, num_max_sample, True) + cl.addNewContact(sId, limbName, p, normal, num_max_sample, False) return cl.setStartStateId(sId) @@ -303,7 +303,7 @@ class FullBody (Robot): num_max_sample = 1 for (limbName, normal) in zip(contacts, normals): p = cl.getEffectorPosition(limbName,configuration)[0] - cl.addNewContact(sId, limbName, p, normal, num_max_sample, True) + cl.addNewContact(sId, limbName, p, normal, num_max_sample, False) return cl.setEndStateId(sId) ## Initialize the first state of the path interpolation diff --git a/src/hpp/corbaserver/rbprm/rbprmstate.py b/src/hpp/corbaserver/rbprm/rbprmstate.py index b13c74c6..6c8dce9f 100644 --- a/src/hpp/corbaserver/rbprm/rbprmstate.py +++ b/src/hpp/corbaserver/rbprm/rbprmstate.py @@ -202,3 +202,16 @@ class StateHelper(object): sId = fullBody.generateStateInContact(q,direction,acceleration) s = State(fullBody,sId=sId) return s + + @staticmethod + def moveAndContact(state,rootOffset,limbName): + s, success = StateHelper.removeContact(state, limbName) + assert success + success = s.projectToRoot((array(s.q()[:3]) + array(rootOffset)).tolist()+s.q()[3:7]) + if not success: + return state, False + sId = s.fullBody.clientRbprm.rbprm.generateContactState(s.sId, limbName,rootOffset) + if sId < 0: + return state, False + s = State(s.fullBody,sId=sId) + return s, True diff --git a/src/hpp/corbaserver/rbprm/tools/affordance_centroids.py b/src/hpp/corbaserver/rbprm/tools/affordance_centroids.py new file mode 100644 index 00000000..7b887559 --- /dev/null +++ b/src/hpp/corbaserver/rbprm/tools/affordance_centroids.py @@ -0,0 +1,67 @@ +from numpy import array, cross +from numpy.linalg import norm + + +## tools to retrive obstacles of a given affordance, indexed by the centroid of their surface. +## method to import is computeAffordanceCentroids + +def flat(pts): + return [item for sublist in pts for item in sublist] + +__EPS = 1e-5 + +def __filter_points(points): + res = [] + for el in points: + el_arr = array(el) + add = True + for al in res: + if(norm(al - el_arr) < __EPS): + add = False + break + if add: + res += [array(el)] + return res + +def __normal(points): + p1 = array(points[0]) + p2 = array(points[1]) + p3 = array(points[2]) + normal = cross((p2 - p1),(p3 - p1)) + normal /= norm(normal) + return normal.tolist() + +def __centroid(points): + return sum(points) / len(points) + +def __centroid_list(list_points): + return [[__centroid(__filter_points(flat(pts))).tolist(), __normal(pts[0]) ] for pts in list_points] + +def computeAffordanceCentroids(afftool, affordances=["Support","Lean"]): + all_points = [] + for _, el in enumerate(affordances): + all_points += afftool.getAffordancePoints(el) + return __centroid_list(all_points) + +b_id = 0 + +def draw_centroid(gui, winId, pt, scene="n_name", color = [1,1,1,0.3]): + p = pt[0] + n = array(pt[0]) + 0.03 * array(pt[1]) + resolution = 0.01 + global b_id + boxname = scene+"/"+str(b_id) + boxnameN = scene+"/"+str(b_id)+"n" + b_id += 1 + gui.addBox(boxname,resolution,resolution,resolution, color) + gui.addBox(boxnameN,resolution,resolution,resolution, color) + gui.applyConfiguration(boxname,[p[0],p[1],p[2],1,0,0,0]) + gui.applyConfiguration(boxnameN,[n[0],n[1],n[2],1,0,0,0]) + gui.addSceneToWindow(scene,winId) + gui.refresh() + +def draw_centroids(gui, winId, pts_lists, scene="n_name", color = [1,0,0,1]): + gui.createScene(scene) + for _, pt in enumerate(pts_lists): + draw_centroid(gui, winId, pt, scene=scene, color = color) + diff --git a/src/rbprmbuilder.impl.cc b/src/rbprmbuilder.impl.cc index 238e9500..ac4dc272 100644 --- a/src/rbprmbuilder.impl.cc +++ b/src/rbprmbuilder.impl.cc @@ -1065,6 +1065,83 @@ namespace hpp { } } + short RbprmBuilder::generateContactState(::CORBA::UShort cId, const char* name, const ::hpp::floatSeq& direction) + throw (hpp::Error) + { + try + { + if(lastStatesComputed_.size() <= (std::size_t)(cId)) + { + throw std::runtime_error ("Unexisting state " + std::string(""+(cId+1))); + } + State& state = lastStatesComputed_[cId]; + std::string limbname(name); + fcl::Vec3f dir; + for(std::size_t i =0; i <3; ++i) + { + dir[i] = direction[(_CORBA_ULong)i]; + } + pinocchio::Configuration_t config = state.configuration_; + fullBody()->device_->currentConfiguration(config); + + sampling::T_OctreeReport finalSet; + rbprm::T_Limb::const_iterator lit = fullBody()->GetLimbs().find(limbname); + if(lit == fullBody()->GetLimbs().end()) + { + throw std::runtime_error ("Impossible to find limb for joint " + + std::string(limbname) + " to robot; limb not defined."); + } + const RbPrmLimbPtr_t& limb = lit->second; + pinocchio::Transform3f transformPino = limb->octreeRoot(); // get root transform from configuration + fcl::Transform3f transform(transformPino.rotation(),transformPino.translation()); + // TODO fix as in rbprm-fullbody.cc!! + const affMap_t &affMap = problemSolver()->affordanceObjects; + if (affMap.map.empty ()) + { + throw hpp::Error ("No affordances found. Unable to interpolate."); + } + const std::vector<pinocchio::CollisionObjectPtr_t> objects = contact::getAffObjectsForLimb(std::string(limbname), affMap, + bindShooter_.affFilter_); + + std::vector<sampling::T_OctreeReport> reports(objects.size()); + std::size_t i (0); + //#pragma omp parallel for + for(std::vector<pinocchio::CollisionObjectPtr_t>::const_iterator oit = objects.begin(); + oit != objects.end(); ++oit, ++i) + { + sampling::GetCandidates(limb->sampleContainer_, transform, *oit, dir, reports[i], sampling::HeuristicParam()); + } + for(std::vector<sampling::T_OctreeReport>::const_iterator cit = reports.begin(); + cit != reports.end(); ++cit) + { + finalSet.insert(cit->begin(), cit->end()); + } + // randomize samples + std::random_shuffle(reports.begin(), reports.end()); + unsigned short num_samples_ok (0); + pinocchio::Configuration_t sampleConfig = config; + sampling::T_OctreeReport::const_iterator candCit = finalSet.begin(); + for(std::size_t i=0; i< _CORBA_ULong(finalSet.size()) && num_samples_ok < 100; ++i, ++candCit) + { + const sampling::OctreeReport& report = *candCit; + State state; + state.configuration_ = config; + hpp::rbprm::projection::ProjectionReport rep = + hpp::rbprm::projection::projectSampleToObstacle(fullBody(),std::string(limbname), limb, report, fullBody()->GetCollisionValidation(), sampleConfig, state); + if(rep.success_) + { + + lastStatesComputed_.push_back(rep.result_); + lastStatesComputedTime_.push_back(std::make_pair(-1., rep.result_)); + return lastStatesComputed_.size() -1; + } + } + return -1; + } catch (const std::exception& exc) { + throw hpp::Error (exc.what ()); + } + } + hpp::floatSeqSeq* RbprmBuilder::getContactSamplesProjected(const char* limbname, const hpp::floatSeq& configuration, const hpp::floatSeq& direction, diff --git a/src/rbprmbuilder.impl.hh b/src/rbprmbuilder.impl.hh index ab8639b2..b7f07336 100644 --- a/src/rbprmbuilder.impl.hh +++ b/src/rbprmbuilder.impl.hh @@ -237,6 +237,9 @@ namespace hpp { const hpp::floatSeq& direction, unsigned short numSamples) throw (hpp::Error); + virtual short generateContactState(::CORBA::UShort currentState, const char* name, const ::hpp::floatSeq& direction) throw (hpp::Error); + + virtual hpp::floatSeq* getSamplesIdsInOctreeNode(const char* limb, double octreeNodeId) throw (hpp::Error); -- GitLab