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
00037 #include <queue>
00038 #include <cmath>
00039 #include <set>
00040
00041 #include <ros/ros.h>
00042 #include <planning_models/kinematic_model.h>
00043 #include <geometric_shapes/shape_operations.h>
00044 #include <ros/console.h>
00045 #include <angles/angles.h>
00046
00047
00048
00049 planning_models::KinematicModel::KinematicModel(const urdf::Model &model,
00050 const std::vector<GroupConfig>& group_configs,
00051 const std::vector<MultiDofConfig>& multi_dof_configs)
00052 {
00053 model_name_ = model.getName();
00054 if (model.getRoot())
00055 {
00056 const urdf::Link *root = model.getRoot().get();
00057 root_ = buildRecursive(NULL, root, multi_dof_configs);
00058 buildGroups(group_configs);
00059 }
00060 else
00061 {
00062 root_ = NULL;
00063 ROS_WARN("No root link found");
00064 }
00065 }
00066
00067 planning_models::KinematicModel::KinematicModel(const KinematicModel &source)
00068 {
00069 copyFrom(source);
00070 }
00071
00072 planning_models::KinematicModel::~KinematicModel(void)
00073 {
00074 for (std::map<std::string, JointModelGroup*>::iterator it = joint_model_group_map_.begin() ; it != joint_model_group_map_.end() ; ++it)
00075 {
00076 delete it->second;
00077 }
00078
00079 if(root_) {
00080 delete root_;
00081 }
00082 }
00083
00084 void planning_models::KinematicModel::exclusiveLock(void) const
00085 {
00086 lock_.lock();
00087 }
00088
00089 void planning_models::KinematicModel::exclusiveUnlock(void) const
00090 {
00091 lock_.unlock();
00092 }
00093
00094 void planning_models::KinematicModel::sharedLock(void) const
00095 {
00096 lock_.lock_shared();
00097 }
00098
00099 void planning_models::KinematicModel::sharedUnlock(void) const
00100 {
00101 lock_.unlock_shared();
00102 }
00103
00104 const std::string& planning_models::KinematicModel::getName() const {
00105 return model_name_;
00106 }
00107
00108 void planning_models::KinematicModel::copyFrom(const KinematicModel &source)
00109 {
00110 model_name_ = source.model_name_;
00111
00112 if (source.root_)
00113 {
00114 root_ = copyRecursive(NULL, source.root_->child_link_model_);
00115
00116
00117 const std::map<std::string, JointModelGroup*>& source_group_map = source.getJointModelGroupMap();
00118 std::map< std::string, std::vector<std::string> > groupContent;
00119 std::vector<GroupConfig> group_configs;
00120 std::vector<std::string> empty_strings;
00121 for(std::map<std::string, JointModelGroup*>::const_iterator it = source_group_map.begin();
00122 it != source_group_map.end();
00123 it++) {
00124 group_configs.push_back(GroupConfig(it->first, it->second->getJointModelNames(), empty_strings));
00125 }
00126 buildGroups(group_configs);
00127 } else
00128 {
00129 root_ = NULL;
00130 }
00131 }
00132
00133 void planning_models::KinematicModel::buildGroups(const std::vector<GroupConfig>& group_configs)
00134 {
00135
00136 std::vector<bool> processed(group_configs.size(), false);
00137 while(true) {
00138
00139 bool added = false;
00140 for(unsigned int i = 0; i < group_configs.size(); i++) {
00141 if(!processed[i]) {
00142
00143 bool all_subgroups_added = true;
00144 for(unsigned int j = 0; j < group_configs[i].subgroups_.size(); j++) {
00145 if(joint_model_group_map_.find(group_configs[i].subgroups_[j]) ==
00146 joint_model_group_map_.end()) {
00147 all_subgroups_added = false;
00148 break;
00149 }
00150 }
00151 if(all_subgroups_added) {
00152
00153 if(addModelGroup(group_configs[i])) {
00154 processed[i] = true;
00155 added = true;
00156 } else {
00157 ROS_WARN_STREAM("Failed to add group " << group_configs[i].name_);
00158 }
00159 }
00160 }
00161 }
00162 if(!added) {
00163 for(unsigned int i = 0; i < processed.size(); i++) {
00164 if(!processed[i]) {
00165 ROS_WARN_STREAM("Could not process group " << group_configs[i].name_ << " due to unmet subgroup dependencies");
00166 }
00167 }
00168 return;
00169 }
00170 }
00171 }
00172
00173 void planning_models::KinematicModel::removeModelGroup(const std::string& group) {
00174 if(!hasModelGroup(group)) return;
00175 delete joint_model_group_map_[group];
00176 joint_model_group_map_.erase(group);
00177 joint_model_group_config_map_.erase(group);
00178 }
00179
00180 bool planning_models::KinematicModel::addModelGroup(const planning_models::KinematicModel::GroupConfig& gc)
00181 {
00182 if(joint_model_group_map_.find(gc.name_) != joint_model_group_map_.end()) {
00183 ROS_WARN_STREAM("Already have a model group named " << gc.name_ <<". Not adding.");
00184 return false;
00185 }
00186 std::vector<const JointModel*> jointv;
00187 std::vector<const JointModel*> fixed_jointv;
00188 if(!gc.tip_link_.empty() && !gc.base_link_.empty()) {
00189 if(!gc.subgroups_.empty()) {
00190 ROS_WARN_STREAM("Ignoring subgroups as tip and base are defined for group " << gc.name_);
00191 }
00192
00193 bool base_link_is_world_link = (gc.base_link_ == getRoot()->getParentFrameId() &&
00194 getLinkModel(gc.base_link_) == NULL);
00195 const LinkModel* base_link = NULL;
00196 if(!base_link_is_world_link) {
00197 base_link = getLinkModel(gc.base_link_);
00198 if(base_link == NULL) {
00199 ROS_WARN_STREAM("Group config " << gc.name_ << " has invalid base link " << gc.base_link_);
00200 return false;
00201 }
00202 }
00203 const LinkModel* tip_link = getLinkModel(gc.tip_link_);
00204 if(tip_link == NULL) {
00205 ROS_WARN_STREAM("Group config " << gc.name_ << " has invalid tip link " << gc.tip_link_);
00206 return false;
00207 }
00208 const LinkModel* lm = tip_link;
00209 bool ok = false;
00210 while(true) {
00211 if(lm == NULL) {
00212 if(base_link_is_world_link) {
00213 ok = true;
00214 }
00215 break;
00216 }
00217 if(lm == base_link) {
00218 ok = true;
00219 break;
00220 }
00221 if(lm->getParentJointModel() == NULL) {
00222 break;
00223 }
00224
00225 const FixedJointModel* fjm = dynamic_cast<const FixedJointModel*>(lm->getParentJointModel());
00226 if(fjm == NULL) {
00227 jointv.push_back(lm->getParentJointModel());
00228 } else {
00229 fixed_jointv.push_back(fjm);
00230 }
00231 lm = lm->getParentJointModel()->getParentLinkModel();
00232 }
00233 if(!ok) {
00234 ROS_WARN_STREAM("For group " << gc.name_
00235 << " base link " << gc.base_link_
00236 << " does not appear to be a direct descendent of " << gc.tip_link_);
00237 return false;
00238 }
00239
00240 std::reverse(jointv.begin(), jointv.end());
00241 } else {
00242 if(!gc.subgroups_.empty()) {
00243 std::set<const JointModel*> joint_set;
00244 for(unsigned int i = 0; i < gc.subgroups_.size(); i++) {
00245 if(joint_model_group_map_.find(gc.subgroups_[i]) == joint_model_group_map_.end()) {
00246 ROS_INFO_STREAM("Subgroup " << gc.subgroups_[i] << " not defined so can't add group " << gc.name_);
00247 return false;
00248 }
00249 const JointModelGroup* jmg = joint_model_group_map_.find(gc.subgroups_[i])->second;
00250 for(unsigned int j = 0; j < jmg->getJointModels().size(); j++) {
00251 joint_set.insert(jmg->getJointModels()[j]);
00252 }
00253 }
00254 for(std::set<const JointModel*>::iterator it = joint_set.begin();
00255 it != joint_set.end();
00256 it++) {
00257 jointv.push_back((*it));
00258 }
00259 }
00260 if(gc.joints_.size() == 0 && gc.subgroups_.empty()) {
00261 ROS_WARN_STREAM("Group " << gc.name_ << " must have tip/base links, subgroups, or one or more joints");
00262 return false;
00263 }
00264 for(unsigned int j = 0; j < gc.joints_.size(); j++) {
00265 const JointModel* joint = getJointModel(gc.joints_[j]);
00266 if(joint == NULL) {
00267 ROS_ERROR_STREAM("Group " << gc.name_ << " has invalid joint " << gc.joints_[j]);
00268 return false;
00269 }
00270 jointv.push_back(joint);
00271 }
00272 }
00273 if(jointv.size() == 0) {
00274 ROS_WARN_STREAM("Group " << gc.name_ << " must have at least one valid joint");
00275 return false;
00276 }
00277 joint_model_group_map_[gc.name_] = new JointModelGroup(gc.name_, jointv, fixed_jointv, this);
00278 joint_model_group_config_map_[gc.name_] = gc;
00279 return true;
00280 }
00281
00282 planning_models::KinematicModel::JointModel* planning_models::KinematicModel::buildRecursive(LinkModel *parent, const urdf::Link *link,
00283 const std::vector<MultiDofConfig>& multi_dof_configs)
00284 {
00285 JointModel *joint = constructJointModel(link->parent_joint.get(), link, multi_dof_configs);
00286 if(joint == NULL) {
00287 return NULL;
00288 }
00289 joint_model_map_[joint->name_] = joint;
00290 for(JointModel::js_type::const_iterator it = joint->getJointStateEquivalents().begin();
00291 it != joint->getJointStateEquivalents().end();
00292 it++) {
00293 joint_model_map_[it->right] = joint;
00294 }
00295 joint_model_vector_.push_back(joint);
00296 joint->parent_link_model_ = parent;
00297 joint->child_link_model_ = constructLinkModel(link);
00298 if (parent == NULL)
00299 joint->child_link_model_->joint_origin_transform_.setIdentity();
00300 link_model_map_[joint->child_link_model_->name_] = joint->child_link_model_;
00301 link_model_vector_.push_back(joint->child_link_model_);
00302 if(joint->child_link_model_->shape_ != NULL) {
00303 link_models_with_collision_geometry_vector_.push_back(joint->child_link_model_);
00304 }
00305 joint->child_link_model_->parent_joint_model_ = joint;
00306
00307 for (unsigned int i = 0 ; i < link->child_links.size() ; ++i) {
00308 JointModel* jm = buildRecursive(joint->child_link_model_, link->child_links[i].get(), multi_dof_configs);
00309 if(jm != NULL) {
00310 joint->child_link_model_->child_joint_models_.push_back(jm);
00311 }
00312 }
00313
00314 return joint;
00315 }
00316
00317 planning_models::KinematicModel::JointModel* planning_models::KinematicModel::constructJointModel(const urdf::Joint *urdf_joint,
00318 const urdf::Link *child_link,
00319 const std::vector<MultiDofConfig>& multi_dof_configs)
00320 {
00321 const MultiDofConfig* joint_config = NULL;
00322 bool found = false;
00323 for(std::vector<MultiDofConfig>::const_iterator it = multi_dof_configs.begin();
00324 it != multi_dof_configs.end();
00325 it++) {
00326 if(it->child_frame_id == child_link->name) {
00327 if(found == true) {
00328 ROS_WARN_STREAM("KinematicModel - two multi-dof joints with same " << it->child_frame_id << " child frame");
00329 } else {
00330 found = true;
00331 joint_config = &(*it);
00332 }
00333 }
00334 }
00335
00336 planning_models::KinematicModel::JointModel* result = NULL;
00337
00338
00339 if(urdf_joint == NULL) {
00340 if(!found) {
00341 ROS_ERROR("Root transform has no multi dof joint config");
00342 return NULL;
00343 }
00344 if(joint_config->type == "Planar") {
00345 result = new PlanarJointModel(joint_config->name, joint_config);
00346 } else if(joint_config->type == "Floating") {
00347 result = new FloatingJointModel(joint_config->name, joint_config);
00348 } else if(joint_config->type == "Fixed"){
00349 result = new FixedJointModel(joint_config->name, joint_config);
00350 } else {
00351 ROS_ERROR_STREAM("Unrecognized type of multi dof joint " << joint_config->type);
00352 return NULL;
00353 }
00354 } else {
00355 switch (urdf_joint->type)
00356 {
00357 case urdf::Joint::REVOLUTE:
00358 {
00359 RevoluteJointModel *j = new RevoluteJointModel(urdf_joint->name, joint_config);
00360 if(urdf_joint->safety)
00361 {
00362 j->setVariableBounds(j->name_, urdf_joint->safety->soft_lower_limit, urdf_joint->safety->soft_upper_limit);
00363 }
00364 else
00365 {
00366 j->setVariableBounds(j->name_, urdf_joint->limits->lower, urdf_joint->limits->upper);
00367 }
00368 j->continuous_ = false;
00369 j->axis_.setValue(urdf_joint->axis.x, urdf_joint->axis.y, urdf_joint->axis.z);
00370 result = j;
00371 }
00372 break;
00373 case urdf::Joint::CONTINUOUS:
00374 {
00375 RevoluteJointModel *j = new RevoluteJointModel(urdf_joint->name, joint_config);
00376 j->continuous_ = true;
00377 j->setVariableBounds(j->name_, -M_PI, M_PI);
00378 j->axis_.setValue(urdf_joint->axis.x, urdf_joint->axis.y, urdf_joint->axis.z);
00379 result = j;
00380 }
00381 break;
00382 case urdf::Joint::PRISMATIC:
00383 {
00384 PrismaticJointModel *j = new PrismaticJointModel(urdf_joint->name, joint_config);
00385 if(urdf_joint->safety)
00386 {
00387 j->setVariableBounds(j->name_, urdf_joint->safety->soft_lower_limit, urdf_joint->safety->soft_upper_limit);
00388 }
00389 else
00390 {
00391 j->setVariableBounds(j->name_, urdf_joint->limits->lower, urdf_joint->limits->upper);
00392 }
00393 j->axis_.setValue(urdf_joint->axis.x, urdf_joint->axis.y, urdf_joint->axis.z);
00394 result = j;
00395 }
00396 break;
00397 case urdf::Joint::FLOATING:
00398 result = new FloatingJointModel(urdf_joint->name, joint_config);
00399 break;
00400 case urdf::Joint::PLANAR:
00401 result = new PlanarJointModel(urdf_joint->name, joint_config);
00402 break;
00403 case urdf::Joint::FIXED:
00404 result = new FixedJointModel(urdf_joint->name, joint_config);
00405 break;
00406 default:
00407 ROS_ERROR("Unknown joint type: %d", (int)urdf_joint->type);
00408 break;
00409 }
00410 }
00411 return result;
00412 }
00413
00414 namespace planning_models
00415 {
00416 static inline tf::Transform urdfPose2TFTransform(const urdf::Pose &pose)
00417 {
00418 return tf::Transform(tf::Quaternion(pose.rotation.x, pose.rotation.y, pose.rotation.z, pose.rotation.w),
00419 tf::Vector3(pose.position.x, pose.position.y, pose.position.z));
00420 }
00421 }
00422
00423 planning_models::KinematicModel::LinkModel* planning_models::KinematicModel::constructLinkModel(const urdf::Link *urdf_link)
00424 {
00425 ROS_ASSERT(urdf_link);
00426
00427 LinkModel *result = new LinkModel(this);
00428 result->name_ = urdf_link->name;
00429
00430 if(urdf_link->collision && urdf_link->collision->geometry) {
00431 result->collision_origin_transform_ = urdfPose2TFTransform(urdf_link->collision->origin);
00432 result->shape_ = constructShape(urdf_link->collision->geometry.get());
00433 } else if(urdf_link->visual && urdf_link->visual->geometry){
00434 result->collision_origin_transform_ = urdfPose2TFTransform(urdf_link->visual->origin);
00435 result->shape_ = constructShape(urdf_link->visual->geometry.get());
00436 } else {
00437 result->collision_origin_transform_.setIdentity();
00438 result->shape_ = NULL;
00439 }
00440
00441 if (urdf_link->parent_joint.get()) {
00442 result->joint_origin_transform_ = urdfPose2TFTransform(urdf_link->parent_joint->parent_to_joint_origin_transform);
00443 ROS_DEBUG_STREAM("Setting joint origin for " << result->name_ << " to "
00444 << result->joint_origin_transform_.getOrigin().x() << " "
00445 << result->joint_origin_transform_.getOrigin().y() << " "
00446 << result->joint_origin_transform_.getOrigin().z());
00447 } else {
00448 ROS_DEBUG_STREAM("Setting joint origin to identity for " << result->name_);
00449 result->joint_origin_transform_.setIdentity();
00450 }
00451 return result;
00452 }
00453
00454 shapes::Shape* planning_models::KinematicModel::constructShape(const urdf::Geometry *geom)
00455 {
00456 ROS_ASSERT(geom);
00457
00458 shapes::Shape *result = NULL;
00459 switch (geom->type)
00460 {
00461 case urdf::Geometry::SPHERE:
00462 result = new shapes::Sphere(dynamic_cast<const urdf::Sphere*>(geom)->radius);
00463 break;
00464 case urdf::Geometry::BOX:
00465 {
00466 urdf::Vector3 dim = dynamic_cast<const urdf::Box*>(geom)->dim;
00467 result = new shapes::Box(dim.x, dim.y, dim.z);
00468 }
00469 break;
00470 case urdf::Geometry::CYLINDER:
00471 result = new shapes::Cylinder(dynamic_cast<const urdf::Cylinder*>(geom)->radius,
00472 dynamic_cast<const urdf::Cylinder*>(geom)->length);
00473 break;
00474 case urdf::Geometry::MESH:
00475 {
00476 const urdf::Mesh *mesh = dynamic_cast<const urdf::Mesh*>(geom);
00477 if (!mesh->filename.empty())
00478 {
00479 tf::Vector3 scale(mesh->scale.x, mesh->scale.y, mesh->scale.z);
00480 result = shapes::createMeshFromFilename(mesh->filename, &scale);
00481 }
00482 }
00483 break;
00484 default:
00485 ROS_ERROR("Unknown geometry type: %d", (int)geom->type);
00486 break;
00487 }
00488
00489 return result;
00490 }
00491
00492 const planning_models::KinematicModel::JointModel* planning_models::KinematicModel::getRoot(void) const
00493 {
00494 return root_;
00495 }
00496
00497 bool planning_models::KinematicModel::hasJointModel(const std::string &name) const
00498 {
00499 return joint_model_map_.find(name) != joint_model_map_.end();
00500 }
00501
00502 bool planning_models::KinematicModel::hasLinkModel(const std::string &name) const
00503 {
00504 return link_model_map_.find(name) != link_model_map_.end();
00505 }
00506
00507 bool planning_models::KinematicModel::hasModelGroup(const std::string &name) const
00508 {
00509 return joint_model_group_map_.find(name) != joint_model_group_map_.end();
00510 }
00511
00512 const planning_models::KinematicModel::JointModel* planning_models::KinematicModel::getJointModel(const std::string &name) const
00513 {
00514 std::map<std::string, JointModel*>::const_iterator it = joint_model_map_.find(name);
00515 if (it == joint_model_map_.end())
00516 {
00517 ROS_ERROR("Joint '%s' not found", name.c_str());
00518 return NULL;
00519 }
00520 else
00521 return it->second;
00522 }
00523
00524 const planning_models::KinematicModel::LinkModel* planning_models::KinematicModel::getLinkModel(const std::string &name) const
00525 {
00526 std::map<std::string, LinkModel*>::const_iterator it = link_model_map_.find(name);
00527 if (it == link_model_map_.end())
00528 {
00529 ROS_ERROR("Link '%s' not found", name.c_str());
00530 return NULL;
00531 }
00532 else
00533 return it->second;
00534 }
00535
00536 void planning_models::KinematicModel::getModelGroupNames(std::vector<std::string> &groups) const
00537 {
00538 groups.clear();
00539 groups.reserve(joint_model_group_map_.size());
00540 for (std::map<std::string, JointModelGroup*>::const_iterator it = joint_model_group_map_.begin() ; it != joint_model_group_map_.end() ; ++it)
00541 groups.push_back(it->second->name_);
00542 }
00543
00544 void planning_models::KinematicModel::getLinkModelNames(std::vector<std::string> &links) const
00545 {
00546 links.clear();
00547 links.reserve(link_model_vector_.size());
00548 for(unsigned int i = 0; i < link_model_vector_.size(); i++) {
00549 links.push_back(link_model_vector_[i]->getName());
00550 }
00551 }
00552
00553 void planning_models::KinematicModel::getJointModelNames(std::vector<std::string> &joints) const
00554 {
00555 joints.clear();
00556 joints.reserve(joint_model_vector_.size());
00557 for (unsigned int i = 0 ; i < joint_model_vector_.size() ; ++i)
00558 joints.push_back(joint_model_vector_[i]->getName());
00559 }
00560
00561 planning_models::KinematicModel::JointModel* planning_models::KinematicModel::copyRecursive(LinkModel *parent, const LinkModel *link)
00562 {
00563 JointModel *joint = copyJointModel(link->parent_joint_model_);
00564 joint_model_map_[joint->name_] = joint;
00565 for(JointModel::js_type::iterator it = joint->joint_state_equivalents_.begin();
00566 it != joint->joint_state_equivalents_.end();
00567 it++) {
00568 joint_model_map_[it->right] = joint;
00569 }
00570 joint_model_vector_.push_back(joint);
00571 joint->parent_link_model_ = parent;
00572 joint->child_link_model_ = new LinkModel(link);
00573 link_model_map_[joint->child_link_model_->name_] = joint->child_link_model_;
00574 joint->child_link_model_->parent_joint_model_ = joint;
00575
00576 for (unsigned int i = 0 ; i < link->child_joint_models_.size() ; ++i)
00577 joint->child_link_model_->child_joint_models_.push_back(copyRecursive(joint->child_link_model_, link->child_joint_models_[i]->child_link_model_));
00578
00579 return joint;
00580 }
00581
00582 planning_models::KinematicModel::JointModel* planning_models::KinematicModel::copyJointModel(const JointModel *joint)
00583 {
00584 JointModel *newJoint = NULL;
00585
00586 if (dynamic_cast<const FixedJointModel*>(joint))
00587 {
00588 newJoint = new FixedJointModel(dynamic_cast<const FixedJointModel*>(joint));
00589 }
00590 else if (dynamic_cast<const FloatingJointModel*>(joint))
00591 {
00592 newJoint = new FloatingJointModel(dynamic_cast<const FloatingJointModel*>(joint));
00593 }
00594 else if (dynamic_cast<const PlanarJointModel*>(joint))
00595 {
00596 newJoint = new PlanarJointModel(dynamic_cast<const PlanarJointModel*>(joint));
00597 }
00598 else if (dynamic_cast<const PrismaticJointModel*>(joint))
00599 {
00600 newJoint = new PrismaticJointModel(dynamic_cast<const PrismaticJointModel*>(joint));
00601 }
00602 else if (dynamic_cast<const RevoluteJointModel*>(joint))
00603 {
00604 newJoint = new RevoluteJointModel(dynamic_cast<const RevoluteJointModel*>(joint));
00605 }
00606 else
00607 ROS_FATAL("Unimplemented type of joint");
00608
00609 return newJoint;
00610 }
00611
00612 void planning_models::KinematicModel::getChildLinkModels(const KinematicModel::LinkModel *parent,
00613 std::vector<const KinematicModel::LinkModel*> &links) const
00614 {
00615 links.push_back(parent);
00616 std::queue<const KinematicModel::LinkModel*> q;
00617 q.push(parent);
00618 while (!q.empty())
00619 {
00620 const KinematicModel::LinkModel* t = q.front();
00621 q.pop();
00622
00623 for (unsigned int i = 0 ; i < t->child_joint_models_.size() ; ++i) {
00624 if (t->child_joint_models_[i]->child_link_model_)
00625 {
00626 links.push_back(t->child_joint_models_[i]->child_link_model_);
00627 q.push(t->child_joint_models_[i]->child_link_model_);
00628 }
00629 }
00630 }
00631 }
00632
00633 void planning_models::KinematicModel::getChildLinkModels(const KinematicModel::JointModel *parent,
00634 std::vector<const KinematicModel::LinkModel*> &links) const
00635 {
00636 getChildLinkModels(parent->child_link_model_, links);
00637 }
00638
00639 void planning_models::KinematicModel::getChildJointModels(const KinematicModel::LinkModel *parent,
00640 std::vector<const KinematicModel::JointModel*> &joints) const
00641 {
00642 const KinematicModel::LinkModel* t = parent;
00643
00644 std::queue<const KinematicModel::LinkModel*> q;
00645 while(1) {
00646 for (unsigned int i = 0 ; i < t->child_joint_models_.size() ; ++i) {
00647 joints.push_back(t->child_joint_models_[i]);
00648 if (t->child_joint_models_[i]->child_link_model_)
00649 {
00650 q.push(t->child_joint_models_[i]->child_link_model_);
00651 }
00652 }
00653 if(q.empty()) {
00654 break;
00655 }
00656 t = q.front();
00657 q.pop();
00658 } while (!q.empty());
00659 }
00660
00661 void planning_models::KinematicModel::getChildJointModels(const KinematicModel::JointModel *parent,
00662 std::vector<const KinematicModel::JointModel*> &joints) const
00663 {
00664 joints.push_back(parent);
00665 if(parent->child_link_model_) {
00666 getChildJointModels(parent->child_link_model_, joints);
00667 }
00668 }
00669
00670 std::vector<std::string>
00671 planning_models::KinematicModel::getChildLinkModelNames(const KinematicModel::LinkModel *parent) const
00672 {
00673 std::vector<const KinematicModel::LinkModel*> links;
00674 getChildLinkModels(parent, links);
00675 std::vector<std::string> ret_vec(links.size());
00676 for(unsigned int i = 0; i < links.size(); i++) {
00677 ret_vec[i] = links[i]->getName();
00678 }
00679 return ret_vec;
00680 }
00681
00682 std::vector<std::string>
00683 planning_models::KinematicModel::getChildLinkModelNames(const KinematicModel::JointModel *parent) const
00684 {
00685 std::vector<const KinematicModel::LinkModel*> links;
00686 getChildLinkModels(parent,links);
00687 std::vector<std::string> ret_vec(links.size());
00688 for(unsigned int i = 0; i < links.size(); i++) {
00689 ret_vec[i] = links[i]->getName();
00690 }
00691 return ret_vec;
00692 }
00693
00694 std::vector<std::string>
00695 planning_models::KinematicModel::getChildJointModelNames(const KinematicModel::LinkModel *parent) const
00696 {
00697 std::vector<const KinematicModel::JointModel*> joints;
00698 getChildJointModels(parent,joints);
00699 std::vector<std::string> ret_vec(joints.size());
00700 for(unsigned int i = 0; i < joints.size(); i++) {
00701 ret_vec[i] = joints[i]->getName();
00702 }
00703 return ret_vec;
00704 }
00705
00706 std::vector<std::string>
00707 planning_models::KinematicModel::getChildJointModelNames(const KinematicModel::JointModel *parent) const
00708 {
00709 std::vector<const KinematicModel::JointModel*> joints;
00710 getChildJointModels(parent,joints);
00711 std::vector<std::string> ret_vec(joints.size());
00712 for(unsigned int i = 0; i < joints.size(); i++) {
00713 ret_vec[i] = joints[i]->getName();
00714 }
00715 return ret_vec;
00716 }
00717
00718 void planning_models::KinematicModel::clearAllAttachedBodyModels()
00719 {
00720 exclusiveLock();
00721 for(unsigned int i =0; i < link_model_vector_.size(); i++) {
00722 link_model_vector_[i]->clearAttachedBodyModels();
00723 }
00724 exclusiveUnlock();
00725 }
00726
00727 std::vector<const planning_models::KinematicModel::AttachedBodyModel*> planning_models::KinematicModel::getAttachedBodyModels(void) const
00728 {
00729 std::vector<const planning_models::KinematicModel::AttachedBodyModel*> ret_vec;
00730 for(unsigned int i =0; i < link_model_vector_.size(); i++) {
00731 ret_vec.insert(ret_vec.end(), link_model_vector_[i]->getAttachedBodyModels().begin(),
00732 link_model_vector_[i]->getAttachedBodyModels().end());
00733 }
00734 return ret_vec;
00735 }
00736
00737 void planning_models::KinematicModel::clearLinkAttachedBodyModels(const std::string& link_name)
00738 {
00739 exclusiveLock();
00740 if(link_model_map_.find(link_name) == link_model_map_.end()) {
00741 exclusiveUnlock();
00742 return;
00743 }
00744 link_model_map_[link_name]->clearAttachedBodyModels();
00745 exclusiveUnlock();
00746 }
00747
00748 void planning_models::KinematicModel::replaceAttachedBodyModels(const std::string& link_name,
00749 std::vector<AttachedBodyModel*>& attached_body_vector)
00750 {
00751 exclusiveLock();
00752 if(link_model_map_.find(link_name) == link_model_map_.end())
00753 {
00754 ROS_WARN_STREAM("Model has no link named " << link_name << ". This is probably going to introduce a memory leak");
00755 exclusiveUnlock();
00756 return;
00757 }
00758 link_model_map_[link_name]->replaceAttachedBodyModels(attached_body_vector);
00759 exclusiveUnlock();
00760 }
00761
00762 void planning_models::KinematicModel::clearLinkAttachedBodyModel(const std::string& link_name,
00763 const std::string& att_name)
00764 {
00765 exclusiveLock();
00766 if(link_model_map_.find(link_name) == link_model_map_.end()) {
00767 exclusiveUnlock();
00768 return;
00769 }
00770 link_model_map_[link_name]->clearLinkAttachedBodyModel(att_name);
00771 exclusiveUnlock();
00772 }
00773
00774 void planning_models::KinematicModel::addAttachedBodyModel(const std::string& link_name,
00775 planning_models::KinematicModel::AttachedBodyModel* ab)
00776 {
00777 exclusiveLock();
00778 if(link_model_map_.find(link_name) == link_model_map_.end()) {
00779 ROS_WARN_STREAM("Model has no link named " << link_name << " to attach body to. This is probably going to introduce a memory leak");
00780 exclusiveUnlock();
00781 return;
00782 }
00783 link_model_map_[link_name]->addAttachedBodyModel(ab);
00784 exclusiveUnlock();
00785 }
00786
00787
00788
00789
00790 planning_models::KinematicModel::JointModel::JointModel(const std::string& n) :
00791 name_(n), parent_link_model_(NULL), child_link_model_(NULL)
00792 {
00793 }
00794
00795 void planning_models::KinematicModel::JointModel::initialize(const std::vector<std::string>& local_joint_names,
00796 const MultiDofConfig* config)
00797 {
00798 for(std::vector<std::string>::const_iterator it = local_joint_names.begin();
00799 it != local_joint_names.end();
00800 it++) {
00801 joint_state_equivalents_.insert(js_type::value_type(*it,*it));
00802 }
00803 if(config != NULL) {
00804 for(std::map<std::string, std::string>::const_iterator it = config->name_equivalents.begin();
00805 it != config->name_equivalents.end();
00806 it++) {
00807 js_type::left_iterator lit = joint_state_equivalents_.left.find(it->first);
00808 if(lit != joint_state_equivalents_.left.end()) {
00809 joint_state_equivalents_.left.replace_data(lit, it->second);
00810 }
00811 }
00812 parent_frame_id_ = config->parent_frame_id;
00813 child_frame_id_ = config->child_frame_id;
00814 }
00815 unsigned int i = 0;
00816 for(std::vector<std::string>::const_iterator it = local_joint_names.begin();
00817 it != local_joint_names.end();
00818 it++, i++) {
00819 computation_order_map_index_[i] = joint_state_equivalents_.left.at(*it);
00820 }
00821
00822 for(js_type::iterator it = joint_state_equivalents_.begin();
00823 it != joint_state_equivalents_.end();
00824 it++) {
00825 setVariableBounds(it->right,-DBL_MAX,DBL_MAX);
00826 }
00827 }
00828
00829 planning_models::KinematicModel::JointModel::JointModel(const JointModel* joint) {
00830 name_ = joint->name_;
00831 parent_frame_id_ = joint->parent_frame_id_;
00832 child_frame_id_ = joint->child_frame_id_;
00833 joint_state_equivalents_ = joint->joint_state_equivalents_;
00834 joint_state_bounds_ = joint->joint_state_bounds_;
00835 }
00836
00837 planning_models::KinematicModel::JointModel::~JointModel(void)
00838 {
00839 if (child_link_model_)
00840 delete child_link_model_;
00841 }
00842
00843 std::string planning_models::KinematicModel::JointModel::getEquiv(const std::string& name) const {
00844 js_type::left_const_iterator lit = joint_state_equivalents_.left.find(name);
00845 if(lit != joint_state_equivalents_.left.end()) {
00846 return lit->second;
00847 } else {
00848 return "";
00849 }
00850 }
00851
00852 bool planning_models::KinematicModel::JointModel::setVariableBounds(const std::string& variable, double low, double high) {
00853 if(joint_state_equivalents_.right.find(variable) == joint_state_equivalents_.right.end()) {
00854 ROS_WARN_STREAM("Can't find variable " << variable << " to set bounds");
00855 return false;
00856 }
00857 joint_state_bounds_[joint_state_equivalents_.right.at(variable)] = std::pair<double,double>(low, high);
00858 return true;
00859 }
00860
00861 bool planning_models::KinematicModel::JointModel::getVariableBounds(const std::string& variable, std::pair<double, double>& bounds) const{
00862 if(joint_state_equivalents_.right.find(variable) == joint_state_equivalents_.right.end()) {
00863 ROS_WARN_STREAM("Can't find variable " << variable << " to get bounds");
00864 return false;
00865 }
00866 std::string config_name = joint_state_equivalents_.right.find(variable)->second;
00867 if(joint_state_bounds_.find(config_name) == joint_state_bounds_.end()) {
00868 ROS_WARN_STREAM("No joint bounds for " << config_name);
00869 return false;
00870 }
00871 bounds = joint_state_bounds_.find(config_name)->second;
00872 return true;
00873 }
00874
00875 void planning_models::KinematicModel::JointModel::getVariableDefaultValuesGivenBounds(std::map<std::string, double>& ret_map) const
00876 {
00877 for(std::map<std::string, std::pair<double, double> >::const_iterator it = joint_state_bounds_.begin();
00878 it != joint_state_bounds_.end();
00879 it++) {
00880
00881 if(it->second.first <= 0.0 && it->second.second >= 0.0) {
00882 ret_map[it->first] = 0.0;
00883 } else {
00884 ret_map[it->first] = (it->second.first + it->second.second)/2.0;
00885 }
00886 }
00887 }
00888
00889 bool planning_models::KinematicModel::JointModel::isValueWithinVariableBounds(const std::string& variable, const double& value, bool& within_bounds) const
00890 {
00891 std::pair<double, double> bounds;
00892 if(!getVariableBounds(variable, bounds)) {
00893 return false;
00894 }
00895 if(value < bounds.first || value > bounds.second) {
00896 ROS_DEBUG_STREAM("Violates bounds: Value " << value << " lower " << bounds.first << " upper " << bounds.second);
00897 within_bounds = false;
00898 } else {
00899 ROS_DEBUG_STREAM("Satisfies bounds: Value " << value << " lower " << bounds.first << " upper " << bounds.second);
00900 within_bounds = true;
00901 }
00902 return true;
00903 }
00904
00905 planning_models::KinematicModel::PlanarJointModel::PlanarJointModel(const std::string& name, const MultiDofConfig* multi_dof_config)
00906 : JointModel(name)
00907 {
00908 if(multi_dof_config == NULL) {
00909 ROS_WARN("Planar joint needs a config");
00910 return;
00911 }
00912 std::vector<std::string> local_names;
00913 local_names.push_back("planar_x");
00914 local_names.push_back("planar_y");
00915 local_names.push_back("planar_th");
00916 initialize(local_names, multi_dof_config);
00917 setVariableBounds(getEquiv("planar_x"),-DBL_MAX,DBL_MAX);
00918 setVariableBounds(getEquiv("planar_y"),-DBL_MAX,DBL_MAX);
00919 setVariableBounds(getEquiv("planar_th"),-M_PI,M_PI);
00920 }
00921
00922 tf::Transform planning_models::KinematicModel::PlanarJointModel::computeTransform(const std::vector<double>& joint_values) const
00923 {
00924 tf::Transform variable_transform;
00925 variable_transform.setIdentity();
00926 if(joint_values.size() != 3) {
00927 ROS_ERROR("Planar joint given too few values");
00928 return variable_transform;
00929 }
00930 variable_transform.setOrigin(tf::Vector3(joint_values[0],
00931 joint_values[1],
00932 0.0));
00933 variable_transform.setRotation(tf::Quaternion(tf::Vector3(0.0, 0.0, 1.0),
00934 joint_values[2]));
00935 return variable_transform;
00936 }
00937
00938 std::vector<double> planning_models::KinematicModel::PlanarJointModel::computeJointStateValues(const tf::Transform& transform) const
00939 {
00940 std::vector<double> ret;
00941 ret.push_back(transform.getOrigin().x());
00942 ret.push_back(transform.getOrigin().y());
00943 ret.push_back(transform.getRotation().getAngle()*transform.getRotation().getAxis().z());
00944 return ret;
00945 }
00946
00947 planning_models::KinematicModel::FloatingJointModel::FloatingJointModel(const std::string& name,
00948 const MultiDofConfig* multi_dof_config)
00949 : JointModel(name)
00950 {
00951 if(multi_dof_config == NULL) {
00952 ROS_WARN("Planar joint needs a config");
00953 return;
00954 }
00955 std::vector<std::string> local_names;
00956 local_names.push_back("floating_trans_x");
00957 local_names.push_back("floating_trans_y");
00958 local_names.push_back("floating_trans_z");
00959 local_names.push_back("floating_rot_x");
00960 local_names.push_back("floating_rot_y");
00961 local_names.push_back("floating_rot_z");
00962 local_names.push_back("floating_rot_w");
00963 initialize(local_names, multi_dof_config);
00964
00965 setVariableBounds(getEquiv("floating_trans_x"),-DBL_MAX,DBL_MAX);
00966 setVariableBounds(getEquiv("floating_trans_y"),-DBL_MAX,DBL_MAX);
00967 setVariableBounds(getEquiv("floating_trans_z"),-DBL_MAX,DBL_MAX);
00968 setVariableBounds(getEquiv("floating_rot_x"),-1.0,1.0);
00969 setVariableBounds(getEquiv("floating_rot_y"),-1.0,1.0);
00970 setVariableBounds(getEquiv("floating_rot_z"),-1.0,1.0);
00971 setVariableBounds(getEquiv("floating_rot_w"),-1.0,1.0);
00972 }
00973
00974 tf::Transform planning_models::KinematicModel::FloatingJointModel::computeTransform(const std::vector<double>& joint_values) const
00975 {
00976 tf::Transform variable_transform;
00977 variable_transform.setIdentity();
00978 if(joint_values.size() != 7) {
00979 ROS_ERROR("Floating joint given too few values");
00980 return variable_transform;
00981 }
00982 variable_transform.setOrigin(tf::Vector3(joint_values[0], joint_values[1], joint_values[2]));
00983 variable_transform.setRotation(tf::Quaternion(joint_values[3], joint_values[4], joint_values[5], joint_values[6]));
00984 if(joint_values[3] == 0.0 && joint_values[4] == 0.0 && joint_values[5] == 0.0 && joint_values[6] == 0.0) {
00985 ROS_INFO("Setting quaternion with all zeros");
00986 }
00987 return variable_transform;
00988 }
00989
00990 std::vector<double> planning_models::KinematicModel::FloatingJointModel::computeJointStateValues(const tf::Transform& transform) const
00991 {
00992 std::vector<double> ret;
00993 ret.push_back(transform.getOrigin().x());
00994 ret.push_back(transform.getOrigin().y());
00995 ret.push_back(transform.getOrigin().z());
00996 ret.push_back(transform.getRotation().x());
00997 ret.push_back(transform.getRotation().y());
00998 ret.push_back(transform.getRotation().z());
00999 ret.push_back(transform.getRotation().w());
01000 return ret;
01001 }
01002
01003 void planning_models::KinematicModel::FloatingJointModel::getVariableDefaultValuesGivenBounds(std::map<std::string, double>& ret_map) const
01004 {
01005
01006 ret_map[getEquiv("floating_trans_x")] = 0.0;
01007 ret_map[getEquiv("floating_trans_y")] = 0.0;
01008 ret_map[getEquiv("floating_trans_z")] = 0.0;
01009 ret_map[getEquiv("floating_rot_x")] = 0.0;
01010 ret_map[getEquiv("floating_rot_y")] = 0.0;
01011 ret_map[getEquiv("floating_rot_z")] = 0.0;
01012 ret_map[getEquiv("floating_rot_w")] = 1.0;
01013 }
01014
01015 planning_models::KinematicModel::PrismaticJointModel::PrismaticJointModel(const std::string& name,
01016 const MultiDofConfig* multi_dof_config)
01017 : JointModel(name),
01018 axis_(0.0, 0.0, 0.0)
01019 {
01020 std::vector<std::string> local_names(1,name);
01021 initialize(local_names, multi_dof_config);
01022 }
01023
01024 tf::Transform planning_models::KinematicModel::PrismaticJointModel::computeTransform(const std::vector<double>& joint_values) const
01025 {
01026 tf::Transform variable_transform;
01027 variable_transform.setIdentity();
01028 if(joint_values.size() != 1) {
01029 ROS_ERROR("Prismatic joint given wrong number of values");
01030 return variable_transform;
01031 }
01032 variable_transform.setOrigin(axis_*joint_values[0]);
01033 return variable_transform;
01034 }
01035
01036 std::vector<double> planning_models::KinematicModel::PrismaticJointModel::computeJointStateValues(const tf::Transform& transform) const
01037 {
01038 std::vector<double> ret;
01039 ret.push_back(transform.getOrigin().dot(axis_));
01040 return ret;
01041 }
01042
01043 planning_models::KinematicModel::RevoluteJointModel::RevoluteJointModel(const std::string& name,
01044 const MultiDofConfig* multi_dof_config)
01045 : JointModel(name),
01046 axis_(0.0, 0.0, 0.0),
01047 continuous_(false)
01048 {
01049 std::vector<std::string> local_names(1,name);
01050 initialize(local_names, multi_dof_config);
01051 }
01052
01053 tf::Transform planning_models::KinematicModel::RevoluteJointModel::computeTransform(const std::vector<double>& joint_values) const
01054 {
01055 tf::Transform variable_transform;
01056 variable_transform.setIdentity();
01057 if(joint_values.size() != 1) {
01058 ROS_ERROR("Revolute joint given wrong number of values");
01059 return variable_transform;
01060 }
01061 double val = joint_values.front();
01062 if(continuous_) {
01063 val = angles::normalize_angle(val);
01064 }
01065 variable_transform.setRotation(tf::Quaternion(axis_,val));
01066 return variable_transform;
01067 }
01068
01069 std::vector<double> planning_models::KinematicModel::RevoluteJointModel::computeJointStateValues(const tf::Transform& transform) const
01070 {
01071 std::vector<double> ret;
01072 ROS_DEBUG_STREAM("Transform angle is " << transform.getRotation().getAngle()
01073 << " axis x " << transform.getRotation().getAxis().x()
01074 << " axis y " << transform.getRotation().getAxis().y()
01075 << " axis z " << transform.getRotation().getAxis().z());
01076 double val = transform.getRotation().getAngle()*transform.getRotation().getAxis().dot(axis_);
01077 while(val < -M_PI) {
01078 if(val < -M_PI) {
01079 val += 2*M_PI;
01080 }
01081 }
01082 while(val > M_PI) {
01083 if(val > M_PI) {
01084 val -= 2*M_PI;
01085 }
01086 }
01087 ret.push_back(val);
01088 return ret;
01089 }
01090
01091 bool planning_models::KinematicModel::RevoluteJointModel::isValueWithinVariableBounds(const std::string& variable,
01092 const double& value,
01093 bool& within_bounds) const
01094 {
01095 if(!continuous_) {
01096 return JointModel::isValueWithinVariableBounds(variable, value, within_bounds);
01097 }
01098 if(!hasVariable(variable)) {
01099 return false;
01100 }
01101 within_bounds = true;
01102 return true;
01103 }
01104
01105
01106
01107 planning_models::KinematicModel::LinkModel::LinkModel(const KinematicModel* kinematic_model) :
01108 kinematic_model_(kinematic_model),
01109 parent_joint_model_(NULL),
01110 shape_(NULL)
01111 {
01112 joint_origin_transform_.setIdentity();
01113 collision_origin_transform_.setIdentity();
01114 }
01115
01116 planning_models::KinematicModel::LinkModel::LinkModel(const LinkModel* link_model) :
01117 name_(link_model->name_),
01118 kinematic_model_(link_model->kinematic_model_),
01119 joint_origin_transform_(link_model->joint_origin_transform_),
01120 collision_origin_transform_(link_model->collision_origin_transform_)
01121 {
01122 if(link_model->shape_) {
01123 shape_ = shapes::cloneShape(link_model->shape_);
01124 } else {
01125 shape_ = NULL;
01126 }
01127 for (unsigned int i = 0 ; i < link_model->attached_body_models_.size() ; ++i)
01128 {
01129 std::vector<shapes::Shape*> shapes;
01130 for(unsigned int j = 0; j < link_model->attached_body_models_[i]->getShapes().size(); j++) {
01131 shapes.push_back(shapes::cloneShape(link_model->attached_body_models_[i]->getShapes()[j]));
01132 }
01133 AttachedBodyModel *ab = new AttachedBodyModel(this,
01134 link_model->attached_body_models_[i]->getName(),
01135 link_model->attached_body_models_[i]->getAttachedBodyFixedTransforms(),
01136 link_model->attached_body_models_[i]->getTouchLinks(),
01137 shapes);
01138 attached_body_models_.push_back(ab);
01139 }
01140 }
01141
01142 planning_models::KinematicModel::LinkModel::~LinkModel(void)
01143 {
01144 if (shape_)
01145 delete shape_;
01146 for (unsigned int i = 0 ; i < child_joint_models_.size() ; ++i)
01147 delete child_joint_models_[i];
01148 for (unsigned int i = 0 ; i < attached_body_models_.size() ; ++i)
01149 delete attached_body_models_[i];
01150 }
01151
01152 void planning_models::KinematicModel::LinkModel::clearAttachedBodyModels()
01153 {
01154
01155 for (unsigned int i = 0 ; i < attached_body_models_.size() ; ++i)
01156 delete attached_body_models_[i];
01157 attached_body_models_.clear();
01158 }
01159
01160 void planning_models::KinematicModel::LinkModel::replaceAttachedBodyModels(std::vector<AttachedBodyModel*>& attached_body_vector)
01161 {
01162
01163 for (unsigned int i = 0 ; i < attached_body_models_.size() ; ++i)
01164 delete attached_body_models_[i];
01165 attached_body_models_.clear();
01166
01167 attached_body_models_ = attached_body_vector;
01168 }
01169
01170 void planning_models::KinematicModel::LinkModel::clearLinkAttachedBodyModel(const std::string& att_name)
01171 {
01172 for(std::vector<AttachedBodyModel*>::iterator it = attached_body_models_.begin();
01173 it != attached_body_models_.end();
01174 it++) {
01175 if((*it)->getName() == att_name) {
01176 delete (*it);
01177 attached_body_models_.erase(it);
01178 return;
01179 }
01180 }
01181 }
01182
01183 void planning_models::KinematicModel::LinkModel::addAttachedBodyModel(planning_models::KinematicModel::AttachedBodyModel* ab)
01184 {
01185 attached_body_models_.push_back(ab);
01186 }
01187
01188
01189
01190 planning_models::KinematicModel::AttachedBodyModel::AttachedBodyModel(const LinkModel *link,
01191 const std::string& nid,
01192 const std::vector<tf::Transform>& attach_trans,
01193 const std::vector<std::string>& touch_links,
01194 std::vector<shapes::Shape*>& shapes)
01195
01196 : attached_link_model_(link),
01197 id_(nid)
01198 {
01199 attach_trans_ = attach_trans;
01200 touch_links_ = touch_links;
01201 shapes_ = shapes;
01202 }
01203
01204 planning_models::KinematicModel::AttachedBodyModel::~AttachedBodyModel(void)
01205 {
01206 for(unsigned int i = 0; i < shapes_.size(); i++) {
01207 delete shapes_[i];
01208 }
01209 }
01210
01211
01212 planning_models::KinematicModel::JointModelGroup::JointModelGroup(const std::string& group_name,
01213 const std::vector<const JointModel*> &group_joints,
01214 const std::vector<const JointModel*> &fixed_group_joints,
01215 const KinematicModel* parent_model) :
01216 name_(group_name)
01217 {
01218 ROS_DEBUG_STREAM("Group " << group_name);
01219
01220 joint_model_vector_ = group_joints;
01221 fixed_joint_model_vector_ = fixed_group_joints;
01222 joint_model_name_vector_.resize(group_joints.size());
01223
01224 ROS_DEBUG_STREAM("Joints:");
01225 for (unsigned int i = 0 ; i < group_joints.size() ; ++i)
01226 {
01227 ROS_DEBUG_STREAM(group_joints[i]->getName());
01228 joint_model_name_vector_[i] = group_joints[i]->getName();
01229 joint_model_map_[group_joints[i]->getName()] = group_joints[i];
01230 }
01231
01232 ROS_DEBUG_STREAM("Fixed joints:");
01233 for (unsigned int i = 0 ; i < fixed_joint_model_vector_.size() ; ++i)
01234 {
01235 ROS_DEBUG_STREAM(fixed_joint_model_vector_[i]->getName());
01236 }
01237
01238 std::vector<const JointModel*> all_joints = group_joints;
01239 all_joints.insert(all_joints.end(), fixed_group_joints.begin(), fixed_group_joints.end());
01240
01241
01242
01243 std::map<std::string, bool> is_root;
01244 for (unsigned int i = 0 ; i < all_joints.size() ; ++i)
01245 {
01246 bool found = false;
01247 const JointModel *joint = all_joints[i];
01248
01249 while (joint->getParentLinkModel() != NULL)
01250 {
01251 joint = joint->getParentLinkModel()->getParentJointModel();
01252 if (hasJointModel(joint->name_))
01253 {
01254 found = true;
01255 }
01256 }
01257
01258 if(!found) {
01259 joint_roots_.push_back(all_joints[i]);
01260 is_root[all_joints[i]->getName()] = true;
01261 } else {
01262 is_root[all_joints[i]->getName()] = false;
01263 }
01264 }
01265
01266
01267 std::set<const LinkModel*> group_links_set;
01268 for(unsigned int i = 0; i < all_joints.size(); i++) {
01269 const JointModel *joint = all_joints[i];
01270
01271 group_links_set.insert(joint->getChildLinkModel());
01272 while (joint->getParentLinkModel() != NULL)
01273 {
01274 if(is_root.find(joint->getName()) != is_root.end() &&
01275 is_root[joint->getName()]) {
01276 break;
01277 }
01278 group_links_set.insert(joint->getParentLinkModel());
01279 joint = joint->getParentLinkModel()->getParentJointModel();
01280 }
01281 }
01282
01283 ROS_DEBUG("Group links:");
01284 for(std::set<const LinkModel*>::iterator it = group_links_set.begin();
01285 it != group_links_set.end();
01286 it++) {
01287 group_link_model_vector_.push_back(*it);
01288 ROS_DEBUG_STREAM((*it)->getName());
01289 }
01290
01291 for (unsigned int i = 0 ; i < joint_roots_.size() ; ++i)
01292 {
01293 std::vector<const LinkModel*> links;
01294 parent_model->getChildLinkModels(joint_roots_[i], links);
01295 updated_link_model_vector_.insert(updated_link_model_vector_.end(), links.begin(), links.end());
01296 }
01297 }
01298
01299 planning_models::KinematicModel::JointModelGroup::~JointModelGroup(void)
01300 {
01301 }
01302
01303 bool planning_models::KinematicModel::JointModelGroup::hasJointModel(const std::string &joint) const
01304 {
01305 return joint_model_map_.find(joint) != joint_model_map_.end();
01306 }
01307
01308 const planning_models::KinematicModel::JointModel* planning_models::KinematicModel::JointModelGroup::getJointModel(const std::string &name)
01309 {
01310 if(!hasJointModel(name)) return NULL;
01311 return joint_model_map_.find(name)->second;
01312 }
01313