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 #include <moveit/robot_model/joint_model_group.h>
00038 #include <moveit/robot_model/robot_model.h>
00039 #include <algorithm>
00040
00041 namespace robot_model
00042 {
00043 namespace
00044 {
00045
00046 bool orderLinksByIndex(const LinkModel *a, const LinkModel *b)
00047 {
00048 return a->getTreeIndex() < b->getTreeIndex();
00049 }
00050
00051 bool orderJointsByIndex(const JointModel *a, const JointModel *b)
00052 {
00053 return a->getTreeIndex() < b->getTreeIndex();
00054 }
00055
00056 bool includesParent(const JointModel *joint, const JointModelGroup *group)
00057 {
00058 bool found = false;
00059
00060 while (joint->getParentLinkModel() != NULL)
00061 {
00062 joint = joint->getParentLinkModel()->getParentJointModel();
00063 if (group->hasJointModel(joint->getName()) && joint->getVariableCount() > 0 && joint->getMimic() == NULL)
00064 {
00065 found = true;
00066 break;
00067 }
00068 else
00069 if (joint->getMimic() != NULL)
00070 {
00071 const JointModel *mjoint = joint->getMimic();
00072 if (group->hasJointModel(mjoint->getName()) && mjoint->getVariableCount() > 0 && mjoint->getMimic() == NULL)
00073 found = true;
00074 else
00075 if (includesParent(mjoint, group))
00076 found = true;
00077 if (found)
00078 break;
00079 }
00080 }
00081 return found;
00082 }
00083
00084 }
00085 }
00086
00087 robot_model::JointModelGroup::JointModelGroup(const std::string& group_name,
00088 const std::vector<const JointModel*> &unsorted_group_joints,
00089 const RobotModel* parent_model) :
00090 parent_model_(parent_model), name_(group_name),
00091 variable_count_(0), is_end_effector_(false), is_chain_(false),
00092 default_ik_timeout_(0.5), default_ik_attempts_(2)
00093 {
00094
00095 std::vector<const JointModel*> group_joints = unsorted_group_joints;
00096 std::sort(group_joints.begin(), group_joints.end(), &orderJointsByIndex);
00097
00098 for (std::size_t i = 0 ; i < group_joints.size() ; ++i)
00099 {
00100 joint_model_map_[group_joints[i]->getName()] = group_joints[i];
00101 unsigned int vc = group_joints[i]->getVariableCount();
00102 if (vc > 0)
00103 {
00104 if (group_joints[i]->getMimic() == NULL)
00105 {
00106 joint_model_vector_.push_back(group_joints[i]);
00107 variable_count_ += vc;
00108 }
00109 else
00110 mimic_joints_.push_back(group_joints[i]);
00111
00112 if (group_joints[i]->getType() == JointModel::REVOLUTE && static_cast<const RevoluteJointModel*>(group_joints[i])->isContinuous())
00113 continuous_joint_model_vector_const_.push_back(group_joints[i]);
00114 }
00115 else
00116 fixed_joints_.push_back(group_joints[i]);
00117 }
00118
00119
00120
00121 for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
00122 {
00123 joint_model_name_vector_.push_back(joint_model_vector_[i]->getName());
00124 bool found = false;
00125 const JointModel *joint = joint_model_vector_[i];
00126
00127 if (!includesParent(joint, this))
00128 joint_roots_.push_back(joint_model_vector_[i]);
00129 }
00130
00131
00132 unsigned int vector_index_counter = 0;
00133 for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
00134 {
00135 const std::vector<std::string>& name_order = joint_model_vector_[i]->getVariableNames();
00136 for (std::size_t j = 0; j < name_order.size(); ++j)
00137 {
00138 joint_variables_index_map_[name_order[j]] = vector_index_counter + j;
00139 active_variable_names_.push_back(name_order[j]);
00140 active_variable_names_set_.insert(name_order[j]);
00141 }
00142 joint_variables_index_map_[joint_model_vector_[i]->getName()] = vector_index_counter;
00143 vector_index_counter += name_order.size();
00144 }
00145
00146 for (std::size_t i = 0 ; i < mimic_joints_.size() ; ++i)
00147 {
00148 const std::vector<std::string>& name_order = mimic_joints_[i]->getVariableNames();
00149 const std::vector<std::string>& mim_name_order = mimic_joints_[i]->getMimic()->getVariableNames();
00150 for (std::size_t j = 0; j < name_order.size(); ++j)
00151 joint_variables_index_map_[name_order[j]] = joint_variables_index_map_[mim_name_order[j]];
00152 joint_variables_index_map_[mimic_joints_[i]->getName()] = joint_variables_index_map_[mimic_joints_[i]->getMimic()->getName()];
00153 }
00154
00155
00156 std::set<const LinkModel*> group_links_set;
00157 for (std::size_t i = 0 ; i < group_joints.size() ; ++i)
00158 group_links_set.insert(group_joints[i]->getChildLinkModel());
00159
00160 for (std::set<const LinkModel*>::iterator it = group_links_set.begin(); it != group_links_set.end(); ++it)
00161 link_model_vector_.push_back(*it);
00162
00163 std::sort(link_model_vector_.begin(), link_model_vector_.end(), &orderLinksByIndex);
00164 for (std::size_t i = 0 ; i < link_model_vector_.size() ; ++i)
00165 {
00166 link_model_name_vector_.push_back(link_model_vector_[i]->getName());
00167 if (link_model_vector_[i]->getShape())
00168 link_model_with_geometry_name_vector_.push_back(link_model_vector_[i]->getName());
00169 }
00170
00171
00172 std::set<const LinkModel*> u_links;
00173 for (std::size_t i = 0 ; i < joint_roots_.size() ; ++i)
00174 {
00175 std::vector<const LinkModel*> links;
00176 parent_model->getChildLinkModels(joint_roots_[i], links);
00177 u_links.insert(links.begin(), links.end());
00178 }
00179 for (std::set<const LinkModel*>::iterator it = u_links.begin(); it != u_links.end(); ++it)
00180 {
00181 updated_link_model_vector_.push_back(*it);
00182 updated_link_model_set_.insert(*it);
00183 updated_link_model_name_set_.insert((*it)->getName());
00184 if ((*it)->getShape())
00185 {
00186 updated_link_model_with_geometry_vector_.push_back(*it);
00187 updated_link_model_with_geometry_set_.insert(*it);
00188 updated_link_model_with_geometry_name_set_.insert((*it)->getName());
00189 }
00190 }
00191 std::sort(updated_link_model_vector_.begin(), updated_link_model_vector_.end(), &orderLinksByIndex);
00192 std::sort(updated_link_model_with_geometry_vector_.begin(), updated_link_model_with_geometry_vector_.end(), &orderLinksByIndex);
00193 for (std::size_t i = 0; i < updated_link_model_vector_.size(); ++i)
00194 updated_link_model_name_vector_.push_back(updated_link_model_vector_[i]->getName());
00195 for (std::size_t i = 0; i < updated_link_model_with_geometry_vector_.size(); ++i)
00196 updated_link_model_with_geometry_name_vector_.push_back(updated_link_model_with_geometry_vector_[i]->getName());
00197
00198
00199 if (joint_roots_.size() == 1 && joint_model_vector_.size() > 1 && !is_chain_)
00200 {
00201 bool chain = true;
00202
00203 for (std::size_t k = group_joints.size() - 1 ; k > 0 ; --k)
00204 if (!group_joints[k]->getParentLinkModel() || group_joints[k]->getParentLinkModel()->getParentJointModel() != group_joints[k-1])
00205 {
00206 chain = false;
00207 break;
00208 }
00209 if (chain)
00210 is_chain_ = true;
00211 }
00212 }
00213
00214 robot_model::JointModelGroup::~JointModelGroup()
00215 {
00216 }
00217
00218 bool robot_model::JointModelGroup::isSubgroup(const std::string& group) const
00219 {
00220 for (std::size_t i = 0; i < subgroup_names_.size(); ++i)
00221 if (group == subgroup_names_[i])
00222 return true;
00223 return false;
00224 }
00225
00226 bool robot_model::JointModelGroup::hasJointModel(const std::string &joint) const
00227 {
00228 return joint_model_map_.find(joint) != joint_model_map_.end();
00229 }
00230
00231 bool robot_model::JointModelGroup::hasLinkModel(const std::string &link) const
00232 {
00233 return std::find(link_model_name_vector_.begin(), link_model_name_vector_.end(), link) != link_model_name_vector_.end();
00234 }
00235
00236 const robot_model::JointModel* robot_model::JointModelGroup::getJointModel(const std::string &name) const
00237 {
00238 std::map<std::string, const JointModel*>::const_iterator it = joint_model_map_.find(name);
00239 if (it == joint_model_map_.end())
00240 {
00241 logError("Joint '%s' not found in group '%s'", name.c_str(), name_.c_str());
00242 return NULL;
00243 }
00244 else
00245 return it->second;
00246 }
00247
00248 void robot_model::JointModelGroup::getVariableRandomValues(random_numbers::RandomNumberGenerator &rng, std::vector<double> &values) const
00249 {
00250 for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
00251 joint_model_vector_[i]->getVariableRandomValues(rng, values);
00252 }
00253
00254 void robot_model::JointModelGroup::getVariableRandomValuesNearBy(random_numbers::RandomNumberGenerator &rng, std::vector<double> &values, const std::vector<double> &near, const std::map<robot_model::JointModel::JointType, double> &distance_map) const
00255 {
00256 if (near.size() != variable_count_)
00257 {
00258 logError("The specification of the near-by variable values to sample around for group '%s' should be of size %u but it is of size %u",
00259 name_.c_str(), variable_count_, (unsigned int)near.size());
00260 return;
00261 }
00262
00263 for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
00264 {
00265 double distance = 0.0;
00266 std::map<robot_model::JointModel::JointType, double>::const_iterator iter = distance_map.find(joint_model_vector_[i]->getType());
00267 if (iter != distance_map.end())
00268 distance = iter->second;
00269 else
00270 logWarn("Did not pass in distance for %s",joint_model_vector_[i]->getName().c_str());
00271 joint_model_vector_[i]->getVariableRandomValuesNearBy(rng, values, near, distance);
00272 }
00273 }
00274
00275 void robot_model::JointModelGroup::getVariableRandomValuesNearBy(random_numbers::RandomNumberGenerator &rng, std::vector<double> &values, const std::vector<double> &near, const std::vector<double> &distances) const
00276 {
00277 if (distances.size() != joint_model_vector_.size())
00278 {
00279 logError("When sampling random values nearby for group '%s', distances vector should be of size %u, but it is of size %u",
00280 name_.c_str(), (unsigned int)joint_model_vector_.size(), (unsigned int)distances.size());
00281 return;
00282 }
00283 if (near.size() != variable_count_)
00284 {
00285 logError("The specification of the near-by variable values to sample around for group '%s' should be of size %u but it is of size %u",
00286 name_.c_str(), variable_count_, (unsigned int)near.size());
00287 return;
00288 }
00289
00290 for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
00291 joint_model_vector_[i]->getVariableRandomValuesNearBy(rng, values, near, distances[i]);
00292 }
00293
00294 double robot_model::JointModelGroup::getMaximumExtent(void) const
00295 {
00296 double max_distance = 0.0;
00297 for (std::size_t j = 0 ; j < joint_model_vector_.size() ; ++j)
00298 max_distance += joint_model_vector_[j]->getMaximumExtent() * joint_model_vector_[j]->getDistanceFactor();
00299 return max_distance;
00300 }
00301
00302 void robot_model::JointModelGroup::getKnownDefaultStates(std::vector<std::string> &default_states) const
00303 {
00304 default_states.clear();
00305 default_states.reserve(default_states_.size());
00306 for (std::map<std::string, std::map<std::string, double> >::const_iterator it = default_states_.begin() ; it != default_states_.end() ; ++it)
00307 default_states.push_back(it->first);
00308 }
00309
00310 bool robot_model::JointModelGroup::getVariableDefaultValues(const std::string &name, std::map<std::string, double> &values) const
00311 {
00312 std::map<std::string, std::map<std::string, double> >::const_iterator it = default_states_.find(name);
00313 if (it == default_states_.end())
00314 return false;
00315 values = it->second;
00316 return true;
00317 }
00318
00319 void robot_model::JointModelGroup::getVariableDefaultValues(std::vector<double> &values) const
00320 {
00321 values.reserve(values.size() + joint_model_vector_.size());
00322 for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
00323 joint_model_vector_[i]->getVariableDefaultValues(values);
00324 }
00325
00326 void robot_model::JointModelGroup::getVariableDefaultValues(std::map<std::string, double> &values) const
00327 {
00328 for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
00329 joint_model_vector_[i]->getVariableDefaultValues(values);
00330 }
00331
00332 std::vector<moveit_msgs::JointLimits> robot_model::JointModelGroup::getVariableDefaultLimits() const
00333 {
00334 std::vector<moveit_msgs::JointLimits> ret_vec;
00335 for(unsigned int i = 0; i < joint_model_vector_.size(); i++)
00336 {
00337 const std::vector<moveit_msgs::JointLimits> &jvec = joint_model_vector_[i]->getVariableDefaultLimits();
00338 ret_vec.insert(ret_vec.end(), jvec.begin(), jvec.end());
00339 }
00340 return ret_vec;
00341 }
00342
00343 std::vector<moveit_msgs::JointLimits> robot_model::JointModelGroup::getVariableLimits() const
00344 {
00345 std::vector<moveit_msgs::JointLimits> ret_vec;
00346 for(unsigned int i = 0; i < joint_model_vector_.size(); i++)
00347 {
00348 const std::vector<moveit_msgs::JointLimits> &jvec = joint_model_vector_[i]->getVariableLimits();
00349 ret_vec.insert(ret_vec.end(), jvec.begin(), jvec.end());
00350 }
00351 return ret_vec;
00352 }
00353
00354 void robot_model::JointModelGroup::setVariableLimits(const std::vector<moveit_msgs::JointLimits>& jlim)
00355 {
00356
00357
00358 for (unsigned int i = 0; i < joint_model_vector_.size(); i++)
00359 const_cast<JointModel*>(joint_model_vector_[i])->setVariableLimits(jlim);
00360 }
00361
00362 void robot_model::JointModelGroup::setDefaultIKTimeout(double ik_timeout)
00363 {
00364 default_ik_timeout_ = ik_timeout;
00365 if (solver_instance_)
00366 solver_instance_->setDefaultTimeout(ik_timeout);
00367 }
00368
00369 void robot_model::JointModelGroup::setSolverAllocators(const std::pair<SolverAllocatorFn, SolverAllocatorMapFn> &solvers)
00370 {
00371 solver_allocators_ = solvers;
00372 if (solver_allocators_.first)
00373 {
00374 solver_instance_ = solver_allocators_.first(this);
00375 if (solver_instance_)
00376 {
00377 ik_joint_bijection_.clear();
00378 const std::vector<std::string> &ik_jnames = solver_instance_->getJointNames();
00379 for (std::size_t i = 0 ; i < ik_jnames.size() ; ++i)
00380 {
00381 std::map<std::string, unsigned int>::const_iterator it = joint_variables_index_map_.find(ik_jnames[i]);
00382 if (it == joint_variables_index_map_.end())
00383 {
00384 logError("IK solver computes joint values for joint '%s' but group '%s' does not contain such a joint.", ik_jnames[i].c_str(), getName().c_str());
00385 solver_instance_.reset();
00386 return;
00387 }
00388 const robot_model::JointModel *jm = getJointModel(ik_jnames[i]);
00389 for (unsigned int k = 0 ; k < jm->getVariableCount() ; ++k)
00390 ik_joint_bijection_.push_back(it->second + k);
00391 }
00392 solver_instance_const_ = solver_instance_;
00393 }
00394 }
00395 }
00396
00397 bool robot_model::JointModelGroup::canSetStateFromIK(const std::string &tip) const
00398 {
00399 const kinematics::KinematicsBaseConstPtr& solver = getSolverInstance();
00400 if (!solver)
00401 return false;
00402 const std::string &tip_frame = solver->getTipFrame();
00403 if (tip != tip_frame)
00404 {
00405 const LinkModel *lm = getParentModel()->getLinkModel(tip);
00406 if (!lm)
00407 return false;
00408 const LinkModel::AssociatedFixedTransformMap &fixed_links = lm->getAssociatedFixedTransforms();
00409 for (std::map<const LinkModel*, Eigen::Affine3d>::const_iterator it = fixed_links.begin() ; it != fixed_links.end() ; ++it)
00410 if (it->first->getName() == tip_frame)
00411 return true;
00412 return false;
00413 }
00414 else
00415 return true;
00416 }
00417
00418 void robot_model::JointModelGroup::printGroupInfo(std::ostream &out) const
00419 {
00420 out << "Group '" << name_ << "':" << std::endl;
00421 for (std::size_t i = 0 ; i < joint_model_vector_.size() ; ++i)
00422 {
00423 const std::vector<std::string> &vn = joint_model_vector_[i]->getVariableNames();
00424 for (std::vector<std::string>::const_iterator it = vn.begin() ; it != vn.end() ; ++it)
00425 {
00426 out << " " << *it << " [";
00427 std::pair<double, double> b;
00428 joint_model_vector_[i]->getVariableBounds(*it, b);
00429 if (b.first <= -std::numeric_limits<double>::max())
00430 out << "DBL_MIN";
00431 else
00432 out << b.first;
00433 out << ", ";
00434 if (b.second >= std::numeric_limits<double>::max())
00435 out << "DBL_MAX";
00436 else
00437 out << b.second;
00438 out << "]";
00439 if (joint_model_vector_[i]->getMimic())
00440 out << " *";
00441 out << std::endl;
00442 }
00443 }
00444 }