예제 #1
0
bool moveit::core::JointModelGroup::canSetStateFromIK(const std::string &tip) const
{
  const kinematics::KinematicsBaseConstPtr& solver = getSolverInstance();
  if (!solver || tip.empty())
    return false;

  const std::vector<std::string> &tip_frames = solver->getTipFrames();

  if (tip_frames.empty())
  {
    logDebug("Group %s has no tip frame(s)", name_.c_str());
    return false;
  }

  // loop through all tip frames supported by the JMG
  for (std::size_t i = 0; i < tip_frames.size(); ++i)
  {
    // remove frame reference, if specified
    const std::string &tip_local = tip[0] == '/' ? tip.substr(1) : tip;
    const std::string &tip_frame_local = tip_frames[i][0] == '/' ? tip_frames[i].substr(1) : tip_frames[i];
    logDebug("joint_model_group.canSetStateFromIK: comparing input tip: %s to this groups tip: %s ", tip_local.c_str(), tip_frame_local.c_str());

    // Check if the IK solver's tip is the same as the frame of inquiry
    if (tip_local != tip_frame_local)
    {
      // If not the same, check if this planning group includes the frame of inquiry
      if (hasLinkModel(tip_frame_local))
      {
        const LinkModel *lm = getLinkModel(tip_frame_local);
        const LinkTransformMap &fixed_links = lm->getAssociatedFixedTransforms();
        // Check if our frame of inquiry is located anywhere further down the chain (towards the tip of the arm)
        for (LinkTransformMap::const_iterator it = fixed_links.begin() ; it != fixed_links.end() ; ++it)
        {
          if (it->first->getName() == tip_local)
            return true;
        }
      }
    }
    else
      return true;
  }

  // Did not find any valid tip frame links to use
  return false;
}
bool planning_models::KinematicModel::addModelGroup(const planning_models::KinematicModel::GroupConfig& gc)
{
  if(joint_model_group_map_.find(gc.name_) != joint_model_group_map_.end()) {
    ROS_WARN_STREAM("Already have a model group named " << gc.name_ <<". Not adding.");
    return false;
  }
  std::vector<const JointModel*> jointv;
  std::vector<const JointModel*> fixed_jointv;
  if(!gc.tip_link_.empty() && !gc.base_link_.empty()) {
    if(!gc.subgroups_.empty()) {
      ROS_WARN_STREAM("Ignoring subgroups as tip and base are defined for group " << gc.name_);
    }
    //if this is not a physical robot link but is the world link
    bool base_link_is_world_link = (gc.base_link_ == getRoot()->getParentFrameId() &&
                                    getLinkModel(gc.base_link_) == NULL);
    const LinkModel* base_link = NULL;
    if(!base_link_is_world_link) {
      base_link = getLinkModel(gc.base_link_);
      if(base_link == NULL) {
        ROS_WARN_STREAM("Group config " << gc.name_ << " has invalid base link " << gc.base_link_);
        return false;
      }
    }
    const LinkModel* tip_link = getLinkModel(gc.tip_link_);
    if(tip_link == NULL) {
      ROS_WARN_STREAM("Group config " << gc.name_ << " has invalid tip link " << gc.tip_link_);
      return false;
    }
    const LinkModel* lm = tip_link;
    bool ok = false;
    while(true) {
      if(lm == NULL) {
        if(base_link_is_world_link) {
          ok = true;
        }
        break;
      }
      if(lm == base_link) {
        ok = true;
        break;
      }
      if(lm->getParentJointModel() == NULL) {
        break;
      }
      //only adding non-fixed joint models
      const FixedJointModel* fjm = dynamic_cast<const FixedJointModel*>(lm->getParentJointModel());
      if(fjm == NULL) {
        jointv.push_back(lm->getParentJointModel());
      } else {
        fixed_jointv.push_back(fjm);
      }
      lm = lm->getParentJointModel()->getParentLinkModel();
    }
    if(!ok) {
      ROS_WARN_STREAM("For group " << gc.name_ 
                      << " base link " << gc.base_link_ 
                      << " does not appear to be a direct descendent of " << gc.tip_link_);
      return false;
    }
    //need to reverse jointv to get things in right order
    std::reverse(jointv.begin(), jointv.end());
  } else {
    if(!gc.subgroups_.empty()) {
      std::set<const JointModel*> joint_set;
      for(unsigned int i = 0; i < gc.subgroups_.size(); i++) {
        if(joint_model_group_map_.find(gc.subgroups_[i]) == joint_model_group_map_.end()) {
          ROS_INFO_STREAM("Subgroup " << gc.subgroups_[i] << " not defined so can't add group " << gc.name_);
          return false;
        }
        const JointModelGroup* jmg = joint_model_group_map_.find(gc.subgroups_[i])->second;
        for(unsigned int j = 0; j < jmg->getJointModels().size(); j++) {
          joint_set.insert(jmg->getJointModels()[j]);
        }
      }
      for(std::set<const JointModel*>::iterator it = joint_set.begin();
          it != joint_set.end();
          it++) {
        jointv.push_back((*it));
      }
    }
    if(gc.joints_.size() == 0 && gc.subgroups_.empty()) {
      ROS_WARN_STREAM("Group " << gc.name_ << " must have tip/base links, subgroups, or one or more joints");
      return false;
    }
    for(unsigned int j = 0; j < gc.joints_.size(); j++) {
      const JointModel* joint = getJointModel(gc.joints_[j]);
      if(joint == NULL) {
        ROS_ERROR_STREAM("Group " << gc.name_ << " has invalid joint " << gc.joints_[j]);
        return false;
      }
      jointv.push_back(joint);
    }
  }
  if(jointv.size() == 0) {
    ROS_WARN_STREAM("Group " << gc.name_ << " must have at least one valid joint");
    return false;
  }
  joint_model_group_map_[gc.name_] = new JointModelGroup(gc.name_, jointv, fixed_jointv, this);
  joint_model_group_config_map_[gc.name_] = gc;
  return true;
}