Beispiel #1
0
bool moveit::core::JointModelGroup::computeIKIndexBijection(const std::vector<std::string> &ik_jnames, std::vector<unsigned int> &joint_bijection) const
{
  joint_bijection.clear();
  for (std::size_t i = 0 ; i < ik_jnames.size() ; ++i)
  {
    VariableIndexMap::const_iterator it = joint_variables_index_map_.find(ik_jnames[i]);
    if (it == joint_variables_index_map_.end())
    {
      // skip reported fixed joints
      if (hasJointModel(ik_jnames[i]) && getJointModel(ik_jnames[i])->getType() == JointModel::FIXED)
        continue;
      logError("IK solver computes joint values for joint '%s' but group '%s' does not contain such a joint.", ik_jnames[i].c_str(), getName().c_str());
      return false;
    }
    const JointModel *jm = getJointModel(ik_jnames[i]);
    for (unsigned int k = 0 ; k < jm->getVariableCount() ; ++k)
      joint_bijection.push_back(it->second + k);
  }
  return true;
}
const planning_models::KinematicModel::JointModel* planning_models::KinematicModel::JointModelGroup::getJointModel(const std::string &name)
{
  if(!hasJointModel(name)) return NULL;
  return joint_model_map_.find(name)->second;
}
Beispiel #3
0
moveit::core::JointModelGroup::JointModelGroup(const std::string& group_name,
                                               const srdf::Model::Group &config,
                                               const std::vector<const JointModel*> &unsorted_group_joints,
                                               const RobotModel* parent_model)
  : parent_model_(parent_model)
  , name_(group_name)
  , common_root_(NULL)
  , variable_count_(0)
  , is_contiguous_index_list_(true)
  , is_chain_(false)
  , is_single_dof_(true)
  , config_(config)
{
  // sort joints in Depth-First order
  joint_model_vector_ = unsorted_group_joints;
  std::sort(joint_model_vector_.begin(), joint_model_vector_.end(), OrderJointsByIndex());
  joint_model_name_vector_.reserve(joint_model_vector_.size());
  
  // figure out active joints, mimic joints, fixed joints
  // construct index maps, list of variables
  for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
  {
    joint_model_name_vector_.push_back(joint_model_vector_[i]->getName());
    joint_model_map_[joint_model_vector_[i]->getName()] = joint_model_vector_[i];
    unsigned int vc = joint_model_vector_[i]->getVariableCount();
    if (vc > 0)
    {
      if (vc > 1)
        is_single_dof_ = false;
      const std::vector<std::string>& name_order = joint_model_vector_[i]->getVariableNames();
      if (joint_model_vector_[i]->getMimic() == NULL)
      {
        active_joint_model_vector_.push_back(joint_model_vector_[i]);
        active_joint_model_name_vector_.push_back(joint_model_vector_[i]->getName());
        active_joint_model_start_index_.push_back(variable_count_);
        active_joint_models_bounds_.push_back(&joint_model_vector_[i]->getVariableBounds());
      }
      else
        mimic_joints_.push_back(joint_model_vector_[i]);
      for (std::size_t j = 0; j < name_order.size(); ++j)
      {
        variable_names_.push_back(name_order[j]);
        variable_names_set_.insert(name_order[j]);
      }
      
      int first_index = joint_model_vector_[i]->getFirstVariableIndex();
      for (std::size_t j = 0; j < name_order.size(); ++j)
      {
        variable_index_list_.push_back(first_index + j);
        joint_variables_index_map_[name_order[j]] = variable_count_ + j;
      }
      joint_variables_index_map_[joint_model_vector_[i]->getName()] = variable_count_;
      
      if (joint_model_vector_[i]->getType() == JointModel::REVOLUTE && 
          static_cast<const RevoluteJointModel*>(joint_model_vector_[i])->isContinuous())
        continuous_joint_model_vector_.push_back(joint_model_vector_[i]);

      variable_count_ += vc;
    }
    else
      fixed_joints_.push_back(joint_model_vector_[i]);
  }
  
  // now we need to find all the set of joints within this group
  // that root distinct subtrees
  for (std::size_t i = 0 ; i < active_joint_model_vector_.size() ; ++i)
  {
    // if we find that an ancestor is also in the group, then the joint is not a root
    if (!includesParent(active_joint_model_vector_[i], this))
      joint_roots_.push_back(active_joint_model_vector_[i]);
  }
  
  // when updating this group within a state, it is useful to know
  // if the full state of a group is contiguous within the full state of the robot
  if (variable_index_list_.empty())
    is_contiguous_index_list_ = false;
  else
    for (std::size_t i = 1 ; i < variable_index_list_.size() ; ++i)
      if (variable_index_list_[i] != variable_index_list_[i - 1] + 1)
      {
        is_contiguous_index_list_ = false;
        break;
      }

  // when updating/sampling a group state only, only mimic joints that have their parent within the group get updated.
  for (std::size_t i = 0 ; i < mimic_joints_.size() ; ++i)
    // if the joint we mimic is also in this group, we will need to do updates when sampling
    if (hasJointModel(mimic_joints_[i]->getMimic()->getName()))
    {
      int src = joint_variables_index_map_[mimic_joints_[i]->getMimic()->getName()];
      int dest = joint_variables_index_map_[mimic_joints_[i]->getName()];
      GroupMimicUpdate mu(src, dest, mimic_joints_[i]->getMimicFactor(), mimic_joints_[i]->getMimicOffset());
      group_mimic_update_.push_back(mu);
    }
  
  // now we need to make another pass for group links (we include the fixed joints here)
  std::set<const LinkModel*> group_links_set;
  for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
    group_links_set.insert(joint_model_vector_[i]->getChildLinkModel());
  for (std::set<const LinkModel*>::iterator it = group_links_set.begin(); it != group_links_set.end(); ++it)
    link_model_vector_.push_back(*it);
  std::sort(link_model_vector_.begin(), link_model_vector_.end(), OrderLinksByIndex());

  for (std::size_t i = 0 ; i < link_model_vector_.size() ; ++i)
  {
    link_model_map_[link_model_vector_[i]->getName()] = link_model_vector_[i];
    link_model_name_vector_.push_back(link_model_vector_[i]->getName());
    if (!link_model_vector_[i]->getShapes().empty())
    {
      link_model_with_geometry_vector_.push_back(link_model_vector_[i]);
      link_model_with_geometry_name_vector_.push_back(link_model_vector_[i]->getName());
    }
  }
  
  // compute the common root of this group
  if (!joint_roots_.empty())
  {
    common_root_ = joint_roots_[0];
    for (std::size_t i = 1 ; i < joint_roots_.size() ; ++i)
      common_root_ = parent_model->getCommonRoot(joint_roots_[i], common_root_);
  }
  
  // compute updated links
  for (std::size_t i = 0 ; i < joint_roots_.size() ; ++i)
  {
    const std::vector<const LinkModel*> &links = joint_roots_[i]->getDescendantLinkModels();
    updated_link_model_set_.insert(links.begin(), links.end());
  }
  for (std::set<const LinkModel*>::iterator it = updated_link_model_set_.begin(); it != updated_link_model_set_.end(); ++it)
  {
    updated_link_model_name_set_.insert((*it)->getName());
    updated_link_model_vector_.push_back(*it);
    if (!(*it)->getShapes().empty())
    {
      updated_link_model_with_geometry_vector_.push_back(*it);
      updated_link_model_with_geometry_set_.insert(*it);
      updated_link_model_with_geometry_name_set_.insert((*it)->getName());
    }
  }
  std::sort(updated_link_model_vector_.begin(), updated_link_model_vector_.end(), OrderLinksByIndex());
  std::sort(updated_link_model_with_geometry_vector_.begin(), updated_link_model_with_geometry_vector_.end(), OrderLinksByIndex());
  for (std::size_t i = 0; i < updated_link_model_vector_.size(); ++i)
    updated_link_model_name_vector_.push_back(updated_link_model_vector_[i]->getName());
  for (std::size_t i = 0; i < updated_link_model_with_geometry_vector_.size(); ++i)
    updated_link_model_with_geometry_name_vector_.push_back(updated_link_model_with_geometry_vector_[i]->getName());
  
  // check if this group should actually be a chain
  if (joint_roots_.size() == 1 && active_joint_model_vector_.size() > 1)
  {
    bool chain = true;
    // due to our sorting, the joints are sorted in a DF fashion, so looking at them in reverse, 
    // we should always get to the parent.    
    for (std::size_t k = joint_model_vector_.size() - 1 ; k > 0 ; --k)
      if (!jointPrecedes(joint_model_vector_[k], joint_model_vector_[k - 1]))
      {
        chain = false;
        break;
      }
    if (chain)
      is_chain_ = true;
  }
}
/* ------------------------ JointModelGroup ------------------------ */
planning_models::KinematicModel::JointModelGroup::JointModelGroup(const std::string& group_name,
                                                                  const std::vector<const JointModel*> &group_joints,
                                                                  const std::vector<const JointModel*> &fixed_group_joints,
                                                                  const KinematicModel* parent_model) :
  name_(group_name)
{
  ROS_DEBUG_STREAM("Group " << group_name);

  joint_model_vector_ = group_joints;
  fixed_joint_model_vector_ = fixed_group_joints;
  joint_model_name_vector_.resize(group_joints.size());

  ROS_DEBUG_STREAM("Joints:");    
  for (unsigned int i = 0 ; i < group_joints.size() ; ++i)
  {
    ROS_DEBUG_STREAM(group_joints[i]->getName());
    joint_model_name_vector_[i] = group_joints[i]->getName();
    joint_model_map_[group_joints[i]->getName()] = group_joints[i];
  }

  ROS_DEBUG_STREAM("Fixed joints:");    
  for (unsigned int i = 0 ; i < fixed_joint_model_vector_.size() ; ++i)
  {
    ROS_DEBUG_STREAM(fixed_joint_model_vector_[i]->getName());
  }

  std::vector<const JointModel*> all_joints = group_joints;
  all_joints.insert(all_joints.end(), fixed_group_joints.begin(), fixed_group_joints.end());

  //now we need to find all the set of joints within this group
  //that root distinct subtrees
  std::map<std::string, bool> is_root;
  for (unsigned int i = 0 ; i < all_joints.size() ; ++i)
  {
    bool found = false;
    const JointModel *joint = all_joints[i];
    //if we find that an ancestor is also in the group, then the joint is not a root
    while (joint->getParentLinkModel() != NULL)
    {
      joint = joint->getParentLinkModel()->getParentJointModel();
      if (hasJointModel(joint->name_))
      {
        found = true;
      }
    }
	
    if(!found) {
      joint_roots_.push_back(all_joints[i]);
      is_root[all_joints[i]->getName()] = true;
    } else {
      is_root[all_joints[i]->getName()] = false;
    }
  }

  //now we need to make another pass for group links
  std::set<const LinkModel*> group_links_set;
  for(unsigned int i = 0; i < all_joints.size(); i++) {
    const JointModel *joint = all_joints[i];
    //push children in directly
    group_links_set.insert(joint->getChildLinkModel());
    while (joint->getParentLinkModel() != NULL)
    {
      if(is_root.find(joint->getName()) != is_root.end() &&
         is_root[joint->getName()]) {
        break;
      }
      group_links_set.insert(joint->getParentLinkModel());
      joint = joint->getParentLinkModel()->getParentJointModel();
    }
  }

  ROS_DEBUG("Group links:");
  for(std::set<const LinkModel*>::iterator it = group_links_set.begin();
      it != group_links_set.end();
      it++) {
    group_link_model_vector_.push_back(*it);
    ROS_DEBUG_STREAM((*it)->getName());
  }
  //these subtrees are distinct, so we can stack their updated links on top of each other
  for (unsigned int i = 0 ; i < joint_roots_.size() ; ++i)
  {
    std::vector<const LinkModel*> links;
    parent_model->getChildLinkModels(joint_roots_[i], links);
    updated_link_model_vector_.insert(updated_link_model_vector_.end(), links.begin(), links.end());
  }
}