00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
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
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
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
00201
00202
00203
00204
00205
00206
00207 common_joint_roots_.resize(joint_model_vector_.size() * joint_model_vector_.size(), 0);
00208
00209
00210
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
00216 common_joint_roots_[joint_model_vector_[i]->getJointIndex() * (1 + joint_model_vector_.size())] = joint_model_vector_[i]->getJointIndex();
00217
00218
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
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
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
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
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();
00310 }
00311
00312 void moveit::core::RobotModel::buildGroupStates(const srdf::Model &srdf_model)
00313 {
00314
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
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
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
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
00470 std::vector<bool> processed(group_configs.size(), false);
00471
00472 bool added = true;
00473 while (added)
00474 {
00475 added = false;
00476
00477
00478 for (std::size_t i = 0 ; i < group_configs.size() ; ++i)
00479 if (!processed[i])
00480 {
00481
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
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
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
00551 for (std::size_t k = 0 ; k < eefs.size() ; ++k)
00552 if (eefs[k].component_group_ == it->first)
00553 {
00554
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
00560
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
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
00596 if (eef_parent_group == NULL)
00597 if (!possible_parent_groups.empty())
00598 {
00599
00600
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
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
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
00651
00652 if (lm != base_link)
00653 {
00654
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
00679 jset.insert(cj.begin(), cj.end());
00680 }
00681 }
00682
00683
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
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
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
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
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
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
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
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
00757 LinkModel *link = constructLinkModel(urdf_link);
00758 joint->setChildLinkModel(link);
00759 link->setParentLinkModel(parent);
00760
00761
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
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
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
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
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
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
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
01212 updateMimicJoints(state);
01213 }
01214
01215 void moveit::core::RobotModel::setKinematicsAllocators(const std::map<std::string, SolverAllocatorFn> &allocators)
01216 {
01217
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
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
01238 std::set<const JointModel*> joints;
01239 joints.insert(jmg->getJointModels().begin(), jmg->getJointModels().end());
01240
01241 std::vector<const JointModelGroup*> subs;
01242
01243
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
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 }