planning_models::KinematicModel::LinkModel* planning_models::KinematicModel::constructLinkModel(const urdf::Link *urdf_link) { ROS_ASSERT(urdf_link); LinkModel *result = new LinkModel(this); result->name_ = urdf_link->name; if(urdf_link->collision && urdf_link->collision->geometry) { result->collision_origin_transform_ = urdfPose2TFTransform(urdf_link->collision->origin); result->shape_ = constructShape(urdf_link->collision->geometry.get()); } else if(urdf_link->visual && urdf_link->visual->geometry){ result->collision_origin_transform_ = urdfPose2TFTransform(urdf_link->visual->origin); result->shape_ = constructShape(urdf_link->visual->geometry.get()); } else { result->collision_origin_transform_.setIdentity(); result->shape_ = NULL; } if (urdf_link->parent_joint.get()) { result->joint_origin_transform_ = urdfPose2TFTransform(urdf_link->parent_joint->parent_to_joint_origin_transform); ROS_DEBUG_STREAM("Setting joint origin for " << result->name_ << " to " << result->joint_origin_transform_.getOrigin().x() << " " << result->joint_origin_transform_.getOrigin().y() << " " << result->joint_origin_transform_.getOrigin().z()); } else { ROS_DEBUG_STREAM("Setting joint origin to identity for " << result->name_); result->joint_origin_transform_.setIdentity(); } return result; }
bool robot_self_filter_color::SelfMask::configure(const std::vector<LinkInfo> &links) { // in case configure was called before, we free the memory freeMemory(); sensor_pos_.setValue(0, 0, 0); std::string content; boost::shared_ptr<urdf::Model> urdfModel; if (nh_.getParam("robot_description", content)) { urdfModel = boost::shared_ptr<urdf::Model>(new urdf::Model()); if (!urdfModel->initString(content)) { ROS_ERROR("Unable to parse URDF description!"); return false; } } else { ROS_ERROR("Robot model not found! Did you remap 'robot_description'?"); return false; } std::stringstream missing; // from the geometric model, find the shape of each link of interest // and create a body from it, one that knows about poses and can // check for point inclusion for (unsigned int i = 0 ; i < links.size() ; ++i) { const urdf::Link *link = urdfModel->getLink(links[i].name).get(); if (!link) { missing << " " << links[i].name; continue; } if (!(link->collision && link->collision->geometry)) { ROS_WARN("No collision geometry specified for link '%s'", links[i].name.c_str()); continue; } shapes::Shape *shape = constructShape(link->collision->geometry.get()); if (!shape) { ROS_ERROR("Unable to construct collision shape for link '%s'", links[i].name.c_str()); continue; } SeeLink sl; sl.body = bodies::createBodyFromShape(shape); if (sl.body) { sl.name = links[i].name; // collision models may have an offset, in addition to what TF gives // so we keep it around sl.constTransf = urdfPose2TFTransform(link->collision->origin); sl.body->setScale(links[i].scale); sl.body->setPadding(links[i].padding); ROS_DEBUG_STREAM("Self see link name " << links[i].name << " padding " << links[i].padding); sl.volume = sl.body->computeVolume(); sl.unscaledBody = bodies::createBodyFromShape(shape); bodies_.push_back(sl); } else ROS_WARN("Unable to create point inclusion body for link '%s'", links[i].name.c_str()); delete shape; } if (missing.str().size() > 0) ROS_WARN("Some links were included for self mask but they do not exist in the model:%s", missing.str().c_str()); if (bodies_.empty()) ROS_WARN("No robot links will be checked for self mask"); // put larger volume bodies first -- higher chances of containing a point std::sort(bodies_.begin(), bodies_.end(), SortBodies()); bspheres_.resize(bodies_.size()); bspheresRadius2_.resize(bodies_.size()); for (unsigned int i = 0 ; i < bodies_.size() ; ++i) ROS_DEBUG("Self mask includes link %s with volume %f", bodies_[i].name.c_str(), bodies_[i].volume); //ROS_INFO("Self filter using %f padding and %f scaling", padd, scale); return true; }