robot_model.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2013, Ioan A. Sucan
00005  *  Copyright (c) 2013, Willow Garage, Inc.
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/or other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the Willow Garage nor the names of its
00019  *     contributors may be used to endorse or promote products derived
00020  *     from this software without specific prior written permission.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  *  POSSIBILITY OF SUCH DAMAGE.
00034  *********************************************************************/
00035 
00036 /* Author: Ioan Sucan */
00037 
00038 #include <moveit/robot_model/robot_model.h>
00039 #include <geometric_shapes/shape_operations.h>
00040 #include <boost/math/constants/constants.hpp>
00041 #include <moveit/profiler/profiler.h>
00042 #include <algorithm>
00043 #include <limits>
00044 #include <queue>
00045 #include <cmath>
00046 #include "order_robot_model_items.inc"
00047 
00048 /* ------------------------ RobotModel ------------------------ */
00049 
00050 moveit::core::RobotModel::RobotModel(const boost::shared_ptr<const urdf::ModelInterface> &urdf_model,
00051                                      const boost::shared_ptr<const srdf::Model> &srdf_model)
00052 {
00053   root_joint_ = NULL;
00054   urdf_ = urdf_model;
00055   srdf_ = srdf_model;
00056   buildModel(*urdf_model, *srdf_model);
00057 }
00058 
00059 moveit::core::RobotModel::~RobotModel()
00060 {
00061   for (JointModelGroupMap::iterator it = joint_model_group_map_.begin() ; it != joint_model_group_map_.end() ; ++it)
00062     delete it->second;
00063   for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
00064     delete joint_model_vector_[i];
00065   for (std::size_t i = 0 ; i < link_model_vector_.size() ; ++i)
00066     delete link_model_vector_[i];
00067 }
00068 
00069 const moveit::core::JointModel* moveit::core::RobotModel::getRootJoint() const
00070 {
00071   return root_joint_;
00072 }
00073 
00074 const moveit::core::LinkModel* moveit::core::RobotModel::getRootLink() const
00075 {
00076   return root_link_;
00077 }
00078 
00079 void moveit::core::RobotModel::buildModel(const urdf::ModelInterface &urdf_model, const srdf::Model &srdf_model)
00080 {
00081   moveit::tools::Profiler::ScopedStart prof_start;
00082   moveit::tools::Profiler::ScopedBlock prof_block("RobotModel::buildModel");
00083 
00084   root_joint_ = NULL;
00085   root_link_ = NULL;
00086   link_geometry_count_ = 0;
00087   model_name_ = urdf_model.getName();
00088   logInform("Loading robot model '%s'...", model_name_.c_str());
00089   
00090   if (urdf_model.getRoot())
00091   {
00092     const urdf::Link *root_link_ptr = urdf_model.getRoot().get();
00093     model_frame_ = '/' + root_link_ptr->name;
00094     
00095     logDebug("... building kinematic chain"); 
00096     root_joint_ = buildRecursive(NULL, root_link_ptr, srdf_model);
00097     if (root_joint_)
00098       root_link_ = root_joint_->getChildLinkModel();
00099     logDebug("... building mimic joints"); 
00100     buildMimic(urdf_model);
00101 
00102     logDebug("... computing joint indexing"); 
00103     buildJointInfo();
00104 
00105     if (link_models_with_collision_geometry_vector_.empty())
00106       logWarn("No geometry is associated to any robot links");
00107 
00108     // build groups
00109 
00110     logDebug("... constructing joint groups"); 
00111     buildGroups(srdf_model);
00112 
00113     logDebug("... constructing joint group states"); 
00114     buildGroupStates(srdf_model);
00115 
00116     std::stringstream ss;
00117     printModelInfo(ss);
00118     logDebug("%s", ss.str().c_str());
00119   }
00120   else
00121     logWarn("No root link found");
00122 }
00123 
00124 namespace moveit
00125 {
00126 namespace core
00127 {
00128 namespace 
00129 {
00130 
00131 typedef std::map<const JointModel*, std::pair<std::set<const LinkModel*, OrderLinksByIndex>, std::set<const JointModel*, OrderJointsByIndex> > > DescMap;
00132 
00133 void computeDescendantsHelper(const JointModel *joint, std::vector<const JointModel*> &parents,
00134                               std::set<const JointModel*> &seen, DescMap &descendants)
00135 {
00136   if (!joint)
00137     return;
00138   if (seen.find(joint) != seen.end())
00139     return;
00140   seen.insert(joint);
00141   
00142   for (std::size_t i = 0 ; i < parents.size() ; ++i)
00143     descendants[parents[i]].second.insert(joint);
00144   
00145   const LinkModel *lm = joint->getChildLinkModel();
00146   if (!lm)
00147     return;
00148   
00149   for (std::size_t i = 0 ; i < parents.size() ; ++i)
00150     descendants[parents[i]].first.insert(lm);
00151   descendants[joint].first.insert(lm);
00152   
00153   parents.push_back(joint);
00154   const std::vector<const JointModel*> &ch = lm->getChildJointModels();
00155   for (std::size_t i = 0 ; i < ch.size() ; ++i)
00156     computeDescendantsHelper(ch[i], parents, seen, descendants);
00157   const std::vector<const JointModel*> &mim = joint->getMimicRequests();
00158   for (std::size_t i = 0 ; i < mim.size() ; ++i)
00159     computeDescendantsHelper(mim[i], parents, seen, descendants);
00160   parents.pop_back();
00161 }
00162 
00163 void computeCommonRootsHelper(const JointModel *joint, std::vector<int> &common_roots, int size)
00164 {
00165   if (!joint)
00166     return;
00167   const LinkModel *lm = joint->getChildLinkModel();
00168   if (!lm)
00169     return;
00170   
00171   const std::vector<const JointModel*> &ch = lm->getChildJointModels();
00172   for (std::size_t i = 0 ; i < ch.size() ; ++i)
00173   {
00174     const std::vector<const JointModel*> &a = ch[i]->getDescendantJointModels();
00175     for (std::size_t j = i + 1 ; j < ch.size() ; ++j)
00176     {
00177       const std::vector<const JointModel*> &b = ch[j]->getDescendantJointModels();
00178       for (std::size_t m = 0 ; m < b.size() ; ++m)
00179         common_roots[ch[i]->getJointIndex() * size + b[m]->getJointIndex()] = 
00180           common_roots[ch[i]->getJointIndex() + b[m]->getJointIndex() * size] = joint->getJointIndex();
00181       for (std::size_t k = 0 ; k < a.size() ; ++k)
00182       {
00183         common_roots[a[k]->getJointIndex() * size + ch[j]->getJointIndex()] = 
00184           common_roots[a[k]->getJointIndex() + ch[j]->getJointIndex() * size] = joint->getJointIndex();
00185         for (std::size_t m = 0 ; m < b.size() ; ++m)
00186           common_roots[a[k]->getJointIndex() * size + b[m]->getJointIndex()] = 
00187             common_roots[a[k]->getJointIndex() + b[m]->getJointIndex() * size] = joint->getJointIndex();
00188       }
00189     }
00190     computeCommonRootsHelper(ch[i], common_roots, size);
00191   }
00192 }
00193 
00194 }
00195 }
00196 }
00197 
00198 void moveit::core::RobotModel::computeCommonRoots()
00199 {
00200   // compute common roots for all pairs of joints; 
00201   // there are 3 cases of pairs (X, Y):
00202   //    X != Y && X and Y are not descendants of one another
00203   //    X == Y
00204   //    X != Y && X and Y are descendants of one another
00205   
00206   // by default, the common root is always the global root;
00207   common_joint_roots_.resize(joint_model_vector_.size() * joint_model_vector_.size(), 0);
00208   
00209   // look at all descendants recursively; for two sibling nodes A, B, both children of X, all the pairs of respective descendants of A and B
00210   // have X as the common root.
00211   computeCommonRootsHelper(root_joint_, common_joint_roots_, joint_model_vector_.size());
00212   
00213   for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
00214   {
00215     // the common root of a joint and itself is the same joint:
00216     common_joint_roots_[joint_model_vector_[i]->getJointIndex() * (1 + joint_model_vector_.size())] = joint_model_vector_[i]->getJointIndex();
00217     
00218     // a node N and one of its descendants have as common root the node N itself:
00219     const std::vector<const JointModel*> &d = joint_model_vector_[i]->getDescendantJointModels();
00220     for (std::size_t j = 0 ; j < d.size() ; ++j)
00221       common_joint_roots_[d[j]->getJointIndex() * joint_model_vector_.size() + joint_model_vector_[i]->getJointIndex()] = 
00222         common_joint_roots_[d[j]->getJointIndex() + joint_model_vector_[i]->getJointIndex() * joint_model_vector_.size()] = joint_model_vector_[i]->getJointIndex();
00223   }  
00224 }
00225 
00226 void moveit::core::RobotModel::computeDescendants()
00227 {
00228   // compute the list of descendants for all joints
00229   std::vector<const JointModel*> parents;
00230   std::set<const JointModel*> seen;
00231   
00232   DescMap descendants;
00233   computeDescendantsHelper(root_joint_, parents, seen, descendants);
00234   for (DescMap::iterator it = descendants.begin() ; it != descendants.end() ; ++it)
00235   {
00236     JointModel *jm = const_cast<JointModel*>(it->first);
00237     for (std::set<const JointModel*>::const_iterator jt = it->second.second.begin() ; jt != it->second.second.end() ; ++jt)
00238       jm->addDescendantJointModel(*jt);
00239     for (std::set<const LinkModel*>::const_iterator jt = it->second.first.begin() ; jt != it->second.first.end() ; ++jt)
00240       jm->addDescendantLinkModel(*jt);
00241   }
00242 }
00243 
00244 void moveit::core::RobotModel::buildJointInfo()
00245 {
00246   moveit::tools::Profiler::ScopedStart prof_start;
00247   moveit::tools::Profiler::ScopedBlock prof_block("RobotModel::buildJointInfo");
00248 
00249   // construct additional maps for easy access by name
00250   variable_count_ = 0;
00251   active_joint_model_start_index_.reserve(joint_model_vector_.size());
00252   variable_names_.reserve(joint_model_vector_.size());
00253   joints_of_variable_.reserve(joint_model_vector_.size());
00254   
00255   for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
00256   {
00257     joint_model_vector_[i]->setJointIndex(i);
00258     const std::vector<std::string> &name_order = joint_model_vector_[i]->getVariableNames();
00259     
00260     // compute index map
00261     if (!name_order.empty())
00262     {
00263       for (std::size_t j = 0; j < name_order.size(); ++j)
00264       {
00265         joint_variables_index_map_[name_order[j]] = variable_count_ + j;
00266         variable_names_.push_back(name_order[j]);
00267         joints_of_variable_.push_back(joint_model_vector_[i]);
00268       }
00269       if (joint_model_vector_[i]->getMimic() == NULL)
00270       {
00271         active_joint_model_start_index_.push_back(variable_count_);
00272         active_joint_model_vector_.push_back(joint_model_vector_[i]);
00273         active_joint_model_vector_const_.push_back(joint_model_vector_[i]);
00274         active_joint_models_bounds_.push_back(&joint_model_vector_[i]->getVariableBounds());
00275       }
00276 
00277       if (joint_model_vector_[i]->getType() == JointModel::REVOLUTE && static_cast<const RevoluteJointModel*>(joint_model_vector_[i])->isContinuous())
00278         continuous_joint_model_vector_.push_back(joint_model_vector_[i]);
00279 
00280       joint_model_vector_[i]->setFirstVariableIndex(variable_count_);
00281       joint_variables_index_map_[joint_model_vector_[i]->getName()] = variable_count_;
00282       
00283       // compute variable count
00284       std::size_t vc = joint_model_vector_[i]->getVariableCount();
00285       variable_count_ += vc;
00286       if (vc == 1)
00287         single_dof_joints_.push_back(joint_model_vector_[i]);
00288       else
00289         multi_dof_joints_.push_back(joint_model_vector_[i]);
00290     }
00291   }
00292   
00293   for (std::size_t i = 0 ; i < link_model_vector_.size() ; ++i)
00294   {
00295     LinkTransformMap associated_transforms;
00296     computeFixedTransforms(link_model_vector_[i],  link_model_vector_[i]->getJointOriginTransform().inverse() , associated_transforms);
00297     if (associated_transforms.size() > 1)
00298     {
00299       for (LinkTransformMap::iterator it = associated_transforms.begin() ; it != associated_transforms.end() ; ++it)
00300         if (it->first != link_model_vector_[i])
00301         {
00302           getLinkModel(it->first->getName())->addAssociatedFixedTransform(link_model_vector_[i], it->second.inverse());
00303           link_model_vector_[i]->addAssociatedFixedTransform(it->first, it->second);
00304         }
00305     }
00306   }
00307 
00308   computeDescendants();
00309   computeCommonRoots(); // must be called _after_ list of descendants was computed
00310 }
00311 
00312 void moveit::core::RobotModel::buildGroupStates(const srdf::Model &srdf_model)
00313 {
00314   // copy the default states to the groups
00315   const std::vector<srdf::Model::GroupState> &ds = srdf_model.getGroupStates();
00316   for (std::size_t i = 0 ; i < ds.size() ; ++i)
00317   {
00318     if (hasJointModelGroup(ds[i].group_))
00319     {
00320       JointModelGroup *jmg = getJointModelGroup(ds[i].group_);
00321       std::map<std::string, double> state;
00322       for (std::map<std::string, std::vector<double> >::const_iterator jt = ds[i].joint_values_.begin() ; jt != ds[i].joint_values_.end() ; ++jt)
00323       {
00324         if (jmg->hasJointModel(jt->first))
00325         {
00326           const JointModel* jm = jmg->getJointModel(jt->first);
00327           const std::vector<std::string> &vn = jm->getVariableNames();
00328           if (vn.size() == jt->second.size())
00329             for (std::size_t j = 0 ; j < vn.size() ; ++j)
00330               state[vn[j]] = jt->second[j];
00331           else
00332             logError("The model for joint '%s' requires %d variable values, but only %d variable values were supplied in default state '%s' for group '%s'",
00333                      jt->first.c_str(), (int)vn.size(), (int)jt->second.size(), ds[i].name_.c_str(), jmg->getName().c_str());
00334         }
00335         else
00336           logError("Group state '%s' specifies value for joint '%s', but that joint is not part of group '%s'", ds[i].name_.c_str(),
00337                    jt->first.c_str(), jmg->getName().c_str());
00338       }
00339       if (!state.empty())
00340         jmg->addDefaultState(ds[i].name_, state);
00341     }
00342     else
00343       logError("Group state '%s' specified for group '%s', but that group does not exist", ds[i].name_.c_str(), ds[i].group_.c_str());
00344   }
00345 }
00346 
00347 void moveit::core::RobotModel::buildMimic(const urdf::ModelInterface &urdf_model)
00348 {
00349   // compute mimic joints
00350   for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
00351   {
00352     const urdf::Joint *jm = urdf_model.getJoint(joint_model_vector_[i]->getName()).get();
00353     if (jm)
00354       if (jm->mimic)
00355       {
00356         JointModelMap::const_iterator jit = joint_model_map_.find(jm->mimic->joint_name);
00357         if (jit != joint_model_map_.end())
00358         {
00359           if (joint_model_vector_[i]->getVariableCount() == jit->second->getVariableCount())
00360             joint_model_vector_[i]->setMimic(jit->second, jm->mimic->multiplier, jm->mimic->offset);
00361           else
00362             logError("Join '%s' cannot mimic joint '%s' because they have different number of DOF",
00363                      joint_model_vector_[i]->getName().c_str(), jm->mimic->joint_name.c_str());
00364         }
00365         else
00366           logError("Joint '%s' cannot mimic unknown joint '%s'", joint_model_vector_[i]->getName().c_str(), jm->mimic->joint_name.c_str());
00367       }
00368   }
00369   
00370   // in case we have a joint that mimics a joint that already mimics another joint, we can simplify things:
00371   bool change = true;
00372   while (change)
00373   {
00374     change = false;
00375     for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
00376       if (joint_model_vector_[i]->getMimic())
00377       {
00378         if (joint_model_vector_[i]->getMimic()->getMimic())
00379         {
00380           joint_model_vector_[i]->setMimic(joint_model_vector_[i]->getMimic()->getMimic(),
00381                                            joint_model_vector_[i]->getMimicFactor() * joint_model_vector_[i]->getMimic()->getMimicFactor(),
00382                                            joint_model_vector_[i]->getMimicOffset() + 
00383                                            joint_model_vector_[i]->getMimicFactor() * joint_model_vector_[i]->getMimic()->getMimicOffset());
00384           change = true;
00385         }
00386         if (joint_model_vector_[i] == joint_model_vector_[i]->getMimic())
00387         {
00388           logError("Cycle found in joint that mimic each other. Ignoring all mimic joints.");
00389           for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
00390             joint_model_vector_[i]->setMimic(NULL, 0.0, 0.0);
00391           change = false;
00392           break;
00393         }
00394       }
00395   }
00396   // build mimic requests
00397   for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
00398     if (joint_model_vector_[i]->getMimic())
00399     {
00400       const_cast<JointModel*>(joint_model_vector_[i]->getMimic())->addMimicRequest(joint_model_vector_[i]);
00401       mimic_joints_.push_back(joint_model_vector_[i]);
00402     }
00403 }
00404 
00405 bool moveit::core::RobotModel::hasEndEffector(const std::string& eef) const
00406 {
00407   return end_effectors_map_.find(eef) != end_effectors_map_.end();
00408 }
00409 
00410 const moveit::core::JointModelGroup* moveit::core::RobotModel::getEndEffector(const std::string& name) const
00411 {
00412   JointModelGroupMap::const_iterator it = end_effectors_map_.find(name);
00413   if (it == end_effectors_map_.end())
00414   {
00415     it = joint_model_group_map_.find(name);
00416     if (it != joint_model_group_map_.end() && it->second->isEndEffector())
00417       return it->second;
00418     logError("End-effector '%s' not found in model '%s'", name.c_str(), model_name_.c_str());
00419     return NULL;
00420   }
00421   return it->second;
00422 }
00423 
00424 moveit::core::JointModelGroup* moveit::core::RobotModel::getEndEffector(const std::string& name)
00425 {
00426   JointModelGroupMap::const_iterator it = end_effectors_map_.find(name);
00427   if (it == end_effectors_map_.end())
00428   {
00429     it = joint_model_group_map_.find(name);
00430     if (it != joint_model_group_map_.end() && it->second->isEndEffector())
00431       return it->second;
00432     logError("End-effector '%s' not found in model '%s'", name.c_str(), model_name_.c_str());
00433     return NULL;
00434   }
00435   return it->second;
00436 }
00437 
00438 bool moveit::core::RobotModel::hasJointModelGroup(const std::string &name) const
00439 {
00440   return joint_model_group_map_.find(name) != joint_model_group_map_.end();
00441 }
00442 
00443 const moveit::core::JointModelGroup* moveit::core::RobotModel::getJointModelGroup(const std::string& name) const
00444 {
00445   JointModelGroupMap::const_iterator it = joint_model_group_map_.find(name);
00446   if (it == joint_model_group_map_.end())
00447   {
00448     logError("Group '%s' not found in model '%s'", name.c_str(), model_name_.c_str());
00449     return NULL;
00450   }
00451   return it->second;
00452 }
00453 
00454 moveit::core::JointModelGroup* moveit::core::RobotModel::getJointModelGroup(const std::string& name)
00455 {
00456   JointModelGroupMap::const_iterator it = joint_model_group_map_.find(name);
00457   if (it == joint_model_group_map_.end())
00458   {    
00459     logError("Group '%s' not found in model '%s'", name.c_str(), model_name_.c_str());
00460     return NULL;
00461   }
00462   return it->second;
00463 }
00464 
00465 void moveit::core::RobotModel::buildGroups(const srdf::Model &srdf_model)
00466 {
00467   const std::vector<srdf::Model::Group>& group_configs = srdf_model.getGroups();
00468 
00469   //the only thing tricky is dealing with subgroups
00470   std::vector<bool> processed(group_configs.size(), false);
00471 
00472   bool added = true;
00473   while (added)
00474   {
00475     added = false;
00476 
00477     //going to make passes until we can't do anything else
00478     for (std::size_t i = 0 ; i < group_configs.size() ; ++i)
00479       if (!processed[i])
00480       {
00481         //if we haven't processed, check and see if the dependencies are met yet
00482         bool all_subgroups_added = true;
00483         for (std::size_t j = 0; j < group_configs[i].subgroups_.size(); ++j)
00484           if (joint_model_group_map_.find(group_configs[i].subgroups_[j]) == joint_model_group_map_.end())
00485           {
00486             all_subgroups_added = false;
00487             break;
00488           }
00489         if (all_subgroups_added)
00490         {
00491           added = true;
00492           processed[i] = true;
00493           if (!addJointModelGroup(group_configs[i]))
00494             logWarn("Failed to add group '%s'", group_configs[i].name_.c_str());
00495         }
00496       }
00497   }
00498 
00499   for (std::size_t i = 0 ; i < processed.size() ; ++i)
00500     if (!processed[i])
00501       logWarn("Could not process group '%s' due to unmet subgroup dependencies", group_configs[i].name_.c_str());
00502   
00503   for (JointModelGroupMap::const_iterator it = joint_model_group_map_.begin() ; it != joint_model_group_map_.end(); ++it)
00504     joint_model_groups_.push_back(it->second);
00505   std::sort(joint_model_groups_.begin(), joint_model_groups_.end(), OrderGroupsByName());
00506   for (std::size_t i = 0 ; i < joint_model_groups_.size() ; ++i)
00507   {
00508     joint_model_groups_const_.push_back(joint_model_groups_[i]);
00509     joint_model_group_names_.push_back(joint_model_groups_[i]->getName());
00510   }
00511   
00512   buildGroupsInfo_Subgroups(srdf_model);
00513   buildGroupsInfo_EndEffectors(srdf_model);
00514 }
00515 
00516 void moveit::core::RobotModel::buildGroupsInfo_Subgroups(const srdf::Model &srdf_model)
00517 {
00518   // compute subgroups
00519   for (JointModelGroupMap::const_iterator it = joint_model_group_map_.begin() ; it != joint_model_group_map_.end(); ++it)
00520   {
00521     JointModelGroup *jmg = it->second;
00522     std::vector<std::string> subgroup_names;
00523     std::set<const JointModel*> joints(jmg->getJointModels().begin(), jmg->getJointModels().end());
00524     for (JointModelGroupMap::const_iterator jt = joint_model_group_map_.begin() ; jt != joint_model_group_map_.end(); ++jt)
00525       if (jt->first != it->first)
00526       {
00527         bool ok = true;
00528         JointModelGroup *sub_jmg = jt->second;
00529         const std::vector<const JointModel*> &sub_joints = sub_jmg->getJointModels();
00530         for (std::size_t k = 0 ; k < sub_joints.size() ; ++k)
00531           if (joints.find(sub_joints[k]) == joints.end())
00532           {
00533             ok = false;
00534             break;
00535           }
00536         if (ok)
00537           subgroup_names.push_back(sub_jmg->getName());
00538       }
00539     if (!subgroup_names.empty())
00540       jmg->setSubgroupNames(subgroup_names);
00541   }
00542 }
00543 
00544 void moveit::core::RobotModel::buildGroupsInfo_EndEffectors(const srdf::Model &srdf_model)
00545 {
00546   // set the end-effector flags
00547   const std::vector<srdf::Model::EndEffector> &eefs = srdf_model.getEndEffectors();
00548   for (JointModelGroupMap::const_iterator it = joint_model_group_map_.begin() ; it != joint_model_group_map_.end(); ++it)
00549   {
00550     // check if this group is a known end effector
00551     for (std::size_t k = 0 ; k < eefs.size() ; ++k)
00552       if (eefs[k].component_group_ == it->first)
00553       {
00554         // if it is, mark it as such        
00555         it->second->setEndEffectorName(eefs[k].name_);
00556         end_effectors_map_[eefs[k].name_] = it->second;
00557         end_effectors_.push_back(it->second);
00558         
00559         // check to see if there are groups that contain the parent link of this end effector.
00560         // record this information if found; 
00561         std::vector<JointModelGroup*> possible_parent_groups;
00562         for (JointModelGroupMap::const_iterator jt = joint_model_group_map_.begin() ; jt != joint_model_group_map_.end(); ++jt)
00563           if (jt->first != it->first)
00564           {
00565             if (jt->second->hasLinkModel(eefs[k].parent_link_))
00566             {
00567               jt->second->attachEndEffector(eefs[k].name_);
00568               possible_parent_groups.push_back(jt->second);
00569             }
00570           }
00571         
00572         JointModelGroup *eef_parent_group = NULL;
00573         // if a parent group is specified in SRDF, try to use it
00574         if (!eefs[k].parent_group_.empty())
00575         {
00576           JointModelGroupMap::const_iterator jt = joint_model_group_map_.find(eefs[k].parent_group_);
00577           if (jt != joint_model_group_map_.end())
00578           {
00579             if (jt->second->hasLinkModel(eefs[k].parent_link_))
00580             {
00581               if (jt->second != it->second)
00582                 eef_parent_group = jt->second;
00583               else
00584                 logError("Group '%s' for end-effector '%s' cannot be its own parent", eefs[k].parent_group_.c_str(), eefs[k].name_.c_str());
00585             }
00586             else
00587               logError("Group '%s' was specified as parent group for end-effector '%s' but it does not include the parent link '%s'",
00588                        eefs[k].parent_group_.c_str(), eefs[k].name_.c_str(), eefs[k].parent_link_.c_str());
00589           }
00590           else
00591             logError("Group name '%s' not found (specified as parent group for end-effector '%s')",
00592                      eefs[k].parent_group_.c_str(), eefs[k].name_.c_str());
00593         }
00594 
00595         // if no parent group was specified, use a default one
00596         if (eef_parent_group == NULL)
00597           if (!possible_parent_groups.empty())
00598           {
00599             // if there are multiple options for the group that contains this end-effector,
00600             // we pick the group with fewest joints.
00601             std::size_t best = 0;
00602             for (std::size_t g = 1 ; g < possible_parent_groups.size() ; ++g)
00603               if (possible_parent_groups[g]->getJointModels().size() < possible_parent_groups[best]->getJointModels().size())
00604                 best = g;
00605             eef_parent_group = possible_parent_groups[best];
00606           }
00607         
00608         if (eef_parent_group)
00609         {
00610           it->second->setEndEffectorParent(eef_parent_group->getName(), eefs[k].parent_link_);
00611         }
00612         else
00613         {
00614           logWarn("Could not identify parent group for end-effector '%s'", eefs[k].name_.c_str());
00615           it->second->setEndEffectorParent("", eefs[k].parent_link_);
00616         }
00617         break;
00618       }
00619   }
00620   std::sort(end_effectors_.begin(), end_effectors_.end(), OrderGroupsByName());
00621 }
00622 
00623 bool moveit::core::RobotModel::addJointModelGroup(const srdf::Model::Group& gc)
00624 {
00625   if (joint_model_group_map_.find(gc.name_) != joint_model_group_map_.end())
00626   {
00627     logWarn("A group named '%s' already exists. Not adding.",  gc.name_.c_str());
00628     return false;
00629   }
00630 
00631   std::set<const JointModel*> jset;
00632 
00633   // add joints from chains
00634   for (std::size_t i = 0 ; i < gc.chains_.size() ; ++i)
00635   {
00636     const LinkModel* base_link = getLinkModel(gc.chains_[i].first);
00637     const LinkModel* tip_link = getLinkModel(gc.chains_[i].second);
00638     if (base_link && tip_link)
00639     {
00640       // go from tip, up the chain, until we hit the root or we find the base_link
00641       const LinkModel* lm = tip_link;
00642       std::vector<const JointModel*> cj;
00643       while (lm)
00644       {
00645         if (lm == base_link)
00646           break;
00647         cj.push_back(lm->getParentJointModel());
00648         lm = lm->getParentJointModel()->getParentLinkModel();
00649       }
00650       // if we did not find the base_link, we could have a chain like e.g.,
00651       // from one end-effector to another end-effector, so the root is in between
00652       if (lm != base_link)
00653       {
00654         // we go up the chain from the base this time, and see where we intersect the other chain
00655         lm = base_link;
00656         std::size_t index = 0;
00657         std::vector<const JointModel*> cj2;
00658         while (lm)
00659         {
00660           for (std::size_t j = 0 ; j < cj.size() ; ++j)
00661             if (cj[j] == lm->getParentJointModel())
00662             {
00663               index = j + 1;
00664               break;
00665             }
00666           if (index > 0)
00667             break;
00668           cj2.push_back(lm->getParentJointModel());
00669           lm = lm->getParentJointModel()->getParentLinkModel();
00670         }
00671         if (index > 0)
00672         {
00673           jset.insert(cj.begin(), cj.begin() + index);
00674           jset.insert(cj2.begin(), cj2.end());
00675         }
00676       }
00677       else
00678         // if we have a simple chain, just add the joints
00679         jset.insert(cj.begin(), cj.end());
00680     }
00681   }
00682 
00683   // add joints
00684   for (std::size_t i = 0 ; i < gc.joints_.size() ; ++i)
00685   {
00686     const JointModel *j = getJointModel(gc.joints_[i]);
00687     if (j)
00688       jset.insert(j);
00689   }
00690 
00691   // add joints that are parents of included links
00692   for (std::size_t i = 0 ; i < gc.links_.size() ; ++i)
00693   {
00694     const LinkModel *l = getLinkModel(gc.links_[i]);
00695     if (l)
00696       jset.insert(l->getParentJointModel());
00697   }
00698 
00699   // add joints from subgroups
00700   for (std::size_t i = 0 ; i < gc.subgroups_.size() ; ++i)
00701   {
00702     const JointModelGroup *sg = getJointModelGroup(gc.subgroups_[i]);
00703     if (sg)
00704     {
00705       //active joints
00706       const std::vector<const JointModel*> &js = sg->getJointModels();
00707       for (std::size_t j = 0 ; j < js.size() ; ++j)
00708         jset.insert(js[j]);
00709 
00710       //fixed joints
00711       const std::vector<const JointModel*> &fs = sg->getFixedJointModels();
00712       for (std::size_t j = 0 ; j < fs.size() ; ++j)
00713         jset.insert(fs[j]);
00714 
00715       //mimic joints
00716       const std::vector<const JointModel*> &ms = sg->getMimicJointModels();
00717       for (std::size_t j = 0 ; j < ms.size() ; ++j)
00718         jset.insert(ms[j]);
00719     }
00720   }
00721 
00722   if (jset.empty())
00723   {
00724     logWarn("Group '%s' must have at least one valid joint", gc.name_.c_str());
00725     return false;
00726   }
00727 
00728   std::vector<const JointModel*> joints;
00729   for (std::set<const JointModel*>::iterator it = jset.begin() ; it != jset.end() ; ++it)
00730     joints.push_back(*it);
00731 
00732   JointModelGroup *jmg = new JointModelGroup(gc.name_, gc, joints, this);
00733   joint_model_group_map_[gc.name_] = jmg;
00734   
00735   return true;
00736 }
00737 
00738 moveit::core::JointModel* moveit::core::RobotModel::buildRecursive(LinkModel *parent, const urdf::Link *urdf_link,
00739                                                                    const srdf::Model &srdf_model)
00740 {
00741   // construct the joint
00742   JointModel *joint = urdf_link->parent_joint ?
00743     constructJointModel(urdf_link->parent_joint.get(), urdf_link, srdf_model) :
00744     constructJointModel(NULL, urdf_link, srdf_model);
00745   if (joint == NULL)
00746     return NULL;
00747   
00748   // bookkeeping for the joint
00749   joint_model_map_[joint->getName()] = joint;
00750   joint->setJointIndex(joint_model_vector_.size());
00751   joint_model_vector_.push_back(joint);
00752   joint_model_vector_const_.push_back(joint);
00753   joint_model_names_vector_.push_back(joint->getName());
00754   joint->setParentLinkModel(parent);
00755 
00756   // construct the link
00757   LinkModel *link = constructLinkModel(urdf_link);
00758   joint->setChildLinkModel(link);
00759   link->setParentLinkModel(parent);
00760   
00761   // bookkeeping for the link
00762   link_model_map_[joint->getChildLinkModel()->getName()] = link;
00763   link->setLinkIndex(link_model_vector_.size());
00764   link_model_vector_.push_back(link);
00765   link_model_vector_const_.push_back(link);
00766   link_model_names_vector_.push_back(link->getName());
00767   if (!link->getShapes().empty())
00768   {
00769     link_models_with_collision_geometry_vector_.push_back(link);
00770     link_model_names_with_collision_geometry_vector_.push_back(link->getName());
00771     link->setFirstCollisionBodyTransformIndex(link_geometry_count_);
00772     link_geometry_count_ += link->getShapes().size();
00773   }
00774   link->setParentJointModel(joint);
00775 
00776   // recursively build child links (and joints)
00777   for (std::size_t i = 0 ; i < urdf_link->child_links.size() ; ++i)
00778   {
00779     JointModel* jm = buildRecursive(link, urdf_link->child_links[i].get(), srdf_model);
00780     if (jm)
00781       link->addChildJointModel(jm);
00782   }
00783   return joint;
00784 }
00785 
00786 namespace
00787 {
00788 // construct bounds for 1DOF joint
00789 static inline moveit::core::VariableBounds jointBoundsFromURDF(const urdf::Joint *urdf_joint)
00790 {
00791   moveit::core::VariableBounds b;
00792   if (urdf_joint->safety)
00793   {
00794     b.position_bounded_ = true;
00795     b.min_position_ = urdf_joint->safety->soft_lower_limit;
00796     b.max_position_ = urdf_joint->safety->soft_upper_limit;
00797     if (urdf_joint->limits)
00798     {
00799       if (urdf_joint->limits->lower > b.min_position_)
00800         b.min_position_ = urdf_joint->limits->lower;
00801       if (urdf_joint->limits->upper < b.max_position_)
00802         b.max_position_ = urdf_joint->limits->upper;
00803     }
00804   }
00805   else
00806   {
00807     if (urdf_joint->limits)
00808     {
00809       b.position_bounded_ = true;
00810       b.min_position_ = urdf_joint->limits->lower;
00811       b.max_position_ = urdf_joint->limits->upper;
00812     }
00813   }
00814   if (urdf_joint->limits)
00815   {
00816     b.max_velocity_ = fabs(urdf_joint->limits->velocity);
00817     b.min_velocity_ = -b.max_velocity_;
00818     b.velocity_bounded_ = b.max_velocity_ > std::numeric_limits<double>::epsilon();
00819   }
00820   return b;
00821 }
00822 }
00823 
00824 moveit::core::JointModel* moveit::core::RobotModel::constructJointModel(const urdf::Joint *urdf_joint, const urdf::Link *child_link,
00825                                                                         const srdf::Model &srdf_model)
00826 {
00827   JointModel* result = NULL;
00828 
00829   // must be the root link transform
00830   if (urdf_joint)
00831   {
00832     switch (urdf_joint->type)
00833     {
00834     case urdf::Joint::REVOLUTE:
00835       {
00836         RevoluteJointModel *j = new RevoluteJointModel(urdf_joint->name);
00837         j->setVariableBounds(j->getName(), jointBoundsFromURDF(urdf_joint));
00838         j->setContinuous(false);
00839         j->setAxis(Eigen::Vector3d(urdf_joint->axis.x, urdf_joint->axis.y, urdf_joint->axis.z));
00840         result = j;
00841       }
00842       break;
00843     case urdf::Joint::CONTINUOUS:
00844       {
00845         RevoluteJointModel *j = new RevoluteJointModel(urdf_joint->name);
00846         j->setVariableBounds(j->getName(), jointBoundsFromURDF(urdf_joint));
00847         j->setContinuous(true);
00848         j->setAxis(Eigen::Vector3d(urdf_joint->axis.x, urdf_joint->axis.y, urdf_joint->axis.z));
00849         result = j;
00850       }
00851       break;
00852     case urdf::Joint::PRISMATIC:
00853       {
00854         PrismaticJointModel *j = new PrismaticJointModel(urdf_joint->name);
00855         j->setVariableBounds(j->getName(), jointBoundsFromURDF(urdf_joint));
00856         j->setAxis(Eigen::Vector3d(urdf_joint->axis.x, urdf_joint->axis.y, urdf_joint->axis.z));
00857         result = j;
00858       }
00859       break;
00860     case urdf::Joint::FLOATING:
00861       result = new FloatingJointModel(urdf_joint->name);
00862       break;
00863     case urdf::Joint::PLANAR:
00864       result = new PlanarJointModel(urdf_joint->name);
00865       break;
00866     case urdf::Joint::FIXED:
00867       result = new FixedJointModel(urdf_joint->name);
00868       break;
00869     default:
00870       logError("Unknown joint type: %d", (int)urdf_joint->type);
00871       break;
00872     }
00873   }
00874   else
00875   {
00876     const std::vector<srdf::Model::VirtualJoint> &vjoints = srdf_model.getVirtualJoints();
00877     for (std::size_t i = 0 ; i < vjoints.size() ; ++i)
00878       if (vjoints[i].child_link_ == child_link->name && !vjoints[i].parent_frame_.empty())
00879       {
00880         if (vjoints[i].type_ == "fixed")
00881           result = new FixedJointModel(vjoints[i].name_);
00882         else if (vjoints[i].type_ == "planar")
00883           result = new PlanarJointModel(vjoints[i].name_);
00884         else if (vjoints[i].type_ == "floating")
00885           result = new FloatingJointModel(vjoints[i].name_);
00886         if (result)
00887         {
00888           // for fixed frames we still use the robot root link
00889           if (vjoints[i].type_ != "fixed")
00890           {
00891             model_frame_ = vjoints[i].parent_frame_;
00892             if (model_frame_[0] != '/')
00893               model_frame_ = '/' + model_frame_;
00894           }
00895           break;
00896         }
00897       }
00898     if (!result)
00899     {
00900       logInform("No root joint specified. Assuming fixed joint");
00901       result = new FixedJointModel("ASSUMED_FIXED_ROOT_JOINT");
00902     }
00903   }
00904 
00905   if (result)
00906   {
00907     result->setDistanceFactor(result->getStateSpaceDimension());
00908     const std::vector<srdf::Model::PassiveJoint> &pjoints = srdf_model.getPassiveJoints();
00909     for (std::size_t i = 0 ; i < pjoints.size() ; ++i)
00910     {
00911       if (result->getName() == pjoints[i].name_)
00912       {
00913         result->setPassive(true);
00914         break;
00915       }
00916     }
00917   }
00918   
00919   return result;
00920 }
00921 
00922 namespace 
00923 {
00924 static inline Eigen::Affine3d urdfPose2Affine3d(const urdf::Pose &pose)
00925 {
00926   Eigen::Quaterniond q(pose.rotation.w, pose.rotation.x, pose.rotation.y, pose.rotation.z);
00927   Eigen::Affine3d af(Eigen::Translation3d(pose.position.x, pose.position.y, pose.position.z)*q.toRotationMatrix());
00928   return af;
00929 }
00930 
00931 }
00932 
00933 moveit::core::LinkModel* moveit::core::RobotModel::constructLinkModel(const urdf::Link *urdf_link)
00934 {
00935   LinkModel *result = new LinkModel(urdf_link->name);
00936 
00937   const std::vector<boost::shared_ptr<urdf::Collision> > &col_array = urdf_link->collision_array.empty() ? 
00938     std::vector<boost::shared_ptr<urdf::Collision> >(1, urdf_link->collision) : urdf_link->collision_array;
00939   
00940   std::vector<shapes::ShapeConstPtr> shapes;
00941   EigenSTL::vector_Affine3d poses;
00942   
00943   for (std::size_t i = 0 ; i < col_array.size() ; ++i)
00944     if (col_array[i] && col_array[i]->geometry)
00945     {
00946       shapes::ShapeConstPtr s = constructShape(col_array[i]->geometry.get());
00947       if (s)
00948       {
00949         shapes.push_back(s);
00950         poses.push_back(urdfPose2Affine3d(col_array[i]->origin));
00951       }
00952     }
00953   if (shapes.empty())
00954   {
00955     const std::vector<boost::shared_ptr<urdf::Visual> > &vis_array = urdf_link->visual_array.empty() ? 
00956       std::vector<boost::shared_ptr<urdf::Visual> >(1, urdf_link->visual) : urdf_link->visual_array;
00957     for (std::size_t i = 0 ; i < vis_array.size() ; ++i)
00958       if (vis_array[i] && vis_array[i]->geometry)
00959       {
00960         shapes::ShapeConstPtr s = constructShape(vis_array[i]->geometry.get());
00961         if (s)
00962         {
00963           shapes.push_back(s);
00964           poses.push_back(urdfPose2Affine3d(vis_array[i]->origin));
00965         }
00966       }
00967   }
00968 
00969   result->setGeometry(shapes, poses);
00970   
00971   // figure out visual mesh (try visual urdf tag first, collision tag otherwise
00972   if (urdf_link->visual && urdf_link->visual->geometry)
00973   {
00974     if (urdf_link->visual->geometry->type == urdf::Geometry::MESH)
00975     {
00976       const urdf::Mesh *mesh = static_cast<const urdf::Mesh*>(urdf_link->visual->geometry.get());
00977       if (!mesh->filename.empty())
00978         result->setVisualMesh(mesh->filename, urdfPose2Affine3d(urdf_link->visual->origin),
00979                               Eigen::Vector3d(mesh->scale.x, mesh->scale.y, mesh->scale.z));
00980     }
00981   }
00982   else
00983     if (urdf_link->collision && urdf_link->collision->geometry)
00984     {
00985       if (urdf_link->collision->geometry->type == urdf::Geometry::MESH)
00986       {
00987         const urdf::Mesh *mesh = static_cast<const urdf::Mesh*>(urdf_link->collision->geometry.get()); 
00988         if (!mesh->filename.empty())
00989           result->setVisualMesh(mesh->filename, urdfPose2Affine3d(urdf_link->collision->origin),
00990                                 Eigen::Vector3d(mesh->scale.x, mesh->scale.y, mesh->scale.z));
00991       }
00992     }
00993   
00994   if (urdf_link->parent_joint)
00995     result->setJointOriginTransform(urdfPose2Affine3d(urdf_link->parent_joint->parent_to_joint_origin_transform));
00996   
00997   return result;
00998 }
00999 
01000 shapes::ShapePtr moveit::core::RobotModel::constructShape(const urdf::Geometry *geom)
01001 {
01002   moveit::tools::Profiler::ScopedBlock prof_block("RobotModel::constructShape");
01003 
01004   shapes::Shape *result = NULL;
01005   switch (geom->type)
01006   {
01007   case urdf::Geometry::SPHERE:
01008     result = new shapes::Sphere(static_cast<const urdf::Sphere*>(geom)->radius);
01009     break;
01010   case urdf::Geometry::BOX:
01011     {
01012       urdf::Vector3 dim = static_cast<const urdf::Box*>(geom)->dim;
01013       result = new shapes::Box(dim.x, dim.y, dim.z);
01014     }
01015     break;
01016   case urdf::Geometry::CYLINDER:
01017     result = new shapes::Cylinder(static_cast<const urdf::Cylinder*>(geom)->radius,
01018                                   static_cast<const urdf::Cylinder*>(geom)->length);
01019     break;
01020   case urdf::Geometry::MESH:
01021     {
01022       const urdf::Mesh *mesh = static_cast<const urdf::Mesh*>(geom);
01023       if (!mesh->filename.empty())
01024       {
01025         Eigen::Vector3d scale(mesh->scale.x, mesh->scale.y, mesh->scale.z);
01026         shapes::Mesh *m = shapes::createMeshFromResource(mesh->filename, scale);
01027         result = m;
01028       }
01029     }
01030     break;
01031   default:
01032     logError("Unknown geometry type: %d", (int)geom->type);
01033     break;
01034   }
01035 
01036   return shapes::ShapePtr(result);
01037 }
01038 
01039 bool moveit::core::RobotModel::hasJointModel(const std::string &name) const
01040 {
01041   return joint_model_map_.find(name) != joint_model_map_.end();
01042 }
01043 
01044 bool moveit::core::RobotModel::hasLinkModel(const std::string &name) const
01045 {
01046   return link_model_map_.find(name) != link_model_map_.end();
01047 }
01048 
01049 const moveit::core::JointModel* moveit::core::RobotModel::getJointModel(const std::string &name) const
01050 {
01051   JointModelMap::const_iterator it = joint_model_map_.find(name);
01052   if (it != joint_model_map_.end())
01053     return it->second;
01054   logError("Joint '%s' not found in model '%s'", name.c_str(), model_name_.c_str());
01055   return NULL;
01056 }
01057 
01058 const moveit::core::JointModel* moveit::core::RobotModel::getJointModel(int index) const
01059 {
01060   if (index < 0 || index >= static_cast<int>(joint_model_vector_.size()))
01061   {
01062     logError("Joint index '%i' out of bounds of joints in model '%s'", index, model_name_.c_str());
01063     return NULL;
01064   } 
01065   assert(joint_model_vector_[index]->getJointIndex() == index);
01066   return joint_model_vector_[index];
01067 }
01068 
01069 moveit::core::JointModel* moveit::core::RobotModel::getJointModel(const std::string &name)
01070 {
01071   JointModelMap::const_iterator it = joint_model_map_.find(name);
01072   if (it != joint_model_map_.end())
01073     return it->second;
01074   logError("Joint '%s' not found in model '%s'", name.c_str(), model_name_.c_str());
01075   return NULL;
01076 }
01077 
01078 const moveit::core::LinkModel* moveit::core::RobotModel::getLinkModel(const std::string &name) const
01079 {
01080   LinkModelMap::const_iterator it = link_model_map_.find(name);
01081   if (it != link_model_map_.end())
01082     return it->second;
01083   logError("Link '%s' not found in model '%s'", name.c_str(), model_name_.c_str());
01084   return NULL;  
01085 }
01086 
01087 const moveit::core::LinkModel* moveit::core::RobotModel::getLinkModel(int index) const
01088 {
01089   if (index < 0 || index >= static_cast<int>(link_model_vector_.size()))
01090   {
01091     logError("Link index '%i' out of bounds of links in model '%s'", index, model_name_.c_str());
01092     return NULL;
01093   } 
01094   assert(link_model_vector_[index]->getLinkIndex() == index);
01095   return link_model_vector_[index];
01096 }
01097 
01098 moveit::core::LinkModel* moveit::core::RobotModel::getLinkModel(const std::string &name)
01099 {
01100   LinkModelMap::const_iterator it = link_model_map_.find(name);
01101   if (it != link_model_map_.end())
01102     return it->second;
01103   logError("Link '%s' not found in model '%s'", name.c_str(), model_name_.c_str());
01104   return NULL;
01105 }
01106 
01107 void moveit::core::RobotModel::updateMimicJoints(double *values) const
01108 {
01109   for (std::size_t i = 0 ; i < mimic_joints_.size() ; ++i)
01110   {
01111     int src = mimic_joints_[i]->getMimic()->getFirstVariableIndex();
01112     int dest = mimic_joints_[i]->getFirstVariableIndex();
01113     values[dest] = values[src] * mimic_joints_[i]->getMimicFactor() + mimic_joints_[i]->getMimicOffset();
01114   }
01115 }
01116 
01117 void moveit::core::RobotModel::getVariableRandomPositions(random_numbers::RandomNumberGenerator &rng, double *values) const
01118 {
01119   for (std::size_t i = 0 ; i < active_joint_model_vector_.size() ; ++i)
01120     active_joint_model_vector_[i]->getVariableRandomPositions(rng, values + active_joint_model_start_index_[i]);
01121   updateMimicJoints(values);
01122 }
01123 
01124 void moveit::core::RobotModel::getVariableRandomPositions(random_numbers::RandomNumberGenerator &rng, std::map<std::string, double> &values) const
01125 {
01126   std::vector<double> tmp(variable_count_);
01127   getVariableRandomPositions(rng, &tmp[0]);
01128   values.clear();
01129   for (std::size_t i = 0 ; i < variable_names_.size() ; ++i)
01130     values[variable_names_[i]] = tmp[i];
01131 }
01132 
01133 void moveit::core::RobotModel::getVariableDefaultPositions(double *values) const
01134 {
01135   for (std::size_t i = 0 ; i < active_joint_model_vector_.size() ; ++i)
01136     active_joint_model_vector_[i]->getVariableDefaultPositions(values + active_joint_model_start_index_[i]);
01137   updateMimicJoints(values);
01138 }
01139 
01140 void moveit::core::RobotModel::getVariableDefaultPositions(std::map<std::string, double> &values) const
01141 {
01142   std::vector<double> tmp(variable_count_);
01143   getVariableDefaultPositions(&tmp[0]);
01144   values.clear();
01145   for (std::size_t i = 0 ; i < variable_names_.size() ; ++i)
01146     values[variable_names_[i]] = tmp[i];
01147 }
01148 
01149 void moveit::core::RobotModel::getMissingVariableNames(const std::vector<std::string> &variables, std::vector<std::string> &missing_variables) const
01150 {
01151   missing_variables.clear();
01152   std::set<std::string> keys(variables.begin(), variables.end());
01153   for (std::size_t i = 0 ; i < variable_names_.size() ; ++i)
01154     if (keys.find(variable_names_[i]) == keys.end())
01155       if (getJointOfVariable(variable_names_[i])->getMimic() == NULL)
01156         missing_variables.push_back(variable_names_[i]);
01157 }
01158 
01159 int moveit::core::RobotModel::getVariableIndex(const std::string &variable) const
01160 {
01161   VariableIndexMap::const_iterator it = joint_variables_index_map_.find(variable);
01162   if (it == joint_variables_index_map_.end())
01163     throw Exception("Variable '" + variable + "' is not known to model '" + model_name_ + "'");
01164   return it->second;
01165 }
01166 
01167 double moveit::core::RobotModel::getMaximumExtent(const JointBoundsVector &active_joint_bounds) const
01168 {
01169   double max_distance = 0.0;
01170   for (std::size_t j = 0 ; j < active_joint_model_vector_.size() ; ++j)
01171     max_distance += active_joint_model_vector_[j]->getMaximumExtent(*active_joint_bounds[j]) * active_joint_model_vector_[j]->getDistanceFactor();
01172   return max_distance;
01173 }
01174 
01175 bool moveit::core::RobotModel::satisfiesPositionBounds(const double *state, const JointBoundsVector &active_joint_bounds, double margin) const
01176 {
01177   assert(active_joint_bounds.size() == active_joint_model_vector_.size());
01178   for (std::size_t i = 0 ; i < active_joint_model_vector_.size() ; ++i)
01179     if (!active_joint_model_vector_[i]->satisfiesPositionBounds(state + active_joint_model_start_index_[i], *active_joint_bounds[i], margin))
01180       return false;
01181   return true;
01182 }
01183 
01184 bool moveit::core::RobotModel::enforcePositionBounds(double *state, const JointBoundsVector &active_joint_bounds) const
01185 {
01186   assert(active_joint_bounds.size() == active_joint_model_vector_.size());
01187   bool change = false;
01188   for (std::size_t i = 0 ; i < active_joint_model_vector_.size() ; ++i)
01189     if (active_joint_model_vector_[i]->enforcePositionBounds(state + active_joint_model_start_index_[i], *active_joint_bounds[i]))
01190       change = true;
01191   if (change)
01192     updateMimicJoints(state);
01193   return change;  
01194 }
01195 
01196 double moveit::core::RobotModel::distance(const double *state1, const double *state2) const
01197 {
01198   double d = 0.0;
01199   for (std::size_t i = 0 ; i < active_joint_model_vector_.size() ; ++i)
01200     d += active_joint_model_vector_[i]->getDistanceFactor() * 
01201       active_joint_model_vector_[i]->distance(state1 + active_joint_model_start_index_[i], state2 + active_joint_model_start_index_[i]);
01202   return d;
01203 }
01204 
01205 void moveit::core::RobotModel::interpolate(const double *from, const double *to, double t, double *state) const
01206 {
01207   // we interpolate values only for active joint models (non-mimic)
01208   for (std::size_t i = 0 ; i < active_joint_model_vector_.size() ; ++i)
01209     active_joint_model_vector_[i]->interpolate(from + active_joint_model_start_index_[i], to + active_joint_model_start_index_[i],
01210                                                t, state + active_joint_model_start_index_[i]);
01211   // now we update mimic as needed
01212   updateMimicJoints(state);
01213 }
01214 
01215 void moveit::core::RobotModel::setKinematicsAllocators(const std::map<std::string, SolverAllocatorFn> &allocators)
01216 {
01217   // we first set all the "simple" allocators -- where a group has one IK solver
01218   for (JointModelGroupMap::const_iterator it = joint_model_group_map_.begin() ; it != joint_model_group_map_.end() ; ++it)
01219   {
01220     std::map<std::string, SolverAllocatorFn>::const_iterator jt = allocators.find(it->second->getName());
01221     if (jt != allocators.end())
01222     {
01223       std::pair<SolverAllocatorFn, SolverAllocatorMapFn> result;
01224       result.first = jt->second;
01225       it->second->setSolverAllocators(result);
01226     }
01227   }
01228   
01229   // now we set compound IK solvers; we do this later because we need the index maps computed by the previous calls to setSolverAllocators()
01230   for (JointModelGroupMap::const_iterator it = joint_model_group_map_.begin() ; it != joint_model_group_map_.end() ; ++it)
01231   {
01232     JointModelGroup *jmg = it->second;
01233     std::pair<SolverAllocatorFn, SolverAllocatorMapFn> result;
01234     std::map<std::string, SolverAllocatorFn>::const_iterator jt = allocators.find(jmg->getName());
01235     if (jt == allocators.end())
01236     {
01237       // if an kinematics allocator is NOT available for this group, we try to see if we can use subgroups for IK
01238       std::set<const JointModel*> joints;
01239       joints.insert(jmg->getJointModels().begin(), jmg->getJointModels().end());
01240 
01241       std::vector<const JointModelGroup*> subs;
01242 
01243       // go through the groups that we know have IK allocators and see if they are included in the group that does not; if so, put that group in sub
01244       for (std::map<std::string, SolverAllocatorFn>::const_iterator kt = allocators.begin() ; kt != allocators.end() ; ++kt)
01245       {
01246         const JointModelGroup *sub = getJointModelGroup(kt->first);
01247         if (!sub)
01248         {
01249           subs.clear();
01250           break;
01251         }
01252         std::set<const JointModel*> sub_joints;
01253         sub_joints.insert(sub->getJointModels().begin(), sub->getJointModels().end());
01254 
01255         if (std::includes(joints.begin(), joints.end(), sub_joints.begin(), sub_joints.end()))
01256         {
01257           std::set<const JointModel*> resultj;
01258           std::set_difference(joints.begin(), joints.end(), sub_joints.begin(), sub_joints.end(),
01259                               std::inserter(resultj, resultj.end()));
01260           subs.push_back(sub);
01261           joints.swap(resultj);
01262         }
01263       }
01264 
01265       // if we found subgroups, pass that information to the planning group
01266       if (!subs.empty())
01267       {
01268         std::stringstream ss;
01269         for (std::size_t i = 0 ; i < subs.size() ; ++i)
01270         {
01271           ss << subs[i]->getName() << " ";
01272           result.second[subs[i]] = allocators.find(subs[i]->getName())->second;
01273         }
01274         logDebug("Added sub-group IK allocators for group '%s': [ %s]", jmg->getName().c_str(), ss.str().c_str());
01275       }
01276       jmg->setSolverAllocators(result);
01277     }
01278   }
01279 }
01280 
01281 void moveit::core::RobotModel::printModelInfo(std::ostream &out) const
01282 {
01283   out << "Model " << model_name_ << " in frame " << model_frame_ << ", using " << getVariableCount() << " variables" << std::endl;
01284 
01285   std::ios_base::fmtflags old_flags = out.flags();
01286   out.setf(std::ios::fixed, std::ios::floatfield);
01287   std::streamsize old_prec = out.precision();
01288   out.precision(5);
01289   out << "Joints: " << std::endl;
01290   for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
01291   {
01292     out << " '" << joint_model_vector_[i]->getName() << "' (" << joint_model_vector_[i]->getTypeName() << ")" << std::endl;
01293     out << "  * Joint Index: " << joint_model_vector_[i]->getJointIndex() << std::endl;
01294     const std::vector<std::string> &vn = joint_model_vector_[i]->getVariableNames();
01295     out << "  * " << vn.size() << (vn.size() > 1 ? " variables:" : (vn.empty() ? " variables" : " variable:")) << std::endl;
01296     int idx = joint_model_vector_[i]->getFirstVariableIndex();
01297     for (std::vector<std::string>::const_iterator it = vn.begin() ; it != vn.end() ; ++it)
01298     {
01299       out << "     * '" << *it << "', index " << idx++ << " in full state";
01300       if (joint_model_vector_[i]->getMimic())
01301         out << ", mimic '" << joint_model_vector_[i]->getMimic()->getName() << "'";
01302       if (joint_model_vector_[i]->isPassive())
01303         out << ", passive";
01304       out << std::endl;
01305       out << "        " << joint_model_vector_[i]->getVariableBounds(*it) << std::endl;
01306     }
01307   }
01308   out << std::endl;
01309   out.precision(old_prec);
01310   out.flags(old_flags);
01311   out << "Links: " << std::endl;
01312   for (std::size_t i = 0 ; i < link_model_vector_.size() ; ++i)
01313   {
01314     out << " '" << link_model_vector_[i]->getName() << "' with " << link_model_vector_[i]->getShapes().size() << " geoms" << std::endl;
01315     if (link_model_vector_[i]->parentJointIsFixed())
01316       out << "   * " << "parent joint is fixed" << std::endl;
01317     if (link_model_vector_[i]->jointOriginTransformIsIdentity())
01318       out << "   * " << "joint origin transform is identity" << std::endl;
01319   }
01320     
01321   out << "Available groups: " << std::endl;
01322   for (std::size_t i = 0 ; i < joint_model_groups_.size() ; ++i)
01323     joint_model_groups_[i]->printGroupInfo(out);  
01324 }
01325 
01326 void moveit::core::RobotModel::computeFixedTransforms(const LinkModel *link, const Eigen::Affine3d &transform, LinkTransformMap &associated_transforms)
01327 {
01328   associated_transforms[link] = transform * link->getJointOriginTransform();
01329   for (std::size_t i = 0 ; i < link->getChildJointModels().size() ; ++i)
01330     if (link->getChildJointModels()[i]->getType() == JointModel::FIXED)
01331       computeFixedTransforms(link->getChildJointModels()[i]->getChildLinkModel(), transform * link->getJointOriginTransform(), associated_transforms);
01332 }


moveit_core
Author(s): Ioan Sucan , Sachin Chitta , Acorn Pooley
autogenerated on Thu Aug 27 2015 13:58:53