コード例 #1
0
bool constraint_samplers::IKConstraintSampler::configure(const moveit_msgs::Constraints &constr)
{
  for (std::size_t p = 0 ; p < constr.position_constraints.size() ; ++p)
    for (std::size_t o = 0 ; o < constr.orientation_constraints.size() ; ++o)
      if (constr.position_constraints[p].link_name == constr.orientation_constraints[o].link_name)
      {
        boost::shared_ptr<kinematic_constraints::PositionConstraint> pc(new kinematic_constraints::PositionConstraint(scene_->getKinematicModel(), scene_->getTransforms()));
        boost::shared_ptr<kinematic_constraints::OrientationConstraint> oc(new kinematic_constraints::OrientationConstraint(scene_->getKinematicModel(), scene_->getTransforms()));
        if (pc->configure(constr.position_constraints[p]) && oc->configure(constr.orientation_constraints[o]))
          return setup(IKSamplingPose(pc, oc));
      }
  
  for (std::size_t p = 0 ; p < constr.position_constraints.size() ; ++p)
  {   
    boost::shared_ptr<kinematic_constraints::PositionConstraint> pc(new kinematic_constraints::PositionConstraint(scene_->getKinematicModel(), scene_->getTransforms()));
    if (pc->configure(constr.position_constraints[p]))
      return setup(IKSamplingPose(pc));
  }
  
  for (std::size_t o = 0 ; o < constr.orientation_constraints.size() ; ++o)
  {            
    boost::shared_ptr<kinematic_constraints::OrientationConstraint> oc(new kinematic_constraints::OrientationConstraint(scene_->getKinematicModel(), scene_->getTransforms()));
      if (oc->configure(constr.orientation_constraints[o]))
        return setup(IKSamplingPose(oc));
  }
  return false;
}
コード例 #2
0
constraint_samplers::ConstraintSamplerPtr constraint_samplers::ConstraintSamplerManager::selectDefaultSampler(const planning_scene::PlanningSceneConstPtr &scene,
                                                                                                              const std::string &group_name,
                                                                                                              const moveit_msgs::Constraints &constr)
{
  const robot_model::JointModelGroup *jmg = scene->getRobotModel()->getJointModelGroup(group_name);
  if (!jmg)
    return constraint_samplers::ConstraintSamplerPtr();
  std::stringstream ss; ss << constr;
  logDebug("Attempting to construct constrained state sampler for group '%s', using constraints:\n%s.\n", jmg->getName().c_str(), ss.str().c_str());
  
  ConstraintSamplerPtr joint_sampler;
  // if there are joint constraints, we could possibly get a sampler from those
  if (!constr.joint_constraints.empty())
  {    
    logDebug("There are joint constraints specified. Attempting to construct a JointConstraintSampler for group '%s'", jmg->getName().c_str());

    std::map<std::string, bool> joint_coverage;
    for(std::size_t i = 0; i < jmg->getVariableNames().size() ; ++i)
      joint_coverage[jmg->getVariableNames()[i]] = false;
    
    // construct the constraints
    std::vector<kinematic_constraints::JointConstraint> jc;
    for (std::size_t i = 0 ; i < constr.joint_constraints.size() ; ++i)
    {
      kinematic_constraints::JointConstraint j(scene->getRobotModel(), scene->getTransforms());
      if (j.configure(constr.joint_constraints[i]))
      {
        if (joint_coverage.find(j.getJointVariableName()) != joint_coverage.end())
        {
          joint_coverage[j.getJointVariableName()] = true;
          jc.push_back(j);
        }
      }
    }

    bool full_coverage = true;
    for (std::map<std::string, bool>::iterator it = joint_coverage.begin(); it != joint_coverage.end(); ++it) 
      if (!it->second) 
      {
        full_coverage = false;
        break;
      }
    
    // if we have constrained every joint, then we just use a sampler using these constraints
    if (full_coverage)
    {
      boost::shared_ptr<JointConstraintSampler> sampler(new JointConstraintSampler(scene, jmg->getName()));
      if (sampler->configure(jc))
      {
        logDebug("Allocated a sampler satisfying joint constraints for group '%s'", jmg->getName().c_str());
        return sampler;
      }
    }
    else
      // if a smaller set of joints has been specified, keep the constraint sampler around, but use it only if no IK sampler has been specified.
      if (!jc.empty())
      {
        boost::shared_ptr<JointConstraintSampler> sampler(new JointConstraintSampler(scene, jmg->getName()));
        if (sampler->configure(jc))
        {
          logDebug("Temporary sampler satisfying joint constraints for group '%s' allocated. Looking for different types of constraints before returning though.", jmg->getName().c_str());
          joint_sampler = sampler;
        }
      }
  }
  
  std::vector<ConstraintSamplerPtr> samplers;
  if (joint_sampler) 
    samplers.push_back(joint_sampler);
  
  // read the ik allocators, if any
  robot_model::SolverAllocatorFn ik_alloc = jmg->getSolverAllocators().first;
  std::map<const robot_model::JointModelGroup*, robot_model::SolverAllocatorFn> ik_subgroup_alloc = jmg->getSolverAllocators().second;
  
  // if we have a means of computing complete states for the group using IK, then we try to see if any IK constraints should be used
  if (ik_alloc)
  {
    logDebug("There is an IK allocator for '%s'. Checking for corresponding position and/or orientation constraints", jmg->getName().c_str());
    
    // keep track of which links we constrained
    std::map<std::string, boost::shared_ptr<IKConstraintSampler> > usedL;
    
    // if we have position and/or orientation constraints on links that we can perform IK for,
    // we will use a sampleable goal region that employs IK to sample goals;
    // if there are multiple constraints for the same link, we keep the one with the smallest 
    // volume for sampling
    for (std::size_t p = 0 ; p < constr.position_constraints.size() ; ++p)
      for (std::size_t o = 0 ; o < constr.orientation_constraints.size() ; ++o)
        if (constr.position_constraints[p].link_name == constr.orientation_constraints[o].link_name)
        {
          boost::shared_ptr<kinematic_constraints::PositionConstraint> pc(new kinematic_constraints::PositionConstraint(scene->getRobotModel(), scene->getTransforms()));
          boost::shared_ptr<kinematic_constraints::OrientationConstraint> oc(new kinematic_constraints::OrientationConstraint(scene->getRobotModel(), scene->getTransforms()));
          if (pc->configure(constr.position_constraints[p]) && oc->configure(constr.orientation_constraints[o]))
          {        
            boost::shared_ptr<IKConstraintSampler> iks(new IKConstraintSampler(scene, jmg->getName()));
            if(iks->configure(IKSamplingPose(pc, oc))) {
              bool use = true;
              if (usedL.find(constr.position_constraints[p].link_name) != usedL.end())
                if (usedL[constr.position_constraints[p].link_name]->getSamplingVolume() < iks->getSamplingVolume())
                  use = false;
              if (use)
              {
                usedL[constr.position_constraints[p].link_name] = iks;
                logDebug("Allocated an IK-based sampler for group '%s' satisfying position and orientation constraints on link '%s'",
                         jmg->getName().c_str(), constr.position_constraints[p].link_name.c_str());
              }
            }
          }
        }
    
    // keep track of links constrained with a full pose
    std::map<std::string, boost::shared_ptr<IKConstraintSampler> > usedL_fullPose = usedL;
    
    for (std::size_t p = 0 ; p < constr.position_constraints.size() ; ++p)
    {   
      // if we are constraining this link with a full pose, we do not attempt to constrain it with a position constraint only
      if (usedL_fullPose.find(constr.position_constraints[p].link_name) != usedL_fullPose.end())
        continue;
      
      boost::shared_ptr<kinematic_constraints::PositionConstraint> pc(new kinematic_constraints::PositionConstraint(scene->getRobotModel(), scene->getTransforms()));
      if (pc->configure(constr.position_constraints[p]))
      {
        boost::shared_ptr<IKConstraintSampler> iks(new IKConstraintSampler(scene, jmg->getName()));
        if(iks->configure(IKSamplingPose(pc))) 
        {
          bool use = true;
          if (usedL.find(constr.position_constraints[p].link_name) != usedL.end())
            if (usedL[constr.position_constraints[p].link_name]->getSamplingVolume() < iks->getSamplingVolume())
              use = false;
          if (use)
          {
            usedL[constr.position_constraints[p].link_name] = iks;
            logDebug("Allocated an IK-based sampler for group '%s' satisfying position constraints on link '%s'", 
                     jmg->getName().c_str(), constr.position_constraints[p].link_name.c_str());
          }
        }
      }
    }
    
    for (std::size_t o = 0 ; o < constr.orientation_constraints.size() ; ++o)
    {            
      // if we are constraining this link with a full pose, we do not attempt to constrain it with an orientation constraint only
      if (usedL_fullPose.find(constr.orientation_constraints[o].link_name) != usedL_fullPose.end())
        continue;
      
      boost::shared_ptr<kinematic_constraints::OrientationConstraint> oc(new kinematic_constraints::OrientationConstraint(scene->getRobotModel(), scene->getTransforms()));
      if (oc->configure(constr.orientation_constraints[o]))
      {
        boost::shared_ptr<IKConstraintSampler> iks(new IKConstraintSampler(scene, jmg->getName()));
        if(iks->configure(IKSamplingPose(oc))) 
        {
          bool use = true;
          if (usedL.find(constr.orientation_constraints[o].link_name) != usedL.end())
            if (usedL[constr.orientation_constraints[o].link_name]->getSamplingVolume() < iks->getSamplingVolume())
              use = false;
          if (use)
          {
            usedL[constr.orientation_constraints[o].link_name] = iks;
            logDebug("Allocated an IK-based sampler for group '%s' satisfying orientation constraints on link '%s'", 
                     jmg->getName().c_str(), constr.orientation_constraints[o].link_name.c_str());
          } 
        } 
      }
    }
    
    if (usedL.size() == 1)
    {
      if (samplers.empty())
        return usedL.begin()->second;
      else
      {
        samplers.push_back(usedL.begin()->second);
        return ConstraintSamplerPtr(new UnionConstraintSampler(scene, jmg->getName(), samplers));
      }
    } 
    else 
      if (usedL.size() > 1)
      {
        logDebug("Too many IK-based samplers for group '%s'. Keeping the one with minimal sampling volume", jmg->getName().c_str());
        // find the sampler with the smallest sampling volume; delete the rest
        boost::shared_ptr<IKConstraintSampler> iks = usedL.begin()->second;
        double msv = iks->getSamplingVolume();
        for (std::map<std::string, boost::shared_ptr<IKConstraintSampler> >::const_iterator it = ++usedL.begin() ; it != usedL.end() ; ++it)
        {
          double v = it->second->getSamplingVolume();
          if (v < msv)
          {
            iks = it->second;
            msv = v;
          } 
        }
        if (samplers.empty())
        {
          return iks;
        }
        else
        {
          samplers.push_back(iks);
          return ConstraintSamplerPtr(new UnionConstraintSampler(scene, jmg->getName(), samplers));
        }
      }
  }
  
  // if we got to this point, we have not decided on a sampler.
  // we now check to see if we can use samplers from subgroups
  if (!ik_subgroup_alloc.empty())
  {        
    logDebug("There are IK allocators for subgroups of group '%s'. Checking for corresponding position and/or orientation constraints", jmg->getName().c_str());

    bool some_sampler_valid = false;
    
    std::set<std::size_t> usedP, usedO;
    for (std::map<const robot_model::JointModelGroup*, robot_model::SolverAllocatorFn>::const_iterator it = ik_subgroup_alloc.begin() ; it != ik_subgroup_alloc.end() ; ++it)
    {
      // construct a sub-set of constraints that operate on the sub-group for which we have an IK allocator
      moveit_msgs::Constraints sub_constr;
      for (std::size_t p = 0 ; p < constr.position_constraints.size() ; ++p)
        if (it->first->hasLinkModel(constr.position_constraints[p].link_name))
          if (usedP.find(p) == usedP.end())
          {
            sub_constr.position_constraints.push_back(constr.position_constraints[p]);
            usedP.insert(p);
          }
      
      for (std::size_t o = 0 ; o < constr.orientation_constraints.size() ; ++o)        
        if (it->first->hasLinkModel(constr.orientation_constraints[o].link_name))
          if (usedO.find(o) == usedO.end())
          {
            sub_constr.orientation_constraints.push_back(constr.orientation_constraints[o]);
            usedO.insert(o);
          }
      
      // if some matching constraints were found, construct the allocator
      if (!sub_constr.orientation_constraints.empty() || !sub_constr.position_constraints.empty())
      {
        logDebug("Attempting to construct a sampler for the '%s' subgroup of '%s'", it->first->getName().c_str(), jmg->getName().c_str());
        ConstraintSamplerPtr cs = selectDefaultSampler(scene, it->first->getName(), sub_constr);
        if (cs)
        {
          logDebug("Constructed a sampler for the joints corresponding to group '%s', but part of group '%s'", 
                   it->first->getName().c_str(), jmg->getName().c_str());
          some_sampler_valid = true;
          samplers.push_back(cs);
        }
      }
    }
    if (some_sampler_valid)
    {
      logDebug("Constructing sampler for group '%s' as a union of %u samplers", jmg->getName().c_str(), (unsigned int)samplers.size());
      return ConstraintSamplerPtr(new UnionConstraintSampler(scene, jmg->getName(), samplers));
    }
  }

  //if we've gotten here, just return joint sampler
  if (joint_sampler)
  {
    logDebug("Allocated a sampler satisfying joint constraints for group '%s'", jmg->getName().c_str());
    return joint_sampler;
  }
  
  logDebug("No constraints sampler allocated for group '%s'", jmg->getName().c_str());
  
  return ConstraintSamplerPtr();
}