From fdc63ef65e1a3970885ceab9ee1bf06b71e76c9a Mon Sep 17 00:00:00 2001 From: Steve Tonneau <stonneau@axle.laas.fr> Date: Wed, 3 Aug 2016 23:03:44 +0200 Subject: [PATCH] early attempt at computing contact points --- idl/hpp/corbaserver/rbprm/rbprmbuilder.idl | 6 ++ src/hpp/corbaserver/rbprm/rbprmfullbody.py | 10 +++ src/rbprmbuilder.impl.cc | 88 ++++++++++++++++++++++ src/rbprmbuilder.impl.hh | 1 + 4 files changed, 105 insertions(+) diff --git a/idl/hpp/corbaserver/rbprm/rbprmbuilder.idl b/idl/hpp/corbaserver/rbprm/rbprmbuilder.idl index 8c3d0ed6..0c220798 100755 --- a/idl/hpp/corbaserver/rbprm/rbprmbuilder.idl +++ b/idl/hpp/corbaserver/rbprm/rbprmbuilder.idl @@ -204,6 +204,12 @@ module hpp /// \param contactLimbs ids of the limb in contact for the state void setEndState(in floatSeq dofArray, in Names_t contactLimbs) raises (Error); + /// Provided a discrete contact sequence has already been computed, computes + /// all the contact positions and normals for a given state, the next one, and the intermediate between them. + /// \param stateId normalized step for generation along the path (ie the path has a length of 1). + /// \return list of 2 or 3 lists of 6d vectors [pox, poy, posz, nprmalx, normaly, normalz] + floatSeqSeq computeContactPoints(in unsigned short stateId) raises (Error); + /// Provided a path has already been computed, interpolates it and generates the statically stable /// constact configurations along it. setStartState and setEndState must have been called prior /// to this function. If these conditions are not met an error is raised. diff --git a/src/hpp/corbaserver/rbprm/rbprmfullbody.py b/src/hpp/corbaserver/rbprm/rbprmfullbody.py index 58b0b13a..ae3ed9e7 100755 --- a/src/hpp/corbaserver/rbprm/rbprmfullbody.py +++ b/src/hpp/corbaserver/rbprm/rbprmfullbody.py @@ -233,6 +233,16 @@ class FullBody (object): # \param robustnessTreshold minimum value of the static equilibrium robustness criterion required to accept the configuration (0 by default). def interpolate(self, stepsize, pathId = 1, robustnessTreshold = 0): return self.client.rbprm.rbprm.interpolate(stepsize, pathId, robustnessTreshold) + + ## Discretizes a path return by a motion planner into a discrete + # sequence of balanced, contact configurations and returns + # the sequence as an array of configurations + # + # \param stateId id of the first state + # \param pathId Id of the path to compute from + # \param robustnessTreshold minimum value of the static equilibrium robustness criterion required to accept the configuration (0 by default). + def computeContactPoints(self, stateId): + return self.client.rbprm.rbprm.computeContactPoints(stateId) ## Given start and goal states # generate a contact sequence over a list of configurations diff --git a/src/rbprmbuilder.impl.cc b/src/rbprmbuilder.impl.cc index dacf398a..fb3d7997 100755 --- a/src/rbprmbuilder.impl.cc +++ b/src/rbprmbuilder.impl.cc @@ -616,6 +616,94 @@ namespace hpp { } } + + typedef Eigen::Matrix <value_type, 4, 3, Eigen::RowMajor> Matrix43; + typedef Eigen::Matrix <value_type, 4, 3, Eigen::RowMajor> Rotation; + typedef Eigen::Ref<Matrix43> Ref_matrix43; + + std::vector<fcl::Vec3f> computeRectangleContact(const rbprm::RbPrmFullBodyPtr_t device, + const rbprm::State& state) + { + std::vector<fcl::Vec3f> res; + const rbprm::T_Limb& limbs = device->GetLimbs(); + rbprm::RbPrmLimbPtr_t limb; + Matrix43 p; Eigen::Matrix3d R; + for(std::map<std::string, fcl::Vec3f>::const_iterator cit = state.contactPositions_.begin(); + cit != state.contactPositions_.end(); ++cit) + { + const std::string& name = cit->first; + const fcl::Vec3f& position = cit->second; + limb = limbs.at(name); + const double& lx = limb->x_, ly = limb->y_; + p << lx, ly, 0, + lx, -ly, 0, + -lx, -ly, 0, + -lx, ly, 0; + const fcl::Matrix3f& fclRotation = state.contactRotation_.at(name); + for(int i =0; i< 3; ++i) + for(int j =0; j<3;++j) + R(i,j) = fclRotation(i,j); + for(std::size_t i =0; i<4; ++i) + { + res.push_back(position + (R*p.row(i).transpose())); + res.push_back(state.contactNormals_.at(name)); + } + } + return res; + } + + floatSeqSeq* RbprmBuilder::computeContactPoints(unsigned short cId) throw (hpp::Error) + { + if(lastStatesComputed_.size() <= cId + 1) + { + throw std::runtime_error ("Unexisting state " + std::string(""+(cId+1))); + } + const State& firstState = lastStatesComputed_[cId], thirdState = lastStatesComputed_[cId+1]; + std::vector<std::vector<fcl::Vec3f> > allStates; + allStates.push_back(computeRectangleContact(fullBody_, firstState)); + std::vector<std::string> variations =thirdState.contactVariations(firstState); + if(variations.size() >1) + { + throw std::runtime_error ("too many state variation between states" + std::string(""+cId) + + "and " + std::string(""+(cId + 1))); + } + if(!variations.empty()) + { +std::cout << "variation " << variations[0] << std::endl; + State intermediary(firstState); + intermediary.RemoveContact(*variations.begin()); + allStates.push_back(computeRectangleContact(fullBody_, intermediary)); + } + allStates.push_back(computeRectangleContact(fullBody_, thirdState)); + + hpp::floatSeqSeq *res; + res = new hpp::floatSeqSeq (); + + // compute array of contact positions + + res->length ((_CORBA_ULong)allStates.size()); + std::size_t i=0; + for(std::vector<std::vector<fcl::Vec3f> >::const_iterator cit = allStates.begin(); + cit != allStates.end(); ++cit, ++i) + { + const std::vector<fcl::Vec3f>& positions = *cit; + _CORBA_ULong size = (_CORBA_ULong) positions.size () * 3; + double* dofArray = hpp::floatSeq::allocbuf(size); + hpp::floatSeq floats (size, size, dofArray, true); + //convert the config in dofseq + for(std::size_t h = 0; h<positions.size(); ++h) + { + for(std::size_t k =0; k<3; ++k) + { + model::size_type j (h*3 + k); + dofArray[j] = positions[h][k]; + } + } + (*res) [(_CORBA_ULong)i] = floats; + } + return res; + } + floatSeqSeq* RbprmBuilder::interpolate(double timestep, double path, double robustnessTreshold) throw (hpp::Error) { try diff --git a/src/rbprmbuilder.impl.hh b/src/rbprmbuilder.impl.hh index 62580fe7..593c344e 100755 --- a/src/rbprmbuilder.impl.hh +++ b/src/rbprmbuilder.impl.hh @@ -139,6 +139,7 @@ namespace hpp { virtual void setStartState(const hpp::floatSeq& configuration, const hpp::Names_t& contactLimbs) throw (hpp::Error); virtual void setEndState(const hpp::floatSeq& configuration, const hpp::Names_t& contactLimbs) throw (hpp::Error); + virtual hpp::floatSeqSeq* computeContactPoints(unsigned short cId) throw (hpp::Error); virtual hpp::floatSeqSeq* interpolate(double timestep, double path, double robustnessTreshold) throw (hpp::Error); virtual hpp::floatSeqSeq* interpolateConfigs(const hpp::floatSeqSeq& configs, double robustnessTreshold) throw (hpp::Error); virtual void interpolateBetweenStates(double state1, double state2, unsigned short numOptimizations) throw (hpp::Error); -- GitLab