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 <planning_models/kinematic_model.h>
00038 #include <geometric_shapes/shape_operations.h>
00039 #include <resource_retriever/retriever.h>
00040 #include <queue>
00041 #include <ros/console.h>
00042 #include <cmath>
00043 #include <angles/angles.h>
00044 #include <assimp/assimp.hpp>
00045 #include <assimp/aiScene.h>
00046 #include <assimp/aiPostProcess.h>
00047
00048
00049
00050 planning_models::KinematicModel::KinematicModel(const urdf::Model &model,
00051 const std::map< std::string, std::vector<std::string> > &groups,
00052 const std::vector<MultiDofConfig>& multi_dof_configs)
00053 {
00054 model_name_ = model.getName();
00055 if (model.getRoot())
00056 {
00057 const urdf::Link *root = model.getRoot().get();
00058 root_ = buildRecursive(NULL, root, multi_dof_configs);
00059 buildGroups(groups);
00060 }
00061 else
00062 {
00063 root_ = NULL;
00064 ROS_WARN("No root link found");
00065 }
00066 }
00067
00068 planning_models::KinematicModel::KinematicModel(const KinematicModel &source)
00069 {
00070 copyFrom(source);
00071 }
00072
00073 planning_models::KinematicModel::~KinematicModel(void)
00074 {
00075 for (std::map<std::string, JointModelGroup*>::iterator it = joint_model_group_map_.begin() ; it != joint_model_group_map_.end() ; ++it)
00076 {
00077 delete it->second;
00078 }
00079
00080 if(root_) {
00081 delete root_;
00082 }
00083 }
00084
00085 void planning_models::KinematicModel::exclusiveLock(void) const
00086 {
00087 lock_.lock();
00088 }
00089
00090 void planning_models::KinematicModel::exclusiveUnlock(void) const
00091 {
00092 lock_.unlock();
00093 }
00094
00095 void planning_models::KinematicModel::sharedLock(void) const
00096 {
00097 lock_.lock_shared();
00098 }
00099
00100 void planning_models::KinematicModel::sharedUnlock(void) const
00101 {
00102 lock_.unlock_shared();
00103 }
00104
00105 const std::string& planning_models::KinematicModel::getName() const {
00106 return model_name_;
00107 }
00108
00109 void planning_models::KinematicModel::copyFrom(const KinematicModel &source)
00110 {
00111 model_name_ = source.model_name_;
00112
00113 if (source.root_)
00114 {
00115 root_ = copyRecursive(NULL, source.root_->child_link_model_);
00116
00117
00118 const std::map<std::string, JointModelGroup*>& source_group_map = source.getJointModelGroupMap();
00119 std::map< std::string, std::vector<std::string> > groupContent;
00120 for(std::map<std::string, JointModelGroup*>::const_iterator it = source_group_map.begin();
00121 it != source_group_map.end();
00122 it++) {
00123 groupContent[it->second->getName()] = it->second->getJointModelNames();
00124 }
00125 buildGroups(groupContent);
00126 } else
00127 {
00128 root_ = NULL;
00129 }
00130 }
00131
00132 void planning_models::KinematicModel::buildGroups(const std::map< std::string, std::vector<std::string> > &groups)
00133 {
00134 for (std::map< std::string, std::vector<std::string> >::const_iterator it = groups.begin() ; it != groups.end() ; ++it)
00135 {
00136 std::vector<const JointModel*> jointv;
00137 for (unsigned int i = 0 ; i < it->second.size() ; ++i)
00138 {
00139 std::map<std::string, JointModel*>::iterator p = joint_model_map_.find(it->second[i]);
00140 if (p == joint_model_map_.end())
00141 {
00142 ROS_ERROR("Unknown joint '%s'. Not adding to group '%s'", it->second[i].c_str(), it->first.c_str());
00143 jointv.clear();
00144 break;
00145 }
00146 else
00147 jointv.push_back(p->second);
00148 }
00149
00150 if (jointv.empty())
00151 ROS_DEBUG("Skipping group '%s'", it->first.c_str());
00152 else
00153 {
00154 ROS_DEBUG("Adding group '%s'", it->first.c_str());
00155 joint_model_group_map_[it->first] = new JointModelGroup(it->first, jointv);
00156 }
00157 }
00158 }
00159
00160 planning_models::KinematicModel::JointModel* planning_models::KinematicModel::buildRecursive(LinkModel *parent, const urdf::Link *link,
00161 const std::vector<MultiDofConfig>& multi_dof_configs)
00162 {
00163 JointModel *joint = constructJointModel(link->parent_joint.get(), link, multi_dof_configs);
00164 joint_model_map_[joint->name_] = joint;
00165 for(JointModel::js_type::const_iterator it = joint->getJointStateEquivalents().begin();
00166 it != joint->getJointStateEquivalents().end();
00167 it++) {
00168 joint_model_map_[it->right] = joint;
00169 }
00170 joint_model_vector_.push_back(joint);
00171 joint->parent_link_model_ = parent;
00172 joint->child_link_model_ = constructLinkModel(link);
00173 if (parent == NULL)
00174 joint->child_link_model_->joint_origin_transform_.setIdentity();
00175 link_model_map_[joint->child_link_model_->name_] = joint->child_link_model_;
00176 link_model_vector_.push_back(joint->child_link_model_);
00177 joint->child_link_model_->parent_joint_model_ = joint;
00178
00179 for (unsigned int i = 0 ; i < link->child_links.size() ; ++i)
00180 joint->child_link_model_->child_joint_models_.push_back(buildRecursive(joint->child_link_model_, link->child_links[i].get(), multi_dof_configs));
00181
00182 return joint;
00183 }
00184
00185 planning_models::KinematicModel::JointModel* planning_models::KinematicModel::constructJointModel(const urdf::Joint *urdf_joint,
00186 const urdf::Link *child_link,
00187 const std::vector<MultiDofConfig>& multi_dof_configs)
00188 {
00189 const MultiDofConfig* joint_config = NULL;
00190 bool found = false;
00191 for(std::vector<MultiDofConfig>::const_iterator it = multi_dof_configs.begin();
00192 it != multi_dof_configs.end();
00193 it++) {
00194 if(it->child_frame_id == child_link->name) {
00195 if(found == true) {
00196 ROS_WARN_STREAM("KinematicModel - two multi-dof joints with same " << it->child_frame_id << " child frame");
00197 } else {
00198 found = true;
00199 joint_config = &(*it);
00200 }
00201 }
00202 }
00203
00204 planning_models::KinematicModel::JointModel* result = NULL;
00205
00206
00207 if(urdf_joint == NULL) {
00208 if(!found) {
00209 ROS_ERROR("Root transform has no multi dof joint config");
00210 return NULL;
00211 }
00212 if(joint_config->type == "Planar") {
00213 result = new PlanarJointModel(joint_config->name, joint_config);
00214 } else if(joint_config->type == "Floating") {
00215 result = new FloatingJointModel(joint_config->name, joint_config);
00216 } else if(joint_config->type == "Fixed"){
00217 result = new FixedJointModel(joint_config->name, joint_config);
00218 } else {
00219 ROS_ERROR_STREAM("Unrecognized type of multi dof joint " << joint_config->type);
00220 return NULL;
00221 }
00222 } else {
00223 switch (urdf_joint->type)
00224 {
00225 case urdf::Joint::REVOLUTE:
00226 {
00227 RevoluteJointModel *j = new RevoluteJointModel(urdf_joint->name, joint_config);
00228 if(urdf_joint->safety)
00229 {
00230 j->setVariableBounds(j->name_, urdf_joint->safety->soft_lower_limit, urdf_joint->safety->soft_upper_limit);
00231 }
00232 else
00233 {
00234 j->setVariableBounds(j->name_, urdf_joint->limits->lower, urdf_joint->limits->upper);
00235 }
00236 j->continuous_ = false;
00237 j->axis_.setValue(urdf_joint->axis.x, urdf_joint->axis.y, urdf_joint->axis.z);
00238 result = j;
00239 }
00240 break;
00241 case urdf::Joint::CONTINUOUS:
00242 {
00243 RevoluteJointModel *j = new RevoluteJointModel(urdf_joint->name, joint_config);
00244 j->continuous_ = true;
00245 j->setVariableBounds(j->name_, -M_PI, M_PI);
00246 j->axis_.setValue(urdf_joint->axis.x, urdf_joint->axis.y, urdf_joint->axis.z);
00247 result = j;
00248 }
00249 break;
00250 case urdf::Joint::PRISMATIC:
00251 {
00252 PrismaticJointModel *j = new PrismaticJointModel(urdf_joint->name, joint_config);
00253 if(urdf_joint->safety)
00254 {
00255 j->setVariableBounds(j->name_, urdf_joint->safety->soft_lower_limit, urdf_joint->safety->soft_upper_limit);
00256 }
00257 else
00258 {
00259 j->setVariableBounds(j->name_, urdf_joint->limits->upper, urdf_joint->limits->lower);
00260 }
00261 j->axis_.setValue(urdf_joint->axis.x, urdf_joint->axis.y, urdf_joint->axis.z);
00262 result = j;
00263 }
00264 break;
00265 case urdf::Joint::FLOATING:
00266 result = new FloatingJointModel(urdf_joint->name, joint_config);
00267 break;
00268 case urdf::Joint::PLANAR:
00269 result = new PlanarJointModel(urdf_joint->name, joint_config);
00270 break;
00271 case urdf::Joint::FIXED:
00272 result = new FixedJointModel(urdf_joint->name, joint_config);
00273 break;
00274 default:
00275 ROS_ERROR("Unknown joint type: %d", (int)urdf_joint->type);
00276 break;
00277 }
00278 }
00279 return result;
00280 }
00281
00282 namespace planning_models
00283 {
00284 static inline btTransform urdfPose2btTransform(const urdf::Pose &pose)
00285 {
00286 return btTransform(btQuaternion(pose.rotation.x, pose.rotation.y, pose.rotation.z, pose.rotation.w),
00287 btVector3(pose.position.x, pose.position.y, pose.position.z));
00288 }
00289 }
00290
00291 planning_models::KinematicModel::LinkModel* planning_models::KinematicModel::constructLinkModel(const urdf::Link *urdf_link)
00292 {
00293 ROS_ASSERT(urdf_link);
00294
00295 LinkModel *result = new LinkModel(this);
00296 result->name_ = urdf_link->name;
00297
00298 if(urdf_link->collision)
00299 result->collision_origin_transform_ = urdfPose2btTransform(urdf_link->collision->origin);
00300 else
00301 result->collision_origin_transform_.setIdentity();
00302
00303 if (urdf_link->parent_joint.get())
00304 result->joint_origin_transform_ = urdfPose2btTransform(urdf_link->parent_joint->parent_to_joint_origin_transform);
00305 else
00306 result->joint_origin_transform_.setIdentity();
00307
00308 if(urdf_link->collision) {
00309 result->shape_ = constructShape(urdf_link->collision->geometry.get());
00310 } else {
00311 shapes::Shape *tmp_shape = NULL;
00312 tmp_shape = new shapes::Sphere(0.0001);
00313 result->shape_ = tmp_shape;
00314 }
00315 return result;
00316 }
00317
00318 shapes::Shape* planning_models::KinematicModel::constructShape(const urdf::Geometry *geom)
00319 {
00320 ROS_ASSERT(geom);
00321
00322 shapes::Shape *result = NULL;
00323 switch (geom->type)
00324 {
00325 case urdf::Geometry::SPHERE:
00326 result = new shapes::Sphere(dynamic_cast<const urdf::Sphere*>(geom)->radius);
00327 break;
00328 case urdf::Geometry::BOX:
00329 {
00330 urdf::Vector3 dim = dynamic_cast<const urdf::Box*>(geom)->dim;
00331 result = new shapes::Box(dim.x, dim.y, dim.z);
00332 }
00333 break;
00334 case urdf::Geometry::CYLINDER:
00335 result = new shapes::Cylinder(dynamic_cast<const urdf::Cylinder*>(geom)->radius,
00336 dynamic_cast<const urdf::Cylinder*>(geom)->length);
00337 break;
00338 case urdf::Geometry::MESH:
00339 {
00340 const urdf::Mesh *mesh = dynamic_cast<const urdf::Mesh*>(geom);
00341 if (!mesh->filename.empty())
00342 {
00343 resource_retriever::Retriever retriever;
00344 resource_retriever::MemoryResource res;
00345 bool ok = true;
00346
00347 try
00348 {
00349 res = retriever.get(mesh->filename);
00350 }
00351 catch (resource_retriever::Exception& e)
00352 {
00353 ROS_ERROR("%s", e.what());
00354 ok = false;
00355 }
00356
00357 if (ok)
00358 {
00359 if (res.size == 0)
00360 ROS_WARN("Retrieved empty mesh for resource '%s'", mesh->filename.c_str());
00361 else
00362 {
00363
00364 Assimp::Importer importer;
00365
00366
00367 std::string hint;
00368 std::size_t pos = mesh->filename.find_last_of(".");
00369 if (pos != std::string::npos)
00370 {
00371 hint = mesh->filename.substr(pos + 1);
00372
00373
00374 if (hint.find("stl") != std::string::npos)
00375 hint = "stl";
00376 }
00377
00378
00379 const aiScene* scene = importer.ReadFileFromMemory(reinterpret_cast<void*>(res.data.get()), res.size,
00380 aiProcess_Triangulate |
00381 aiProcess_JoinIdenticalVertices |
00382 aiProcess_SortByPType, hint.c_str());
00383 btVector3 scale(mesh->scale.x, mesh->scale.y, mesh->scale.z);
00384 if (scene)
00385 {
00386 if (scene->HasMeshes())
00387 {
00388 if (scene->mNumMeshes > 1)
00389 ROS_WARN("More than one mesh specified in resource. Using first one");
00390 result = shapes::createMeshFromAsset(scene->mMeshes[0], scale);
00391 }
00392 else
00393 ROS_ERROR("There is no mesh specified in the indicated resource");
00394 }
00395 else
00396 {
00397 std::string ext;
00398 importer.GetExtensionList(ext);
00399 ROS_ERROR("Failed to import scene containing mesh: %s. Supported extensions are: %s", importer.GetErrorString(), ext.c_str());
00400 }
00401
00402 if (result == NULL)
00403 ROS_ERROR("Failed to load mesh '%s'", mesh->filename.c_str());
00404 else
00405 ROS_DEBUG("Loaded mesh '%s' consisting of %d triangles", mesh->filename.c_str(), static_cast<shapes::Mesh*>(result)->triangleCount);
00406 }
00407 }
00408 }
00409 else
00410 ROS_WARN("Empty mesh filename");
00411 }
00412
00413 break;
00414 default:
00415 ROS_ERROR("Unknown geometry type: %d", (int)geom->type);
00416 break;
00417 }
00418
00419 return result;
00420 }
00421
00422 const planning_models::KinematicModel::JointModel* planning_models::KinematicModel::getRoot(void) const
00423 {
00424 return root_;
00425 }
00426
00427 bool planning_models::KinematicModel::hasJointModel(const std::string &name) const
00428 {
00429 return joint_model_map_.find(name) != joint_model_map_.end();
00430 }
00431
00432 bool planning_models::KinematicModel::hasLinkModel(const std::string &name) const
00433 {
00434 return link_model_map_.find(name) != link_model_map_.end();
00435 }
00436
00437 bool planning_models::KinematicModel::hasModelGroup(const std::string &name) const
00438 {
00439 return joint_model_group_map_.find(name) != joint_model_group_map_.end();
00440 }
00441
00442 const planning_models::KinematicModel::JointModel* planning_models::KinematicModel::getJointModel(const std::string &name) const
00443 {
00444 std::map<std::string, JointModel*>::const_iterator it = joint_model_map_.find(name);
00445 if (it == joint_model_map_.end())
00446 {
00447 ROS_ERROR("Joint '%s' not found", name.c_str());
00448 return NULL;
00449 }
00450 else
00451 return it->second;
00452 }
00453
00454 const planning_models::KinematicModel::LinkModel* planning_models::KinematicModel::getLinkModel(const std::string &name) const
00455 {
00456 std::map<std::string, LinkModel*>::const_iterator it = link_model_map_.find(name);
00457 if (it == link_model_map_.end())
00458 {
00459 ROS_ERROR("Link '%s' not found", name.c_str());
00460 return NULL;
00461 }
00462 else
00463 return it->second;
00464 }
00465
00466 void planning_models::KinematicModel::getModelGroupNames(std::vector<std::string> &groups) const
00467 {
00468 groups.clear();
00469 groups.reserve(joint_model_group_map_.size());
00470 for (std::map<std::string, JointModelGroup*>::const_iterator it = joint_model_group_map_.begin() ; it != joint_model_group_map_.end() ; ++it)
00471 groups.push_back(it->second->name_);
00472 }
00473
00474 void planning_models::KinematicModel::getLinkModelNames(std::vector<std::string> &links) const
00475 {
00476 links.clear();
00477 links.reserve(link_model_vector_.size());
00478 for(unsigned int i = 0; i < link_model_vector_.size(); i++) {
00479 links.push_back(link_model_vector_[i]->getName());
00480 }
00481 }
00482
00483 void planning_models::KinematicModel::getJointModelNames(std::vector<std::string> &joints) const
00484 {
00485 joints.clear();
00486 joints.reserve(joint_model_vector_.size());
00487 for (unsigned int i = 0 ; i < joint_model_vector_.size() ; ++i)
00488 joints.push_back(joint_model_vector_[i]->getName());
00489 }
00490
00491 planning_models::KinematicModel::JointModel* planning_models::KinematicModel::copyRecursive(LinkModel *parent, const LinkModel *link)
00492 {
00493 JointModel *joint = copyJointModel(link->parent_joint_model_);
00494 joint_model_map_[joint->name_] = joint;
00495 for(JointModel::js_type::iterator it = joint->joint_state_equivalents_.begin();
00496 it != joint->joint_state_equivalents_.end();
00497 it++) {
00498 joint_model_map_[it->right] = joint;
00499 }
00500 joint_model_vector_.push_back(joint);
00501 joint->parent_link_model_ = parent;
00502 joint->child_link_model_ = new LinkModel(link);
00503 link_model_map_[joint->child_link_model_->name_] = joint->child_link_model_;
00504 joint->child_link_model_->parent_joint_model_ = joint;
00505
00506 for (unsigned int i = 0 ; i < link->child_joint_models_.size() ; ++i)
00507 joint->child_link_model_->child_joint_models_.push_back(copyRecursive(joint->child_link_model_, link->child_joint_models_[i]->child_link_model_));
00508
00509 return joint;
00510 }
00511
00512 planning_models::KinematicModel::JointModel* planning_models::KinematicModel::copyJointModel(const JointModel *joint)
00513 {
00514 JointModel *newJoint = NULL;
00515
00516 if (dynamic_cast<const FixedJointModel*>(joint))
00517 {
00518 newJoint = new FixedJointModel(dynamic_cast<const FixedJointModel*>(joint));
00519 }
00520 else if (dynamic_cast<const FloatingJointModel*>(joint))
00521 {
00522 newJoint = new FloatingJointModel(dynamic_cast<const FloatingJointModel*>(joint));
00523 }
00524 else if (dynamic_cast<const PlanarJointModel*>(joint))
00525 {
00526 newJoint = new PlanarJointModel(dynamic_cast<const PlanarJointModel*>(joint));
00527 }
00528 else if (dynamic_cast<const PrismaticJointModel*>(joint))
00529 {
00530 newJoint = new PrismaticJointModel(dynamic_cast<const PrismaticJointModel*>(joint));
00531 }
00532 else if (dynamic_cast<const RevoluteJointModel*>(joint))
00533 {
00534 newJoint = new RevoluteJointModel(dynamic_cast<const RevoluteJointModel*>(joint));
00535 }
00536 else
00537 ROS_FATAL("Unimplemented type of joint");
00538
00539 return newJoint;
00540 }
00541
00542 void planning_models::KinematicModel::getChildLinkModels(const KinematicModel::LinkModel *parent,
00543 std::vector<const KinematicModel::LinkModel*> &links) const
00544 {
00545 std::queue<const KinematicModel::LinkModel*> q;
00546 q.push(parent);
00547 while (!q.empty())
00548 {
00549 const KinematicModel::LinkModel* t = q.front();
00550 q.pop();
00551
00552 for (unsigned int i = 0 ; i < t->child_joint_models_.size() ; ++i) {
00553 if (t->child_joint_models_[i]->child_link_model_)
00554 {
00555 links.push_back(t->child_joint_models_[i]->child_link_model_);
00556 q.push(t->child_joint_models_[i]->child_link_model_);
00557 }
00558 }
00559 }
00560 }
00561
00562 void planning_models::KinematicModel::clearAllAttachedBodyModels()
00563 {
00564 exclusiveLock();
00565 for(unsigned int i =0; i < link_model_vector_.size(); i++) {
00566 link_model_vector_[i]->clearAttachedBodyModels();
00567 }
00568 exclusiveUnlock();
00569 }
00570
00571 void planning_models::KinematicModel::clearLinkAttachedBodyModels(const std::string& link_name)
00572 {
00573 exclusiveLock();
00574 if(link_model_map_.find(link_name) == link_model_map_.end()) return;
00575 link_model_map_[link_name]->clearAttachedBodyModels();
00576 exclusiveUnlock();
00577 }
00578
00579 void planning_models::KinematicModel::replaceAttachedBodyModels(const std::string& link_name,
00580 std::vector<AttachedBodyModel*>& attached_body_vector)
00581 {
00582 exclusiveLock();
00583 if(link_model_map_.find(link_name) == link_model_map_.end())
00584 {
00585 ROS_WARN_STREAM("Model has no link named " << link_name << ". This is probably going to introduce a memory leak");
00586 return;
00587 }
00588 link_model_map_[link_name]->replaceAttachedBodyModels(attached_body_vector);
00589 exclusiveUnlock();
00590 }
00591
00592 void planning_models::KinematicModel::clearLinkAttachedBodyModel(const std::string& link_name,
00593 const std::string& att_name)
00594 {
00595 exclusiveLock();
00596 if(link_model_map_.find(link_name) == link_model_map_.end()) return;
00597 link_model_map_[link_name]->clearLinkAttachedBodyModel(att_name);
00598 exclusiveUnlock();
00599 }
00600
00601 void planning_models::KinematicModel::addAttachedBodyModel(const std::string& link_name,
00602 planning_models::KinematicModel::AttachedBodyModel* ab)
00603 {
00604 exclusiveLock();
00605 if(link_model_map_.find(link_name) == link_model_map_.end()) {
00606 ROS_WARN_STREAM("Model has no link named " << link_name << " to attach body to. This is probably going to introduce a memory leak");
00607 return;
00608 }
00609 link_model_map_[link_name]->addAttachedBodyModel(ab);
00610 exclusiveUnlock();
00611 }
00612
00613
00614
00615
00616 planning_models::KinematicModel::JointModel::JointModel(const std::string& n) :
00617 name_(n), parent_link_model_(NULL), child_link_model_(NULL)
00618 {
00619 }
00620
00621 void planning_models::KinematicModel::JointModel::initialize(const std::vector<std::string>& local_joint_names,
00622 const MultiDofConfig* config)
00623 {
00624 for(std::vector<std::string>::const_iterator it = local_joint_names.begin();
00625 it != local_joint_names.end();
00626 it++) {
00627 joint_state_equivalents_.insert(js_type::value_type(*it,*it));
00628 }
00629 if(config != NULL) {
00630 for(std::map<std::string, std::string>::const_iterator it = config->name_equivalents.begin();
00631 it != config->name_equivalents.end();
00632 it++) {
00633 js_type::left_iterator lit = joint_state_equivalents_.left.find(it->first);
00634 if(lit != joint_state_equivalents_.left.end()) {
00635 joint_state_equivalents_.left.replace_data(lit, it->second);
00636 }
00637 }
00638 parent_frame_id_ = config->parent_frame_id;
00639 child_frame_id_ = config->child_frame_id;
00640 }
00641 unsigned int i = 0;
00642 for(std::vector<std::string>::const_iterator it = local_joint_names.begin();
00643 it != local_joint_names.end();
00644 it++, i++) {
00645 computation_order_map_index_[i] = joint_state_equivalents_.left.at(*it);
00646 }
00647
00648 for(js_type::iterator it = joint_state_equivalents_.begin();
00649 it != joint_state_equivalents_.end();
00650 it++) {
00651 setVariableBounds(it->right,-DBL_MAX,DBL_MAX);
00652 }
00653 }
00654
00655 planning_models::KinematicModel::JointModel::JointModel(const JointModel* joint) {
00656 name_ = joint->name_;
00657 parent_frame_id_ = joint->parent_frame_id_;
00658 child_frame_id_ = joint->child_frame_id_;
00659 joint_state_equivalents_ = joint->joint_state_equivalents_;
00660 joint_state_bounds_ = joint->joint_state_bounds_;
00661 }
00662
00663 planning_models::KinematicModel::JointModel::~JointModel(void)
00664 {
00665 if (child_link_model_)
00666 delete child_link_model_;
00667 }
00668
00669 std::string planning_models::KinematicModel::JointModel::getEquiv(const std::string name) const {
00670 js_type::left_const_iterator lit = joint_state_equivalents_.left.find(name);
00671 if(lit != joint_state_equivalents_.left.end()) {
00672 return lit->second;
00673 } else {
00674 return "";
00675 }
00676 }
00677
00678 void planning_models::KinematicModel::JointModel::setVariableBounds(std::string variable, double low, double high) {
00679 if(joint_state_equivalents_.right.find(variable) == joint_state_equivalents_.right.end()) {
00680 ROS_WARN_STREAM("Can't find variable " << variable << " to set bounds");
00681 return;
00682 }
00683 joint_state_bounds_[joint_state_equivalents_.right.at(variable)] = std::pair<double,double>(low, high);
00684 }
00685
00686 std::pair<double, double> planning_models::KinematicModel::JointModel::getVariableBounds(std::string variable) const{
00687 if(joint_state_equivalents_.right.find(variable) == joint_state_equivalents_.right.end()) {
00688 ROS_WARN_STREAM("Can't find variable " << variable << " to get bounds");
00689 return std::pair<double,double>(0.0,0.0);
00690 }
00691 std::string config_name = joint_state_equivalents_.right.find(variable)->second;
00692 if(joint_state_bounds_.find(config_name) == joint_state_bounds_.end()) {
00693 ROS_WARN_STREAM("No joint bounds for " << config_name);
00694 return std::pair<double,double>(0.0,0.0);
00695 }
00696 return joint_state_bounds_.find(config_name)->second;
00697 }
00698
00699 planning_models::KinematicModel::PlanarJointModel::PlanarJointModel(const std::string& name, const MultiDofConfig* multi_dof_config)
00700 : JointModel(name)
00701 {
00702 if(multi_dof_config == NULL) {
00703 ROS_WARN("Planar joint needs a config");
00704 return;
00705 }
00706 std::vector<std::string> local_names;
00707 local_names.push_back("planar_x");
00708 local_names.push_back("planar_y");
00709 local_names.push_back("planar_th");
00710 initialize(local_names, multi_dof_config);
00711 setVariableBounds(getEquiv("planar_x"),-DBL_MAX,DBL_MAX);
00712 setVariableBounds(getEquiv("planar_y"),-DBL_MAX,DBL_MAX);
00713 setVariableBounds(getEquiv("planar_th"),-M_PI,M_PI);
00714 }
00715
00716 btTransform planning_models::KinematicModel::PlanarJointModel::computeTransform(const std::vector<double>& joint_values) const
00717 {
00718 btTransform variable_transform;
00719 variable_transform.setIdentity();
00720 if(joint_values.size() != 3) {
00721 ROS_ERROR("Planar joint given too few values");
00722 return variable_transform;
00723 }
00724 variable_transform.setOrigin(btVector3(joint_values[0],
00725 joint_values[1],
00726 0.0));
00727 variable_transform.setRotation(btQuaternion(btVector3(0.0, 0.0, 1.0),
00728 joint_values[2]));
00729 return variable_transform;
00730 }
00731
00732 std::vector<double> planning_models::KinematicModel::PlanarJointModel::computeJointStateValues(const btTransform& transform) const
00733 {
00734 std::vector<double> ret;
00735 ret.push_back(transform.getOrigin().x());
00736 ret.push_back(transform.getOrigin().y());
00737 ret.push_back(transform.getRotation().getAngle()*transform.getRotation().getAxis().z());
00738 return ret;
00739 }
00740
00741 planning_models::KinematicModel::FloatingJointModel::FloatingJointModel(const std::string& name,
00742 const MultiDofConfig* multi_dof_config)
00743 : JointModel(name)
00744 {
00745 if(multi_dof_config == NULL) {
00746 ROS_WARN("Planar joint needs a config");
00747 return;
00748 }
00749 std::vector<std::string> local_names;
00750 local_names.push_back("floating_trans_x");
00751 local_names.push_back("floating_trans_y");
00752 local_names.push_back("floating_trans_z");
00753 local_names.push_back("floating_rot_x");
00754 local_names.push_back("floating_rot_y");
00755 local_names.push_back("floating_rot_z");
00756 local_names.push_back("floating_rot_w");
00757 initialize(local_names, multi_dof_config);
00758
00759 setVariableBounds(getEquiv("floating_trans_x"),-DBL_MAX,DBL_MAX);
00760 setVariableBounds(getEquiv("floating_trans_y"),-DBL_MAX,DBL_MAX);
00761 setVariableBounds(getEquiv("floating_trans_z"),-DBL_MAX,DBL_MAX);
00762 setVariableBounds(getEquiv("floating_rot_x"),-1.0,1.0);
00763 setVariableBounds(getEquiv("floating_rot_y"),-1.0,1.0);
00764 setVariableBounds(getEquiv("floating_rot_z"),-1.0,1.0);
00765 setVariableBounds(getEquiv("floating_rot_w"),-1.0,1.0);
00766 }
00767
00768 btTransform planning_models::KinematicModel::FloatingJointModel::computeTransform(const std::vector<double>& joint_values) const
00769 {
00770 btTransform variable_transform;
00771 variable_transform.setIdentity();
00772 if(joint_values.size() != 7) {
00773 ROS_ERROR("Floating joint given too few values");
00774 return variable_transform;
00775 }
00776 variable_transform.setOrigin(btVector3(joint_values[0], joint_values[1], joint_values[2]));
00777 variable_transform.setRotation(btQuaternion(joint_values[3], joint_values[4], joint_values[5], joint_values[6]));
00778 return variable_transform;
00779 }
00780
00781 std::vector<double> planning_models::KinematicModel::FloatingJointModel::computeJointStateValues(const btTransform& transform) const
00782 {
00783 std::vector<double> ret;
00784 ret.push_back(transform.getOrigin().x());
00785 ret.push_back(transform.getOrigin().y());
00786 ret.push_back(transform.getOrigin().z());
00787 ret.push_back(transform.getRotation().x());
00788 ret.push_back(transform.getRotation().y());
00789 ret.push_back(transform.getRotation().z());
00790 ret.push_back(transform.getRotation().w());
00791 return ret;
00792 }
00793
00794 planning_models::KinematicModel::PrismaticJointModel::PrismaticJointModel(const std::string& name,
00795 const MultiDofConfig* multi_dof_config)
00796 : JointModel(name),
00797 axis_(0.0, 0.0, 0.0)
00798 {
00799 std::vector<std::string> local_names(1,name);
00800 initialize(local_names, multi_dof_config);
00801 }
00802
00803 btTransform planning_models::KinematicModel::PrismaticJointModel::computeTransform(const std::vector<double>& joint_values) const
00804 {
00805 btTransform variable_transform;
00806 variable_transform.setIdentity();
00807 if(joint_values.size() != 1) {
00808 ROS_ERROR("Prismatic joint given wrong number of values");
00809 return variable_transform;
00810 }
00811 variable_transform.setOrigin(axis_*joint_values[0]);
00812 return variable_transform;
00813 }
00814
00815 std::vector<double> planning_models::KinematicModel::PrismaticJointModel::computeJointStateValues(const btTransform& transform) const
00816 {
00817 std::vector<double> ret;
00818 ret.push_back(transform.getOrigin().dot(axis_));
00819 return ret;
00820 }
00821
00822 planning_models::KinematicModel::RevoluteJointModel::RevoluteJointModel(const std::string& name,
00823 const MultiDofConfig* multi_dof_config)
00824 : JointModel(name),
00825 axis_(0.0, 0.0, 0.0),
00826 continuous_(false)
00827 {
00828 std::vector<std::string> local_names(1,name);
00829 initialize(local_names, multi_dof_config);
00830 }
00831
00832 btTransform planning_models::KinematicModel::RevoluteJointModel::computeTransform(const std::vector<double>& joint_values) const
00833 {
00834 btTransform variable_transform;
00835 variable_transform.setIdentity();
00836 if(joint_values.size() != 1) {
00837 ROS_ERROR("Revolute joint given wrong number of values");
00838 return variable_transform;
00839 }
00840 double val = joint_values.front();
00841 if(continuous_) {
00842 val = angles::normalize_angle(val);
00843 }
00844 variable_transform.setRotation(btQuaternion(axis_,val));
00845 return variable_transform;
00846 }
00847
00848 std::vector<double> planning_models::KinematicModel::RevoluteJointModel::computeJointStateValues(const btTransform& transform) const
00849 {
00850 std::vector<double> ret;
00851 ret.push_back(transform.getRotation().getAngle()*transform.getRotation().getAxis().dot(axis_));
00852 return ret;
00853 }
00854
00855
00856
00857 planning_models::KinematicModel::LinkModel::LinkModel(const KinematicModel* kinematic_model) :
00858 kinematic_model_(kinematic_model),
00859 parent_joint_model_(NULL),
00860 shape_(NULL)
00861 {
00862 joint_origin_transform_.setIdentity();
00863 collision_origin_transform_.setIdentity();
00864 }
00865
00866 planning_models::KinematicModel::LinkModel::LinkModel(const LinkModel* link_model) :
00867 name_(link_model->name_),
00868 kinematic_model_(link_model->kinematic_model_),
00869 joint_origin_transform_(link_model->joint_origin_transform_),
00870 collision_origin_transform_(link_model->collision_origin_transform_)
00871 {
00872 shape_ = shapes::cloneShape(link_model->shape_);
00873 for (unsigned int i = 0 ; i < link_model->attached_body_models_.size() ; ++i)
00874 {
00875 std::vector<shapes::Shape*> shapes;
00876 for(unsigned int j = 0; j < link_model->attached_body_models_[i]->getShapes().size(); j++) {
00877 shapes.push_back(shapes::cloneShape(link_model->attached_body_models_[i]->getShapes()[j]));
00878 }
00879 AttachedBodyModel *ab = new AttachedBodyModel(this,
00880 link_model->attached_body_models_[i]->getName(),
00881 link_model->attached_body_models_[i]->getAttachedBodyFixedTransforms(),
00882 link_model->attached_body_models_[i]->getTouchLinks(),
00883 shapes);
00884 attached_body_models_.push_back(ab);
00885 }
00886 }
00887
00888 planning_models::KinematicModel::LinkModel::~LinkModel(void)
00889 {
00890 if (shape_)
00891 delete shape_;
00892 for (unsigned int i = 0 ; i < child_joint_models_.size() ; ++i)
00893 delete child_joint_models_[i];
00894 for (unsigned int i = 0 ; i < attached_body_models_.size() ; ++i)
00895 delete attached_body_models_[i];
00896 }
00897
00898 void planning_models::KinematicModel::LinkModel::clearAttachedBodyModels()
00899 {
00900
00901 for (unsigned int i = 0 ; i < attached_body_models_.size() ; ++i)
00902 delete attached_body_models_[i];
00903 attached_body_models_.clear();
00904 }
00905
00906 void planning_models::KinematicModel::LinkModel::replaceAttachedBodyModels(std::vector<AttachedBodyModel*>& attached_body_vector)
00907 {
00908
00909 for (unsigned int i = 0 ; i < attached_body_models_.size() ; ++i)
00910 delete attached_body_models_[i];
00911 attached_body_models_.clear();
00912
00913 attached_body_models_ = attached_body_vector;
00914 }
00915
00916 void planning_models::KinematicModel::LinkModel::clearLinkAttachedBodyModel(const std::string& att_name)
00917 {
00918 for(std::vector<AttachedBodyModel*>::iterator it = attached_body_models_.begin();
00919 it != attached_body_models_.end();
00920 it++) {
00921 if((*it)->getName() == att_name) {
00922 delete (*it);
00923 attached_body_models_.erase(it);
00924 return;
00925 }
00926 }
00927 }
00928
00929 void planning_models::KinematicModel::LinkModel::addAttachedBodyModel(planning_models::KinematicModel::AttachedBodyModel* ab)
00930 {
00931 attached_body_models_.push_back(ab);
00932 }
00933
00934
00935
00936 planning_models::KinematicModel::AttachedBodyModel::AttachedBodyModel(const LinkModel *link,
00937 const std::string& nid,
00938 const std::vector<btTransform>& attach_trans,
00939 const std::vector<std::string>& touch_links,
00940 std::vector<shapes::Shape*>& shapes)
00941
00942 : attached_link_model_(link),
00943 id_(nid)
00944 {
00945 attach_trans_ = attach_trans;
00946 touch_links_ = touch_links;
00947 shapes_ = shapes;
00948 }
00949
00950 planning_models::KinematicModel::AttachedBodyModel::~AttachedBodyModel(void)
00951 {
00952 for(unsigned int i = 0; i < shapes_.size(); i++) {
00953 delete shapes_[i];
00954 }
00955 }
00956
00957
00958 planning_models::KinematicModel::JointModelGroup::JointModelGroup(const std::string& group_name,
00959 const std::vector<const JointModel*> &group_joints) :
00960
00961 name_(group_name)
00962 {
00963 joint_model_vector_ = group_joints;
00964 joint_model_name_vector_.resize(group_joints.size());
00965
00966 for (unsigned int i = 0 ; i < group_joints.size() ; ++i)
00967 {
00968 joint_model_name_vector_[i] = group_joints[i]->getName();
00969 joint_model_map_[group_joints[i]->getName()] = group_joints[i];
00970 }
00971
00972 for (unsigned int i = 0 ; i < group_joints.size() ; ++i)
00973 {
00974 bool found = false;
00975 const JointModel *joint = joint_model_vector_[i];
00976 while (joint->parent_link_model_)
00977 {
00978 joint = joint->getParentLinkModel()->getParentJointModel();
00979 if (hasJointModel(joint->name_))
00980 {
00981 found = true;
00982 break;
00983 }
00984 }
00985
00986 if (!found)
00987 joint_roots_.push_back(joint_model_vector_[i]);
00988 }
00989
00990 for (unsigned int i = 0 ; i < joint_roots_.size() ; ++i)
00991 {
00992 std::queue<const LinkModel*> links;
00993 links.push(joint_roots_[i]->getChildLinkModel());
00994
00995 while (!links.empty())
00996 {
00997 const LinkModel *link = links.front();
00998 if(link == NULL) {
00999 ROS_WARN("Null link in group creation");
01000 }
01001 links.pop();
01002 updated_link_model_vector_.push_back(link);
01003 for (unsigned int i = 0 ; i < link->getChildJointModels().size() ; ++i)
01004 links.push(link->getChildJointModels()[i]->getChildLinkModel());
01005 }
01006 }
01007 }
01008
01009 planning_models::KinematicModel::JointModelGroup::~JointModelGroup(void)
01010 {
01011 }
01012
01013 bool planning_models::KinematicModel::JointModelGroup::hasJointModel(const std::string &joint) const
01014 {
01015 return joint_model_map_.find(joint) != joint_model_map_.end();
01016 }
01017
01018 const planning_models::KinematicModel::JointModel* planning_models::KinematicModel::JointModelGroup::getJointModel(const std::string &name)
01019 {
01020 if(!hasJointModel(name)) return NULL;
01021 return joint_model_map_.find(name)->second;
01022 }
01023