default_constraint_samplers.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2011, Willow Garage, Inc.
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the Willow Garage nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00035 /* Author: Ioan Sucan */
00036 
00037 #include <moveit/constraint_samplers/default_constraint_samplers.h>
00038 #include <set>
00039 #include <cassert>
00040 #include <eigen_conversions/eigen_msg.h>
00041 #include <boost/bind.hpp>
00042 
00043 bool constraint_samplers::JointConstraintSampler::configure(const moveit_msgs::Constraints &constr)
00044 {
00045   // construct the constraints
00046   std::vector<kinematic_constraints::JointConstraint> jc;
00047   for (std::size_t i = 0 ; i < constr.joint_constraints.size() ; ++i)
00048   {
00049     kinematic_constraints::JointConstraint j(scene_->getRobotModel());
00050     if (j.configure(constr.joint_constraints[i]))
00051       jc.push_back(j);
00052   }
00053 
00054   return jc.empty() ? false : configure(jc);
00055 }
00056 
00057 bool constraint_samplers::JointConstraintSampler::configure(const std::vector<kinematic_constraints::JointConstraint> &jc)
00058 {
00059   clear();
00060 
00061   if (!jmg_)
00062   {
00063     logError("NULL group specified for constraint sampler");
00064     return false;
00065   }
00066 
00067   // find and keep the constraints that operate on the group we sample
00068   // also keep bounds for joints as convenient
00069   const std::map<std::string, unsigned int> &vim = jmg_->getJointVariablesIndexMap();
00070   std::map<std::string, JointInfo> bound_data;
00071   bool some_valid_constraint = false;
00072   for (std::size_t i = 0 ; i < jc.size() ; ++i)
00073   {
00074     if (!jc[i].enabled())
00075       continue;
00076 
00077     const robot_model::JointModel *jm = jc[i].getJointModel();
00078     if (!jmg_->hasJointModel(jm->getName()))
00079       continue;
00080 
00081     some_valid_constraint = true;
00082 
00083     std::pair<double, double> joint_bounds;
00084     jm->getVariableBounds(jc[i].getJointVariableName(), joint_bounds);
00085 
00086     JointInfo ji;
00087     ji.index_ = vim.find(jc[i].getJointVariableName())->second;
00088     std::map<std::string, JointInfo>::iterator it = bound_data.find(jc[i].getJointVariableName());
00089     if (it != bound_data.end())
00090       ji = it->second;
00091 
00092     ji.potentiallyAdjustMinMaxBounds(std::max(joint_bounds.first, jc[i].getDesiredJointPosition() - jc[i].getJointToleranceBelow()),
00093                                      std::min(joint_bounds.second, jc[i].getDesiredJointPosition() + jc[i].getJointToleranceAbove()));
00094 
00095 
00096     logDebug("Bounds for %s JointConstraint are %g %g", jc[i].getJointVariableName().c_str(), ji.min_bound_, ji.max_bound_);
00097 
00098     if (ji.min_bound_ > ji.max_bound_ + std::numeric_limits<double>::epsilon())
00099     {
00100       std::stringstream cs; jc[i].print(cs);
00101       logError("The constraints for joint '%s' are such that there are no possible values for the joint - min_bound: %g, max_bound: %g. Failing.\n", jm->getName().c_str(), ji.min_bound_, ji.max_bound_);
00102       clear();
00103       return false;
00104     }
00105     bound_data[jc[i].getJointVariableName()] = ji;
00106   }
00107 
00108   if (!some_valid_constraint)
00109   {
00110     logWarn("No valid joint constraints");
00111     return false;
00112   }
00113 
00114   for (std::map<std::string, JointInfo>::iterator it = bound_data.begin(); it != bound_data.end(); ++it)
00115     bounds_.push_back(it->second);
00116 
00117   // get a separate list of joints that are not bounded; we will sample these randomly
00118   const std::vector<const robot_model::JointModel*> &joints = jmg_->getJointModels();
00119   for (std::size_t i = 0 ; i < joints.size() ; ++i)
00120     if (bound_data.find(joints[i]->getName()) == bound_data.end())
00121     {
00122       // check if all the vars of the joint are found in bound_data instead
00123       const std::vector<std::string> &vars = joints[i]->getVariableNames();
00124       if (vars.size() > 1)
00125       {
00126         bool all_found = true;
00127         for (std::size_t j = 0 ; j < vars.size() ; ++j)
00128           if (bound_data.find(vars[j]) == bound_data.end())
00129           {
00130             all_found = false;
00131             break;
00132           }
00133         if (all_found)
00134           continue;
00135       }
00136       unbounded_.push_back(joints[i]);
00137       uindex_.push_back(vim.find(joints[i]->getName())->second);
00138     }
00139   values_.resize(jmg_->getVariableCount());
00140   is_valid_ = true;
00141   return true;
00142 }
00143 
00144 bool constraint_samplers::JointConstraintSampler::sample(robot_state::JointStateGroup *jsg,
00145                                                          const robot_state::RobotState & /* ks */,
00146                                                          unsigned int /* max_attempts */)
00147 {
00148   if (!is_valid_)
00149   {
00150     logWarn("JointConstraintSampler not configured, won't sample");
00151     return false;
00152   }
00153 
00154   if (jsg->getName() != getGroupName())
00155   {
00156     logWarn("JointConstraintSampler sample function called with name %s which is not the group %s for which it was configured",
00157             jsg->getName().c_str(), getGroupName().c_str());
00158     return false;
00159   }
00160 
00161   // sample the unbounded joints first (in case some joint variables are bounded)
00162   for (std::size_t i = 0 ; i < unbounded_.size() ; ++i)
00163   {
00164     std::vector<double> v;
00165     unbounded_[i]->getVariableRandomValues(random_number_generator_, v);
00166     for (std::size_t j = 0 ; j < v.size() ; ++j)
00167       values_[uindex_[i] + j] = v[j];
00168   }
00169 
00170   // enforce the constraints for the constrained components (could be all of them)
00171   for (std::size_t i = 0 ; i < bounds_.size() ; ++i)
00172     values_[bounds_[i].index_] = random_number_generator_.uniformReal(bounds_[i].min_bound_, bounds_[i].max_bound_);
00173 
00174   jsg->setVariableValues(values_);
00175 
00176   // we are always successful
00177   return true;
00178 }
00179 
00180 bool constraint_samplers::JointConstraintSampler::project(robot_state::JointStateGroup *jsg,
00181                                                           const robot_state::RobotState &reference_state,
00182                                                           unsigned int max_attempts)
00183 {
00184   return sample(jsg, reference_state, max_attempts);
00185 }
00186 
00187 void constraint_samplers::JointConstraintSampler::clear()
00188 {
00189   ConstraintSampler::clear();
00190   bounds_.clear();
00191   unbounded_.clear();
00192   uindex_.clear();
00193   values_.clear();
00194 }
00195 
00196 constraint_samplers::IKSamplingPose::IKSamplingPose()
00197 {
00198 }
00199 
00200 constraint_samplers::IKSamplingPose::IKSamplingPose(const kinematic_constraints::PositionConstraint &pc) : position_constraint_(new kinematic_constraints::PositionConstraint(pc))
00201 {
00202 }
00203 
00204 constraint_samplers::IKSamplingPose::IKSamplingPose(const kinematic_constraints::OrientationConstraint &oc) : orientation_constraint_(new kinematic_constraints::OrientationConstraint(oc))
00205 {
00206 }
00207 
00208 constraint_samplers::IKSamplingPose::IKSamplingPose(const kinematic_constraints::PositionConstraint &pc, const kinematic_constraints::OrientationConstraint &oc) :
00209   position_constraint_(new kinematic_constraints::PositionConstraint(pc)), orientation_constraint_(new kinematic_constraints::OrientationConstraint(oc))
00210 {
00211 }
00212 
00213 constraint_samplers::IKSamplingPose::IKSamplingPose(const boost::shared_ptr<kinematic_constraints::PositionConstraint> &pc) : position_constraint_(pc)
00214 {
00215 }
00216 
00217 constraint_samplers::IKSamplingPose::IKSamplingPose(const boost::shared_ptr<kinematic_constraints::OrientationConstraint> &oc) : orientation_constraint_(oc)
00218 {
00219 }
00220 
00221 constraint_samplers::IKSamplingPose::IKSamplingPose(const boost::shared_ptr<kinematic_constraints::PositionConstraint> &pc, const boost::shared_ptr<kinematic_constraints::OrientationConstraint> &oc) : position_constraint_(pc), orientation_constraint_(oc)
00222 {
00223 }
00224 
00225 void constraint_samplers::IKConstraintSampler::clear()
00226 {
00227   ConstraintSampler::clear();
00228   kb_.reset();
00229   ik_frame_ = "";
00230   transform_ik_ = false;
00231 }
00232 
00233 bool constraint_samplers::IKConstraintSampler::configure(const IKSamplingPose &sp)
00234 {
00235   clear();
00236   if(!sp.position_constraint_ && !sp.orientation_constraint_) return false;
00237   if((!sp.orientation_constraint_ && !sp.position_constraint_->enabled()) ||
00238      (!sp.position_constraint_ && !sp.orientation_constraint_->enabled()) ||
00239      (sp.position_constraint_ && sp.orientation_constraint_ &&
00240       !sp.position_constraint_->enabled() && !sp.orientation_constraint_->enabled())) {
00241     logWarn("No enabled constraints in sampling pose");
00242     return false;
00243   }
00244 
00245   sampling_pose_ = sp;
00246   ik_timeout_ = jmg_->getDefaultIKTimeout();
00247   if (sampling_pose_.position_constraint_ && sampling_pose_.orientation_constraint_)
00248     if (sampling_pose_.position_constraint_->getLinkModel()->getName() != sampling_pose_.orientation_constraint_->getLinkModel()->getName())
00249     {
00250       logError("Position and orientation constraints need to be specified for the same link in order to use IK-based sampling");
00251       return false;
00252     }
00253 
00254   if (sampling_pose_.position_constraint_ && sampling_pose_.position_constraint_->mobileReferenceFrame())
00255     frame_depends_.push_back(sampling_pose_.position_constraint_->getReferenceFrame());
00256   if (sampling_pose_.orientation_constraint_ && sampling_pose_.orientation_constraint_->mobileReferenceFrame())
00257     frame_depends_.push_back(sampling_pose_.orientation_constraint_->getReferenceFrame());
00258   kb_ = jmg_->getSolverInstance();
00259   if (!kb_)
00260   {
00261     logWarn("No solver instance in setup");
00262     is_valid_ = false;
00263     return false;
00264   }
00265   is_valid_ = loadIKSolver();
00266   return is_valid_;
00267 }
00268 
00269 bool constraint_samplers::IKConstraintSampler::configure(const moveit_msgs::Constraints &constr)
00270 {
00271   for (std::size_t p = 0 ; p < constr.position_constraints.size() ; ++p)
00272     for (std::size_t o = 0 ; o < constr.orientation_constraints.size() ; ++o)
00273       if (constr.position_constraints[p].link_name == constr.orientation_constraints[o].link_name)
00274       {
00275         boost::shared_ptr<kinematic_constraints::PositionConstraint> pc(new kinematic_constraints::PositionConstraint(scene_->getRobotModel()));
00276         boost::shared_ptr<kinematic_constraints::OrientationConstraint> oc(new kinematic_constraints::OrientationConstraint(scene_->getRobotModel()));
00277         if (pc->configure(constr.position_constraints[p], scene_->getTransforms()) && oc->configure(constr.orientation_constraints[o], scene_->getTransforms()))
00278           return configure(IKSamplingPose(pc, oc));
00279       }
00280 
00281   for (std::size_t p = 0 ; p < constr.position_constraints.size() ; ++p)
00282   {
00283     boost::shared_ptr<kinematic_constraints::PositionConstraint> pc(new kinematic_constraints::PositionConstraint(scene_->getRobotModel()));
00284     if (pc->configure(constr.position_constraints[p], scene_->getTransforms()))
00285       return configure(IKSamplingPose(pc));
00286   }
00287 
00288   for (std::size_t o = 0 ; o < constr.orientation_constraints.size() ; ++o)
00289   {
00290     boost::shared_ptr<kinematic_constraints::OrientationConstraint> oc(new kinematic_constraints::OrientationConstraint(scene_->getRobotModel()));
00291     if (oc->configure(constr.orientation_constraints[o], scene_->getTransforms()))
00292         return configure(IKSamplingPose(oc));
00293   }
00294   return false;
00295 }
00296 
00297 double constraint_samplers::IKConstraintSampler::getSamplingVolume() const
00298 {
00299   double v = 1.0;
00300   if (sampling_pose_.position_constraint_)
00301   {
00302     const std::vector<bodies::BodyPtr> &b = sampling_pose_.position_constraint_->getConstraintRegions();
00303     double vol = 0;
00304     for (std::size_t i = 0 ; i < b.size() ; ++i)
00305       vol += b[i]->computeVolume();
00306     if (!b.empty())
00307       v *= vol;
00308   }
00309 
00310   if (sampling_pose_.orientation_constraint_)
00311     v *= sampling_pose_.orientation_constraint_->getXAxisTolerance() * sampling_pose_.orientation_constraint_->getYAxisTolerance() * sampling_pose_.orientation_constraint_->getZAxisTolerance();
00312   return v;
00313 }
00314 
00315 const std::string& constraint_samplers::IKConstraintSampler::getLinkName() const
00316 {
00317   if (sampling_pose_.orientation_constraint_)
00318     return sampling_pose_.orientation_constraint_->getLinkModel()->getName();
00319   return sampling_pose_.position_constraint_->getLinkModel()->getName();
00320 }
00321 
00322 bool constraint_samplers::IKConstraintSampler::loadIKSolver()
00323 {
00324   if (!kb_)
00325   {
00326     logError("No IK solver");
00327     return false;
00328   }
00329 
00330   // check if we need to transform the request into the coordinate frame expected by IK
00331   ik_frame_ = kb_->getBaseFrame();
00332   if (!ik_frame_.empty() && ik_frame_[0] == '/')
00333     ik_frame_.erase(ik_frame_.begin());
00334   transform_ik_ = !robot_state::Transforms::sameFrame(ik_frame_, jmg_->getParentModel()->getModelFrame());
00335   if (transform_ik_)
00336     if (!jmg_->getParentModel()->hasLinkModel(ik_frame_))
00337     {
00338       logError("The IK solver expects requests in frame '%s' but this frame is not known to the sampler. Ignoring transformation (IK may fail)", ik_frame_.c_str());
00339       transform_ik_ = false;
00340     }
00341 
00342   // check if IK is performed for the desired link
00343   bool wrong_link = false;
00344   if (sampling_pose_.position_constraint_)
00345   {
00346     if (!robot_state::Transforms::sameFrame(kb_->getTipFrame(), sampling_pose_.position_constraint_->getLinkModel()->getName()))
00347       wrong_link = true;
00348   }
00349   else
00350     if (!robot_state::Transforms::sameFrame(kb_->getTipFrame(), sampling_pose_.orientation_constraint_->getLinkModel()->getName()))
00351       wrong_link = true;
00352   if (wrong_link)
00353   {
00354     logError("IK cannot be performed for link '%s'. The solver can report IK solutions for link '%s'.",
00355              sampling_pose_.position_constraint_ ? sampling_pose_.position_constraint_->getLinkModel()->getName().c_str() : sampling_pose_.orientation_constraint_->getLinkModel()->getName().c_str(), kb_->getTipFrame().c_str());
00356     return false;
00357   }
00358   return true;
00359 }
00360 
00361 bool constraint_samplers::IKConstraintSampler::samplePose(Eigen::Vector3d &pos, Eigen::Quaterniond &quat,
00362                                                           const robot_state::RobotState &ks,
00363                                                           unsigned int max_attempts)
00364 {
00365   if (sampling_pose_.position_constraint_)
00366   {
00367     const std::vector<bodies::BodyPtr> &b = sampling_pose_.position_constraint_->getConstraintRegions();
00368     if (!b.empty())
00369     {
00370       bool found = false;
00371       std::size_t k = random_number_generator_.uniformInteger(0, b.size() - 1);
00372       for (std::size_t i = 0 ; i < b.size() ; ++i)
00373         if (b[(i+k) % b.size()]->samplePointInside(random_number_generator_, max_attempts, pos))
00374         {
00375           found = true;
00376           break;
00377         }
00378       if (!found)
00379       {
00380         logError("Unable to sample a point inside the constraint region");
00381         return false;
00382       }
00383     }
00384     else
00385     {
00386       logError("Unable to sample a point inside the constraint region. Constraint region is empty when it should not be.");
00387       return false;
00388     }
00389 
00390     // if this constraint is with respect a mobile frame, we need to convert this rotation to the root frame of the model
00391     if (sampling_pose_.position_constraint_->mobileReferenceFrame())
00392       pos = ks.getFrameTransform(sampling_pose_.position_constraint_->getReferenceFrame()) * pos;
00393   }
00394   else
00395   {
00396     // do FK for rand state
00397     robot_state::RobotState tempState(ks);
00398     robot_state::JointStateGroup *tmp = tempState.getJointStateGroup(jmg_->getName());
00399     if (tmp)
00400     {
00401       tmp->setToRandomValues();
00402       pos = tempState.getLinkState(sampling_pose_.orientation_constraint_->getLinkModel()->getName())->getGlobalLinkTransform().translation();
00403     }
00404     else
00405     {
00406       logError("Passed a JointStateGroup for a mismatching JointModelGroup");
00407       return false;
00408     }
00409   }
00410 
00411   if (sampling_pose_.orientation_constraint_)
00412   {
00413     // sample a rotation matrix within the allowed bounds
00414     double angle_x = 2.0 * (random_number_generator_.uniform01() - 0.5) * (sampling_pose_.orientation_constraint_->getXAxisTolerance()-std::numeric_limits<double>::epsilon());
00415     double angle_y = 2.0 * (random_number_generator_.uniform01() - 0.5) * (sampling_pose_.orientation_constraint_->getYAxisTolerance()-std::numeric_limits<double>::epsilon());
00416     double angle_z = 2.0 * (random_number_generator_.uniform01() - 0.5) * (sampling_pose_.orientation_constraint_->getZAxisTolerance()-std::numeric_limits<double>::epsilon());
00417     Eigen::Affine3d diff(Eigen::AngleAxisd(angle_x, Eigen::Vector3d::UnitX())
00418                          * Eigen::AngleAxisd(angle_y, Eigen::Vector3d::UnitY())
00419                          * Eigen::AngleAxisd(angle_z, Eigen::Vector3d::UnitZ()));
00420     Eigen::Affine3d reqr(sampling_pose_.orientation_constraint_->getDesiredRotationMatrix() * diff.rotation());
00421     quat = Eigen::Quaterniond(reqr.rotation());
00422 
00423     // if this constraint is with respect a mobile frame, we need to convert this rotation to the root frame of the model
00424     if (sampling_pose_.orientation_constraint_->mobileReferenceFrame())
00425     {
00426       const Eigen::Affine3d &t = ks.getFrameTransform(sampling_pose_.orientation_constraint_->getReferenceFrame());
00427       Eigen::Affine3d rt(t.rotation() * quat.toRotationMatrix());
00428       quat = Eigen::Quaterniond(rt.rotation());
00429     }
00430   }
00431   else
00432   {
00433     // sample a random orientation
00434     double q[4];
00435     random_number_generator_.quaternion(q);
00436     quat = Eigen::Quaterniond(q[3], q[0], q[1], q[2]);
00437   }
00438 
00439   // if there is an offset, we need to undo the induced rotation in the sampled transform origin (point)
00440   if (sampling_pose_.position_constraint_ && sampling_pose_.position_constraint_->hasLinkOffset())
00441     // the rotation matrix that corresponds to the desired orientation
00442     pos = pos - quat.toRotationMatrix() * sampling_pose_.position_constraint_->getLinkOffset();
00443 
00444   // we now have the transform we wish to perform IK for, in the planning frame
00445 
00446   if (transform_ik_)
00447   {
00448     // we need to convert this transform to the frame expected by the IK solver
00449     // both the planning frame and the frame for the IK are assumed to be robot links
00450     Eigen::Affine3d ikq(Eigen::Translation3d(pos) * quat.toRotationMatrix());
00451     ikq = ks.getFrameTransform(ik_frame_).inverse() * ikq;
00452     pos = ikq.translation();
00453     quat = Eigen::Quaterniond(ikq.rotation());
00454   }
00455 
00456   return true;
00457 }
00458 
00459 namespace constraint_samplers
00460 {
00461 namespace
00462 {
00463 void samplingIkCallbackFnAdapter(robot_state::JointStateGroup *jsg, const robot_state::StateValidityCallbackFn &constraint,
00464                                  const geometry_msgs::Pose &, const std::vector<double> &ik_sol, moveit_msgs::MoveItErrorCodes &error_code)
00465 {
00466   const std::vector<unsigned int> &bij = jsg->getJointModelGroup()->getKinematicsSolverJointBijection();
00467   std::vector<double> solution(bij.size());
00468   for (std::size_t i = 0 ; i < bij.size() ; ++i)
00469     solution[i] = ik_sol[bij[i]];
00470   if (constraint(jsg, solution))
00471     error_code.val = moveit_msgs::MoveItErrorCodes::SUCCESS;
00472   else
00473     error_code.val = moveit_msgs::MoveItErrorCodes::NO_IK_SOLUTION;
00474 }
00475 }
00476 }
00477 
00478 bool constraint_samplers::IKConstraintSampler::sample(robot_state::JointStateGroup *jsg, const robot_state::RobotState &ks, unsigned int max_attempts)
00479 {
00480   return sampleHelper(jsg, ks, max_attempts, false);
00481 }
00482 
00483 bool constraint_samplers::IKConstraintSampler::sampleHelper(robot_state::JointStateGroup *jsg, const robot_state::RobotState &ks, unsigned int max_attempts, bool project)
00484 {
00485   if (!is_valid_)
00486     return false;
00487 
00488   if (jsg->getName() != getGroupName())
00489   {
00490     logWarn("IKConstraintSampler sample function called with name %s which is not the group %s for which it was configured",
00491             jsg->getName().c_str(), getGroupName().c_str());
00492     return false;
00493   }
00494 
00495   kinematics::KinematicsBase::IKCallbackFn adapted_ik_validity_callback;
00496   if (state_validity_callback_)
00497     adapted_ik_validity_callback = boost::bind(&samplingIkCallbackFnAdapter, jsg, state_validity_callback_, _1, _2, _3);
00498 
00499   for (unsigned int a = 0 ; a < max_attempts ; ++a)
00500   {
00501     // sample a point in the constraint region
00502     Eigen::Vector3d point;
00503     Eigen::Quaterniond quat;
00504     if (!samplePose(point, quat, ks, max_attempts))
00505     {
00506       if (verbose_)
00507         logInform("IK constraint sampler was unable to produce a pose to run IK for");
00508       return false;
00509     }
00510 
00511     geometry_msgs::Pose ik_query;
00512     ik_query.position.x = point.x();
00513     ik_query.position.y = point.y();
00514     ik_query.position.z = point.z();
00515     ik_query.orientation.x = quat.x();
00516     ik_query.orientation.y = quat.y();
00517     ik_query.orientation.z = quat.z();
00518     ik_query.orientation.w = quat.w();
00519 
00520     if (callIK(ik_query, adapted_ik_validity_callback, ik_timeout_, jsg, project && a == 0))
00521       return true;
00522   }
00523   return false;
00524 }
00525 
00526 bool constraint_samplers::IKConstraintSampler::project(robot_state::JointStateGroup *jsg,
00527                                                        const robot_state::RobotState &reference_state,
00528                                                        unsigned int max_attempts)
00529 {
00530   return sampleHelper(jsg, reference_state, max_attempts, true);
00531 }
00532 
00533 bool constraint_samplers::IKConstraintSampler::callIK(const geometry_msgs::Pose &ik_query, const kinematics::KinematicsBase::IKCallbackFn &adapted_ik_validity_callback,
00534                                                       double timeout, robot_state::JointStateGroup *jsg, bool use_as_seed)
00535 {
00536   const std::vector<unsigned int>& ik_joint_bijection = jmg_->getKinematicsSolverJointBijection();
00537   std::vector<double> seed(ik_joint_bijection.size(), 0.0);
00538   std::vector<double> vals;
00539 
00540   if (use_as_seed)
00541     jsg->getVariableValues(vals);
00542   else
00543     // sample a seed value
00544     jmg_->getVariableRandomValues(random_number_generator_, vals);
00545 
00546   assert(vals.size() == ik_joint_bijection.size());
00547   for (std::size_t i = 0 ; i < ik_joint_bijection.size() ; ++i)
00548     seed[ik_joint_bijection[i]] = vals[i];
00549 
00550   std::vector<double> ik_sol;
00551   moveit_msgs::MoveItErrorCodes error;
00552 
00553   if (adapted_ik_validity_callback ?
00554       kb_->searchPositionIK(ik_query, seed, timeout, ik_sol, adapted_ik_validity_callback, error) :
00555       kb_->searchPositionIK(ik_query, seed, timeout, ik_sol, error))
00556   {
00557     assert(ik_sol.size() == ik_joint_bijection.size());
00558     std::vector<double> solution(ik_joint_bijection.size());
00559     for (std::size_t i = 0 ; i < ik_joint_bijection.size() ; ++i)
00560       solution[i] = ik_sol[ik_joint_bijection[i]];
00561     jsg->setVariableValues(solution);
00562 
00563     assert(!sampling_pose_.orientation_constraint_ || sampling_pose_.orientation_constraint_->decide(*jsg->getRobotState(), verbose_).satisfied);
00564     assert(!sampling_pose_.position_constraint_ || sampling_pose_.position_constraint_->decide(*jsg->getRobotState(), verbose_).satisfied);
00565 
00566     return true;
00567   }
00568   else
00569   {
00570     if (error.val != moveit_msgs::MoveItErrorCodes::NO_IK_SOLUTION &&
00571     error.val != moveit_msgs::MoveItErrorCodes::INVALID_ROBOT_STATE &&
00572         error.val != moveit_msgs::MoveItErrorCodes::TIMED_OUT)
00573       logError("IK solver failed with error %d", error.val);
00574     else
00575       if (verbose_)
00576         logInform("IK failed");
00577   }
00578   return false;
00579 }


moveit_core
Author(s): Ioan Sucan , Sachin Chitta , Acorn Pooley
autogenerated on Mon Oct 6 2014 02:24:46