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_environment/models/collision_models.h"
00038 #include "planning_environment/models/model_utils.h"
00039 #include "planning_environment/util/construct_object.h"
00040 #include <collision_space/environmentODE.h>
00041 #include <sstream>
00042 #include <vector>
00043 #include <geometric_shapes/shape_operations.h>
00044 #include <geometric_shapes/body_operations.h>
00045 #include <boost/foreach.hpp>
00046 #include <rosbag/bag.h>
00047 #include <rosbag/view.h>
00048
00049 inline static std::string stripTFPrefix(const std::string& s) {
00050
00051 if(s.find_last_of('/') == std::string::npos) {
00052 return s;
00053 }
00054 return s.substr(s.find_last_of('/')+1);
00055 }
00056
00057 planning_environment::CollisionModels::CollisionModels(const std::string &description) : RobotModels(description)
00058 {
00059 planning_scene_set_ = false;
00060 loadCollisionFromParamServer();
00061 }
00062
00063 planning_environment::CollisionModels::CollisionModels(boost::shared_ptr<urdf::Model> urdf,
00064 planning_models::KinematicModel* kmodel,
00065 collision_space::EnvironmentModel* ode_collision_model) : RobotModels(urdf, kmodel)
00066 {
00067 ode_collision_model_ = ode_collision_model;
00068 }
00069
00070 planning_environment::CollisionModels::~CollisionModels(void)
00071 {
00072 deleteAllStaticObjects();
00073 deleteAllAttachedObjects();
00074 shapes::deleteShapeVector(collision_map_shapes_);
00075 delete ode_collision_model_;
00076 }
00077
00078 void planning_environment::CollisionModels::setupModelFromParamServer(collision_space::EnvironmentModel* model)
00079 {
00080 XmlRpc::XmlRpcValue coll_ops;
00081
00082
00083 if(!nh_.hasParam(description_ + "_planning/default_collision_operations")) {
00084 ROS_WARN("No default collision operations specified");
00085 } else {
00086
00087 nh_.getParam(description_ + "_planning/default_collision_operations", coll_ops);
00088
00089 if(coll_ops.getType() != XmlRpc::XmlRpcValue::TypeArray) {
00090 ROS_WARN("default_collision_operations is not an array");
00091 return;
00092 }
00093
00094 if(coll_ops.size() == 0) {
00095 ROS_WARN("No collision operations in default collision operations");
00096 return;
00097 }
00098
00099 for(int i = 0; i < coll_ops.size(); i++) {
00100 if(!coll_ops[i].hasMember("object1") || !coll_ops[i].hasMember("object2") || !coll_ops[i].hasMember("operation")) {
00101 ROS_WARN("All collision operations must have two objects and an operation");
00102 continue;
00103 }
00104 arm_navigation_msgs::CollisionOperation collision_operation;
00105 collision_operation.object1 = std::string(coll_ops[i]["object1"]);
00106 collision_operation.object2 = std::string(coll_ops[i]["object2"]);
00107 std::string operation = std::string(coll_ops[i]["operation"]);
00108 if(operation == "enable") {
00109 collision_operation.operation = arm_navigation_msgs::CollisionOperation::ENABLE;
00110 } else if(operation == "disable") {
00111 collision_operation.operation = arm_navigation_msgs::CollisionOperation::DISABLE;
00112 } else {
00113 ROS_WARN_STREAM("Unrecognized collision operation " << operation << ". Must be enable or disable");
00114 continue;
00115 }
00116 default_collision_operations_.push_back(collision_operation);
00117 }
00118 }
00119
00120 nh_.param(description_ + "_planning/default_robot_padding", default_padd_, 0.01);
00121 nh_.param(description_ + "_planning/default_robot_scale", default_scale_, 1.0);
00122 nh_.param(description_ + "_planning/default_object_padding", object_padd_, 0.02);
00123 nh_.param(description_ + "_planning/default_attached_padding", attached_padd_, 0.05);
00124
00125 const std::vector<planning_models::KinematicModel::LinkModel*>& coll_links = kmodel_->getLinkModelsWithCollisionGeometry();
00126 std::map<std::string, double> default_link_padding_map;
00127 std::vector<std::string> coll_names;
00128 for(unsigned int i = 0; i < coll_links.size(); i++) {
00129 default_link_padding_map[coll_links[i]->getName()] = default_padd_;
00130 coll_names.push_back(coll_links[i]->getName());
00131 }
00132
00133 ros::NodeHandle priv("~");
00134
00135 if(priv.hasParam("link_padding")) {
00136 XmlRpc::XmlRpcValue link_padding_xml;
00137 priv.getParam("link_padding", link_padding_xml);
00138 if(link_padding_xml.getType() != XmlRpc::XmlRpcValue::TypeArray) {
00139 ROS_WARN("link_padding is not an array");
00140 } else if(link_padding_xml.size() == 0) {
00141 ROS_WARN("No links specified in link_padding");
00142 } else {
00143 for(int i = 0; i < link_padding_xml.size(); i++) {
00144 if(!link_padding_xml[i].hasMember("link") || !link_padding_xml[i].hasMember("padding")) {
00145 ROS_WARN("Each entry in link padding must specify a link and a padding");
00146 continue;
00147 }
00148 std::string link = std::string(link_padding_xml[i]["link"]);
00149 double padding = link_padding_xml[i]["padding"];
00150
00151 default_link_padding_map[link] = padding;
00152 }
00153 }
00154 }
00155
00156
00157 collision_space::EnvironmentModel::AllowedCollisionMatrix default_collision_matrix(coll_names,false);
00158
00159 for(std::vector<arm_navigation_msgs::CollisionOperation>::iterator it = default_collision_operations_.begin();
00160 it != default_collision_operations_.end();
00161 it++) {
00162 std::vector<std::string> svec1;
00163 std::vector<std::string> svec2;
00164 if(kmodel_->getModelGroup((*it).object1)) {
00165 svec1 = kmodel_->getModelGroup((*it).object1)->getGroupLinkNames();
00166 } else {
00167 svec1.push_back((*it).object1);
00168 }
00169 if(kmodel_->getModelGroup((*it).object2)) {
00170 svec2 = kmodel_->getModelGroup((*it).object2)->getGroupLinkNames();
00171 } else {
00172 svec2.push_back((*it).object2);
00173 }
00174 default_collision_matrix.changeEntry(svec1, svec2, (*it).operation != arm_navigation_msgs::CollisionOperation::ENABLE);
00175 }
00176
00177 model->lock();
00178 model->setRobotModel(kmodel_, default_collision_matrix, default_link_padding_map, default_padd_, default_scale_);
00179
00180 for (unsigned int i = 0 ; i < bounding_planes_.size() / 4 ; ++i)
00181 {
00182 shapes::Plane *plane = new shapes::Plane(bounding_planes_[i * 4], bounding_planes_[i * 4 + 1], bounding_planes_[i * 4 + 2], bounding_planes_[i * 4 + 3]);
00183 model->addObject("bounds", plane);
00184 ROS_INFO("Added static plane %fx + %fy + %fz + %f = 0 for model", bounding_planes_[i * 4], bounding_planes_[i * 4 + 1], bounding_planes_[i * 4 + 2], bounding_planes_[i * 4 + 3]);
00185 }
00186
00187 model->unlock();
00188 }
00189
00190 void planning_environment::CollisionModels::loadCollisionFromParamServer()
00191 {
00192
00193 bounding_planes_.clear();
00194
00195 std::string planes;
00196 nh_.param<std::string>("bounding_planes", planes, std::string());
00197
00198 std::stringstream ss(planes);
00199 if (!planes.empty())
00200 while (ss.good() && !ss.eof())
00201 {
00202 double value;
00203 ss >> value;
00204 bounding_planes_.push_back(value);
00205 }
00206 if (bounding_planes_.size() % 4 != 0)
00207 {
00208 ROS_WARN("~bounding_planes must be a list of 4-tuples (a b c d) that define planes ax+by+cz+d=0");
00209 bounding_planes_.resize(bounding_planes_.size() - (bounding_planes_.size() % 4));
00210 }
00211
00212 if (loadedModels())
00213 {
00214 ode_collision_model_ = new collision_space::EnvironmentModelODE();
00215 setupModelFromParamServer(ode_collision_model_);
00216
00217
00218
00219 } else {
00220 ROS_WARN("Models not loaded");
00221 }
00222 }
00223
00227
00228 planning_models::KinematicState*
00229 planning_environment::CollisionModels::setPlanningScene(const arm_navigation_msgs::PlanningScene& planning_scene) {
00230
00231 if(planning_scene_set_) {
00232 ROS_WARN("Must revert before setting planning scene again");
00233 return NULL;
00234 }
00235
00236 deleteAllStaticObjects();
00237 deleteAllAttachedObjects();
00238 revertAllowedCollisionToDefault();
00239 revertCollisionSpacePaddingToDefault();
00240 clearAllowedContacts();
00241
00242 scene_transform_map_.clear();
00243
00244 for(unsigned int i = 0; i < planning_scene.fixed_frame_transforms.size(); i++) {
00245 if(planning_scene.fixed_frame_transforms[i].header.frame_id != getWorldFrameId()) {
00246 ROS_WARN_STREAM("Fixed transform for " << planning_scene.fixed_frame_transforms[i].child_frame_id
00247 << " has non-fixed header frame " << planning_scene.fixed_frame_transforms[i].header.frame_id);
00248 return NULL;
00249 }
00250 scene_transform_map_[planning_scene.fixed_frame_transforms[i].child_frame_id] = planning_scene.fixed_frame_transforms[i];
00251 }
00252
00253 planning_models::KinematicState* state = new planning_models::KinematicState(kmodel_);
00254 bool complete = setRobotStateAndComputeTransforms(planning_scene.robot_state, *state);
00255 if(!complete) {
00256 ROS_WARN_STREAM("Incomplete robot state in setPlanningScene");
00257 delete state;
00258 return NULL;
00259 }
00260 std::vector<arm_navigation_msgs::CollisionObject> conv_objects;
00261 std::vector<arm_navigation_msgs::AttachedCollisionObject> conv_att_objects;
00262
00263
00264 for(unsigned int i = 0; i < planning_scene.collision_objects.size(); i++) {
00265 if(planning_scene.collision_objects[i].operation.operation != arm_navigation_msgs::CollisionObjectOperation::ADD) {
00266 ROS_WARN_STREAM("Planning scene shouldn't have collision operations other than add");
00267 delete state;
00268 return NULL;
00269 }
00270 conv_objects.push_back(planning_scene.collision_objects[i]);
00271 convertCollisionObjectToNewWorldFrame(*state, conv_objects.back());
00272 }
00273 for(unsigned int i = 0; i < planning_scene.attached_collision_objects.size(); i++) {
00274 if(planning_scene.attached_collision_objects[i].object.operation.operation != arm_navigation_msgs::CollisionObjectOperation::ADD) {
00275 ROS_WARN_STREAM("Planning scene shouldn't have collision operations other than add");
00276 delete state;
00277 return NULL;
00278 }
00279 conv_att_objects.push_back(planning_scene.attached_collision_objects[i]);
00280 convertAttachedCollisionObjectToNewWorldFrame(*state, conv_att_objects.back());
00281 }
00282
00283
00284 delete state;
00285
00286 for(unsigned int i = 0; i < conv_objects.size(); i++) {
00287 addStaticObject(conv_objects[i]);
00288 }
00289 for(unsigned int i = 0; i < conv_att_objects.size(); i++) {
00290 addAttachedObject(conv_att_objects[i]);
00291 }
00292
00293
00294 state = new planning_models::KinematicState(kmodel_);
00295 setRobotStateAndComputeTransforms(planning_scene.robot_state, *state);
00296
00297
00298 updateAttachedBodyPoses(*state);
00299
00300
00301
00302 setCollisionMap(planning_scene.collision_map, true);
00303
00304 if(planning_scene.link_padding.size() > 0) {
00305 applyLinkPaddingToCollisionSpace(planning_scene.link_padding);
00306 }
00307
00308 std::vector<arm_navigation_msgs::AllowedContactSpecification> acmv = planning_scene.allowed_contacts;
00309 for(unsigned int i = 0; i < planning_scene.allowed_contacts.size(); i++) {
00310
00311 if(!convertPoseGivenWorldTransform(*state,
00312 getWorldFrameId(),
00313 planning_scene.allowed_contacts[i].pose_stamped.header,
00314 planning_scene.allowed_contacts[i].pose_stamped.pose,
00315 acmv[i].pose_stamped)) {
00316 ROS_WARN_STREAM("Can't transform allowed contact from frame " << planning_scene.allowed_contacts[i].pose_stamped.header.frame_id
00317 << " into " << getWorldFrameId());
00318 }
00319 }
00320
00321 if(!planning_scene.allowed_contacts.empty()) {
00322 std::vector<collision_space::EnvironmentModel::AllowedContact> acv;
00323 convertAllowedContactSpecificationMsgToAllowedContactVector(acmv,
00324 acv);
00325 ode_collision_model_->lock();
00326 ode_collision_model_->setAllowedContacts(acv);
00327 ode_collision_model_->unlock();
00328 }
00329
00330 if(!planning_scene.allowed_collision_matrix.link_names.empty()) {
00331 ode_collision_model_->lock();
00332 ode_collision_model_->setAlteredCollisionMatrix(convertFromACMMsgToACM(planning_scene.allowed_collision_matrix));
00333 ode_collision_model_->unlock();
00334 }
00335 planning_scene_set_ = true;
00336 return state;
00337 }
00338
00339 void planning_environment::CollisionModels::revertPlanningScene(planning_models::KinematicState* ks) {
00340 bodiesLock();
00341 planning_scene_set_ = false;
00342 delete ks;
00343 deleteAllStaticObjects();
00344 deleteAllAttachedObjects();
00345 revertAllowedCollisionToDefault();
00346 revertCollisionSpacePaddingToDefault();
00347 clearAllowedContacts();
00348 bodiesUnlock();
00349 }
00350
00354
00355 bool planning_environment::CollisionModels::convertPoseGivenWorldTransform(const planning_models::KinematicState& state,
00356 const std::string& des_frame_id,
00357 const std_msgs::Header& header,
00358 const geometry_msgs::Pose& pose,
00359 geometry_msgs::PoseStamped& ret_pose) const
00360 {
00361 ret_pose.header = header;
00362 ret_pose.pose = pose;
00363
00364 std::string r_header_frame_id = stripTFPrefix(header.frame_id);
00365 std::string r_des_frame_id = stripTFPrefix(des_frame_id);
00366
00367 bool header_is_fixed_frame = (r_header_frame_id == getWorldFrameId());
00368 bool des_is_fixed_frame = (r_des_frame_id == getWorldFrameId());
00369
00370
00371
00372 if(header_is_fixed_frame && des_is_fixed_frame) {
00373 return true;
00374 }
00375 const planning_models::KinematicState::LinkState* header_link_state = state.getLinkState(r_header_frame_id);
00376 const planning_models::KinematicState::LinkState* des_link_state = state.getLinkState(r_des_frame_id);
00377
00378 bool header_is_robot_frame = (header_link_state != NULL);
00379 bool des_is_robot_frame = (des_link_state != NULL);
00380
00381 bool header_is_other_frame = !header_is_fixed_frame && !header_is_robot_frame;
00382 bool des_is_other_frame = !des_is_fixed_frame && !des_is_robot_frame;
00383
00384
00385
00386 if(des_is_other_frame) {
00387 ROS_WARN_STREAM("Shouldn't be transforming into non-fixed non-robot frame " << r_des_frame_id);
00388 return false;
00389 }
00390
00391
00392
00393 if(header_is_other_frame) {
00394 if(scene_transform_map_.find(r_header_frame_id) == scene_transform_map_.end()) {
00395 ROS_WARN_STREAM("Trying to transform from other frame " << r_header_frame_id << " to " << r_des_frame_id << " but planning scene doesn't have other frame");
00396 return false;
00397 }
00398 geometry_msgs::TransformStamped trans = scene_transform_map_.find(r_header_frame_id)->second;
00399
00400 tf::Transform tf_trans;
00401 tf::transformMsgToTF(trans.transform, tf_trans);
00402 tf::Transform tf_pose;
00403 tf::poseMsgToTF(ret_pose.pose, tf_pose);
00404
00405 tf::Transform fpose = tf_trans*tf_pose;
00406
00407
00408 ret_pose.header.frame_id = getWorldFrameId();
00409 tf::poseTFToMsg(fpose, ret_pose.pose);
00410
00411 if(des_is_fixed_frame) {
00412 return true;
00413 }
00414 }
00415
00416
00417 tf::Transform bt_pose;
00418 tf::poseMsgToTF(ret_pose.pose,bt_pose);
00419
00420
00421
00422
00423
00424 if(ret_pose.header.frame_id == getWorldFrameId() && des_is_robot_frame) {
00425 tf::Transform trans_bt_pose = des_link_state->getGlobalLinkTransform().inverse()*bt_pose;
00426 tf::poseTFToMsg(trans_bt_pose,ret_pose.pose);
00427 ret_pose.header.frame_id = des_link_state->getName();
00428 } else if(header_is_robot_frame && des_is_fixed_frame) {
00429
00430 tf::Transform trans_bt_pose = header_link_state->getGlobalLinkTransform()*bt_pose;
00431 tf::poseTFToMsg(trans_bt_pose,ret_pose.pose);
00432 ret_pose.header.frame_id = getWorldFrameId();
00433 } else if(header_is_robot_frame && des_is_robot_frame) {
00434
00435 tf::Transform trans_bt_pose = des_link_state->getGlobalLinkTransform().inverse()*(header_link_state->getGlobalLinkTransform()*bt_pose);
00436 tf::poseTFToMsg(trans_bt_pose,ret_pose.pose);
00437 ret_pose.header.frame_id = des_link_state->getName();
00438 } else {
00439 ROS_WARN("Really shouldn't have gotten here");
00440 return false;
00441 }
00442 return true;
00443 }
00444
00445 bool planning_environment::CollisionModels::convertAttachedCollisionObjectToNewWorldFrame(const planning_models::KinematicState& state,
00446 arm_navigation_msgs::AttachedCollisionObject& att_obj) const
00447 {
00448 for(unsigned int i = 0; i < att_obj.object.poses.size(); i++) {
00449 geometry_msgs::PoseStamped ret_pose;
00450 if(!convertPoseGivenWorldTransform(state,
00451 att_obj.link_name,
00452 att_obj.object.header,
00453 att_obj.object.poses[i],
00454 ret_pose)) {
00455 return false;
00456 }
00457 if(i == 0) {
00458 att_obj.object.header = ret_pose.header;
00459 }
00460 att_obj.object.poses[i] = ret_pose.pose;
00461 }
00462 return true;
00463 }
00464
00465 bool planning_environment::CollisionModels::convertCollisionObjectToNewWorldFrame(const planning_models::KinematicState& state,
00466 arm_navigation_msgs::CollisionObject& obj) const
00467 {
00468 for(unsigned int i = 0; i < obj.poses.size(); i++) {
00469 geometry_msgs::PoseStamped ret_pose;
00470 if(!convertPoseGivenWorldTransform(state,
00471 getWorldFrameId(),
00472 obj.header,
00473 obj.poses[i],
00474 ret_pose)) {
00475 return false;
00476 }
00477 if(i == 0) {
00478 obj.header = ret_pose.header;
00479 }
00480 obj.poses[i] = ret_pose.pose;
00481 }
00482 return true;
00483 }
00484
00485 bool planning_environment::CollisionModels::convertConstraintsGivenNewWorldTransform(const planning_models::KinematicState& state,
00486 arm_navigation_msgs::Constraints& constraints,
00487 const std::string& opt_frame) const {
00488 std::string trans_frame;
00489 if(!opt_frame.empty()) {
00490 trans_frame = opt_frame;
00491 } else {
00492 trans_frame = getWorldFrameId();
00493 }
00494 for(unsigned int i = 0; i < constraints.position_constraints.size(); i++) {
00495 geometry_msgs::PointStamped ps;
00496 if(!convertPointGivenWorldTransform(state,
00497 trans_frame,
00498 constraints.position_constraints[i].header,
00499 constraints.position_constraints[i].position,
00500 ps)) {
00501 return false;
00502 }
00503 constraints.position_constraints[i].header = ps.header;
00504 constraints.position_constraints[i].position = ps.point;
00505
00506 geometry_msgs::QuaternionStamped qs;
00507 if(!convertQuaternionGivenWorldTransform(state,
00508 trans_frame,
00509 constraints.position_constraints[i].header,
00510 constraints.position_constraints[i].constraint_region_orientation,
00511 qs)) {
00512 return false;
00513 }
00514 constraints.position_constraints[i].constraint_region_orientation = qs.quaternion;
00515 }
00516
00517 for(unsigned int i = 0; i < constraints.orientation_constraints.size(); i++) {
00518 geometry_msgs::QuaternionStamped qs;
00519 if(!convertQuaternionGivenWorldTransform(state,
00520 trans_frame,
00521 constraints.orientation_constraints[i].header,
00522 constraints.orientation_constraints[i].orientation,
00523 qs)) {
00524 return false;
00525 }
00526 constraints.orientation_constraints[i].header = qs.header;
00527 constraints.orientation_constraints[i].orientation = qs.quaternion;
00528 }
00529
00530 for(unsigned int i = 0; i < constraints.visibility_constraints.size(); i++) {
00531 if(!convertPointGivenWorldTransform(state,
00532 trans_frame,
00533 constraints.visibility_constraints[i].target.header,
00534 constraints.visibility_constraints[i].target.point,
00535 constraints.visibility_constraints[i].target)) {
00536 return false;
00537 }
00538 }
00539 return true;
00540 }
00541
00542 bool planning_environment::CollisionModels::convertPointGivenWorldTransform(const planning_models::KinematicState& state,
00543 const std::string& des_frame_id,
00544 const std_msgs::Header& header,
00545 const geometry_msgs::Point& point,
00546 geometry_msgs::PointStamped& ret_point) const
00547 {
00548 geometry_msgs::Pose arg_pose;
00549 arg_pose.position = point;
00550 arg_pose.orientation.w = 1.0;
00551 geometry_msgs::PoseStamped ret_pose;
00552 if(!convertPoseGivenWorldTransform(state,
00553 des_frame_id,
00554 header,
00555 arg_pose,
00556 ret_pose)) {
00557 return false;
00558 }
00559 ret_point.header = ret_pose.header;
00560 ret_point.point = ret_pose.pose.position;
00561 return true;
00562 }
00563
00564 bool planning_environment::CollisionModels::convertQuaternionGivenWorldTransform(const planning_models::KinematicState& state,
00565 const std::string& des_frame_id,
00566 const std_msgs::Header& header,
00567 const geometry_msgs::Quaternion& quat,
00568 geometry_msgs::QuaternionStamped& ret_quat) const
00569 {
00570 geometry_msgs::Pose arg_pose;
00571 arg_pose.orientation = quat;
00572 geometry_msgs::PoseStamped ret_pose;
00573 if(!convertPoseGivenWorldTransform(state,
00574 des_frame_id,
00575 header,
00576 arg_pose,
00577 ret_pose)) {
00578 return false;
00579 }
00580 ret_quat.header = ret_pose.header;
00581 ret_quat.quaternion = ret_pose.pose.orientation;
00582 return true;
00583 }
00584
00585 bool planning_environment::CollisionModels::updateAttachedBodyPosesForLink(const planning_models::KinematicState& state,
00586 const std::string& link_name)
00587 {
00588 bodiesLock();
00589 if(link_attached_objects_.find(link_name) == link_attached_objects_.end()) {
00590 bodiesUnlock();
00591 return false;
00592 }
00593 const planning_models::KinematicState::LinkState* ls = state.getLinkState(link_name);
00594 for(unsigned int j = 0; j < ls->getAttachedBodyStateVector().size(); j++) {
00595 const planning_models::KinematicState::AttachedBodyState* att_state = ls->getAttachedBodyStateVector()[j];
00596 std::map<std::string, bodies::BodyVector*>::iterator bvit = link_attached_objects_[link_name].find(att_state->getName());
00597 if(bvit == link_attached_objects_[link_name].end()) {
00598 ROS_WARN_STREAM("State out of sync with attached body vector for attached body " << att_state->getName());
00599 bodiesUnlock();
00600 return false;
00601 }
00602 if(bvit->second->getSize() != att_state->getGlobalCollisionBodyTransforms().size()) {
00603 ROS_WARN_STREAM("State out of sync with attached body vector for attached body " << att_state->getName());
00604 bodiesUnlock();
00605 return false;
00606 }
00607 for(unsigned int k = 0; k < att_state->getGlobalCollisionBodyTransforms().size(); k++) {
00608 bvit->second->setPose(k, att_state->getGlobalCollisionBodyTransforms()[k]);
00609 }
00610 }
00611 bodiesUnlock();
00612 return true;
00613 }
00614
00615 bool planning_environment::CollisionModels::updateAttachedBodyPoses(const planning_models::KinematicState& state)
00616 {
00617 for(std::map<std::string, std::map<std::string, bodies::BodyVector*> >::iterator it = link_attached_objects_.begin();
00618 it != link_attached_objects_.end();
00619 it++) {
00620 if(!updateAttachedBodyPosesForLink(state, it->first)) {
00621 return false;
00622 }
00623 }
00624 return true;
00625 }
00626
00627 bool planning_environment::CollisionModels::addStaticObject(const arm_navigation_msgs::CollisionObject& obj)
00628 {
00629 std::vector<shapes::Shape*> shapes;
00630 std::vector<tf::Transform> poses;
00631 for(unsigned int i = 0; i < obj.shapes.size(); i++) {
00632 shapes::Shape *shape = constructObject(obj.shapes[i]);
00633 if(!shape) {
00634 ROS_WARN_STREAM("Something wrong with shape");
00635 return false;
00636 }
00637 shapes.push_back(shape);
00638 tf::Transform pose;
00639 tf::poseMsgToTF(obj.poses[i], pose);
00640 poses.push_back(pose);
00641 }
00642 double padding = object_padd_;
00643 if(obj.padding < 0.0) {
00644 padding = 0.0;
00645 } else if(obj.padding > 0.0){
00646 padding = obj.padding;
00647 }
00648 addStaticObject(obj.id,
00649 shapes,
00650 poses,
00651 padding);
00652 return true;
00653 }
00654
00655
00656 void planning_environment::CollisionModels::addStaticObject(const std::string& name,
00657 std::vector<shapes::Shape*>& shapes,
00658 const std::vector<tf::Transform>& poses,
00659 double padding)
00660 {
00661 if(ode_collision_model_->hasObject(name)) {
00662 deleteStaticObject(name);
00663 }
00664 bodiesLock();
00665 static_object_map_[name] = new bodies::BodyVector(shapes, poses, padding);
00666 ode_collision_model_->lock();
00667 ode_collision_model_->addObjects(name, shapes, poses);
00668 ode_collision_model_->unlock();
00669 bodiesUnlock();
00670 }
00671
00672 void planning_environment::CollisionModels::deleteStaticObject(const std::string& name)
00673 {
00674 bodiesLock();
00675 if(!ode_collision_model_->hasObject(name)) {
00676 return;
00677 }
00678 delete static_object_map_.find(name)->second;
00679 static_object_map_.erase(name);
00680 ode_collision_model_->lock();
00681 ode_collision_model_->clearObjects(name);
00682 ode_collision_model_->unlock();
00683 bodiesUnlock();
00684 }
00685
00686 void planning_environment::CollisionModels::deleteAllStaticObjects() {
00687 bodiesLock();
00688 for(std::map<std::string, bodies::BodyVector*>::iterator it = static_object_map_.begin();
00689 it != static_object_map_.end();
00690 it++) {
00691 delete it->second;
00692 }
00693 static_object_map_.clear();
00694 ode_collision_model_->lock();
00695 ode_collision_model_->clearObjects();
00696 ode_collision_model_->unlock();
00697 bodiesUnlock();
00698 }
00699
00700 void planning_environment::CollisionModels::setCollisionMap(const arm_navigation_msgs::CollisionMap& map,
00701 bool mask_before_insertion) {
00702 std::vector<shapes::Shape*> shapes(map.boxes.size());
00703 std::vector<tf::Transform> poses;
00704 for(unsigned int i = 0; i < map.boxes.size(); i++) {
00705 shapes[i] = new shapes::Box(map.boxes[i].extents.x, map.boxes[i].extents.y, map.boxes[i].extents.z);
00706 tf::Transform pose;
00707 pose.setOrigin(tf::Vector3(map.boxes[i].center.x, map.boxes[i].center.y, map.boxes[i].center.z));
00708 pose.setRotation(tf::Quaternion(tf::Vector3(map.boxes[i].axis.x, map.boxes[i].axis.y, map.boxes[i].axis.z), map.boxes[i].angle));
00709 poses.push_back(pose);
00710 }
00711 setCollisionMap(shapes, poses, mask_before_insertion);
00712 }
00713
00714 void planning_environment::CollisionModels::setCollisionMap(std::vector<shapes::Shape*>& shapes,
00715 const std::vector<tf::Transform>& poses,
00716 bool mask_before_insertion)
00717 {
00718 bodiesLock();
00719 shapes::deleteShapeVector(collision_map_shapes_);
00720 collision_map_shapes_ = shapes::cloneShapeVector(shapes);
00721 collision_map_poses_ = poses;
00722 std::vector<tf::Transform> masked_poses = poses;
00723 if(mask_before_insertion) {
00724 maskAndDeleteShapeVector(shapes,masked_poses);
00725 }
00726 ode_collision_model_->lock();
00727 ode_collision_model_->clearObjects(COLLISION_MAP_NAME);
00728 if(shapes.size() > 0) {
00729 ode_collision_model_->addObjects(COLLISION_MAP_NAME, shapes, masked_poses);
00730 } else {
00731 ROS_DEBUG_STREAM("Not setting any collision map objects");
00732 }
00733 ode_collision_model_->unlock();
00734 bodiesUnlock();
00735 }
00736
00737 void planning_environment::CollisionModels::remaskCollisionMap() {
00738 std::vector<shapes::Shape*> shapes = shapes::cloneShapeVector(collision_map_shapes_);
00739 std::vector<tf::Transform> masked_poses = collision_map_poses_;
00740 maskAndDeleteShapeVector(shapes,masked_poses);
00741 ode_collision_model_->lock();
00742 ode_collision_model_->clearObjects(COLLISION_MAP_NAME);
00743 ode_collision_model_->addObjects(COLLISION_MAP_NAME, shapes, masked_poses);
00744 ode_collision_model_->unlock();
00745 }
00746
00747 void planning_environment::CollisionModels::maskAndDeleteShapeVector(std::vector<shapes::Shape*>& shapes,
00748 std::vector<tf::Transform>& poses)
00749 {
00750 bodiesLock();
00751 std::vector<bool> mask;
00752 std::vector<bodies::BodyVector*> object_vector;
00753
00754 for(std::map<std::string, bodies::BodyVector*>::iterator it = static_object_map_.begin();
00755 it != static_object_map_.end();
00756 it++) {
00757 object_vector.push_back(it->second);
00758 }
00759
00760 for(std::map<std::string, std::map<std::string, bodies::BodyVector*> >::iterator it = link_attached_objects_.begin();
00761 it != link_attached_objects_.end();
00762 it++) {
00763 for(std::map<std::string, bodies::BodyVector*>::iterator it2 = it->second.begin();
00764 it2 != it->second.end();
00765 it2++) {
00766 object_vector.push_back(it2->second);
00767 }
00768 }
00769 bodies::maskPosesInsideBodyVectors(poses, object_vector, mask, true);
00770 std::vector<tf::Transform> ret_poses;
00771 std::vector<shapes::Shape*> ret_shapes;
00772 unsigned int num_masked = 0;
00773 for(unsigned int i = 0; i < mask.size(); i++) {
00774 if(mask[i]) {
00775 ret_shapes.push_back(shapes[i]);
00776 ret_poses.push_back(poses[i]);
00777 } else {
00778 num_masked++;
00779 delete shapes[i];
00780 }
00781 }
00782 shapes = ret_shapes;
00783 poses = ret_poses;
00784 bodiesUnlock();
00785 }
00786
00787 bool planning_environment::CollisionModels::addAttachedObject(const arm_navigation_msgs::AttachedCollisionObject& att)
00788 {
00789 const arm_navigation_msgs::CollisionObject& obj = att.object;
00790 std::vector<shapes::Shape*> shapes;
00791 std::vector<tf::Transform> poses;
00792 for(unsigned int i = 0; i < obj.shapes.size(); i++) {
00793 shapes::Shape *shape = constructObject(obj.shapes[i]);
00794 if(!shape) {
00795 ROS_WARN_STREAM("Something wrong with shape");
00796 return false;
00797 }
00798 shapes.push_back(shape);
00799 tf::Transform pose;
00800 tf::poseMsgToTF(obj.poses[i], pose);
00801 poses.push_back(pose);
00802 }
00803 double padding = attached_padd_;
00804 if(obj.padding < 0.0) {
00805 padding = 0.0;
00806 } else if(obj.padding > 0.0){
00807 padding = obj.padding;
00808 }
00809 if(!addAttachedObject(obj.id,
00810 att.link_name,
00811 shapes,
00812 poses,
00813 att.touch_links,
00814 padding)) {
00815 ROS_INFO_STREAM("Problem attaching " << obj.id);
00816 shapes::deleteShapeVector(shapes);
00817 }
00818 return true;
00819 }
00820
00821
00822 bool planning_environment::CollisionModels::addAttachedObject(const std::string& object_name,
00823 const std::string& link_name,
00824 std::vector<shapes::Shape*>& shapes,
00825 const std::vector<tf::Transform>& poses,
00826 const std::vector<std::string>& touch_links,
00827 double padding)
00828 {
00829 const planning_models::KinematicModel::LinkModel *link = kmodel_->getLinkModel(link_name);
00830 if(link == NULL) {
00831 ROS_WARN_STREAM("No link " << link_name << " for attaching " << object_name);
00832 return false;
00833 }
00834 bodiesLock();
00835 if(link_attached_objects_.find(link_name) != link_attached_objects_.end()) {
00836 if(link_attached_objects_[link_name].find(object_name) !=
00837 link_attached_objects_[link_name].end()) {
00838 delete link_attached_objects_[link_name][object_name];
00839 link_attached_objects_[link_name].erase(object_name);
00840 kmodel_->clearLinkAttachedBodyModel(link_name, object_name);
00841 }
00842 }
00843
00844
00845 link_attached_objects_[link_name][object_name] = new bodies::BodyVector(shapes, poses, padding);
00846
00847 std::vector<std::string> modded_touch_links;
00848
00849
00850 for(unsigned int i = 0; i < touch_links.size(); i++) {
00851 if(kmodel_->getModelGroup(touch_links[i])) {
00852 std::vector<std::string> links = kmodel_->getModelGroup(touch_links[i])->getGroupLinkNames();
00853 modded_touch_links.insert(modded_touch_links.end(), links.begin(), links.end());
00854 } else {
00855 modded_touch_links.push_back(touch_links[i]);
00856 }
00857 }
00858
00859 if(find(modded_touch_links.begin(), modded_touch_links.end(), link_name) == modded_touch_links.end()) {
00860 modded_touch_links.push_back(link_name);
00861 }
00862 planning_models::KinematicModel::AttachedBodyModel* ab =
00863 new planning_models::KinematicModel::AttachedBodyModel(link, object_name,
00864 poses,
00865 modded_touch_links,
00866 shapes);
00867 kmodel_->addAttachedBodyModel(link->getName(),ab);
00868 ode_collision_model_->lock();
00869 ode_collision_model_->updateAttachedBodies();
00870 ode_collision_model_->unlock();
00871
00872 bodiesUnlock();
00873 return true;
00874 }
00875
00876 bool planning_environment::CollisionModels::deleteAttachedObject(const std::string& object_id,
00877 const std::string& link_name)
00878
00879 {
00880 bodiesLock();
00881 if(link_attached_objects_.find(link_name) != link_attached_objects_.end()) {
00882 if(link_attached_objects_[link_name].find(object_id) !=
00883 link_attached_objects_[link_name].end()) {
00884
00885 kmodel_->clearLinkAttachedBodyModel(link_name, object_id);
00886 delete link_attached_objects_[link_name][object_id];
00887 link_attached_objects_[link_name].erase(object_id);
00888 } else {
00889 ROS_WARN_STREAM("Link " << link_name << " has no object " << object_id << " to delete");
00890 bodiesUnlock();
00891 return false;
00892 }
00893 } else {
00894 ROS_WARN_STREAM("No link " << link_name << " for attached object delete");
00895 bodiesUnlock();
00896 return false;
00897 }
00898 ode_collision_model_->lock();
00899 ode_collision_model_->updateAttachedBodies();
00900 ode_collision_model_->unlock();
00901 bodiesUnlock();
00902 return true;
00903 }
00904
00905 void planning_environment::CollisionModels::deleteAllAttachedObjects(const std::string& link_name)
00906 {
00907 bodiesLock();
00908 for(std::map<std::string, std::map<std::string, bodies::BodyVector*> >::iterator it = link_attached_objects_.begin();
00909 it != link_attached_objects_.end();
00910 it++) {
00911 if(link_name.empty() || it->first == "link_name") {
00912 for(std::map<std::string, bodies::BodyVector*>::iterator it2 = it->second.begin();
00913 it2 != it->second.end();
00914 it2++) {
00915 delete it2->second;
00916 }
00917 }
00918 }
00919 if(link_name.empty()) {
00920 link_attached_objects_.clear();
00921 } else {
00922 link_attached_objects_.erase(link_name);
00923 }
00924
00925 if(link_name.empty()) {
00926 ROS_DEBUG_STREAM("Clearing all attached body models");
00927 kmodel_->clearAllAttachedBodyModels();
00928 } else {
00929 ROS_DEBUG_STREAM("Clearing all attached body models for link " << link_name);
00930 kmodel_->clearLinkAttachedBodyModels(link_name);
00931 }
00932 ode_collision_model_->lock();
00933 ode_collision_model_->updateAttachedBodies();
00934 ode_collision_model_->unlock();
00935 bodiesUnlock();
00936 }
00937
00938
00939 bool planning_environment::CollisionModels::convertStaticObjectToAttachedObject(const std::string& object_name,
00940 const std::string& link_name,
00941 const tf::Transform& link_pose,
00942 const std::vector<std::string>& touch_links)
00943 {
00944 const planning_models::KinematicModel::LinkModel *link = kmodel_->getLinkModel(link_name);
00945 if(link == NULL) {
00946 ROS_WARN_STREAM("No link " << link_name << " for attaching " << object_name);
00947 return false;
00948 }
00949 bodiesLock();
00950 if(static_object_map_.find(object_name) == static_object_map_.end()) {
00951 ROS_WARN_STREAM("No static object named " << object_name << " to convert");
00952 bodiesUnlock();
00953 return false;
00954 }
00955 link_attached_objects_[link_name][object_name] = static_object_map_[object_name];
00956 static_object_map_.erase(object_name);
00957
00958 std::vector<std::string> modded_touch_links = touch_links;
00959 if(find(touch_links.begin(), touch_links.end(), link_name) == touch_links.end()) {
00960 modded_touch_links.push_back(link_name);
00961 }
00962
00963 ode_collision_model_->lock();
00964 std::vector<tf::Transform> poses;
00965 std::vector<shapes::Shape*> shapes;
00966 const collision_space::EnvironmentObjects *eo = ode_collision_model_->getObjects();
00967 std::vector<std::string> ns = eo->getNamespaces();
00968 for (unsigned int i = 0 ; i < ns.size() ; ++i) {
00969 if(ns[i] == object_name) {
00970 const collision_space::EnvironmentObjects::NamespaceObjects &no = eo->getObjects(ns[i]);
00971 for(unsigned int j = 0; j < no.shape.size(); j++) {
00972 shapes.push_back(cloneShape(no.shape[j]));
00973 poses.push_back(no.shape_pose[j]);
00974 }
00975 }
00976 }
00977
00978 tf::Transform link_pose_inv = link_pose.inverse();
00979
00980 for(unsigned int i = 0; i < poses.size(); i++) {
00981 poses[i] = link_pose_inv*poses[i];
00982 }
00983
00984 planning_models::KinematicModel::AttachedBodyModel* ab =
00985 new planning_models::KinematicModel::AttachedBodyModel(link, object_name,
00986 poses,
00987 modded_touch_links,
00988 shapes);
00989 kmodel_->addAttachedBodyModel(link->getName(),ab);
00990
00991
00992
00993 ode_collision_model_->clearObjects(object_name);
00994 ode_collision_model_->updateAttachedBodies();
00995 ode_collision_model_->unlock();
00996 bodiesUnlock();
00997 return true;
00998 }
00999
01000 bool planning_environment::CollisionModels::convertAttachedObjectToStaticObject(const std::string& object_name,
01001 const std::string& link_name,
01002 const tf::Transform& link_pose)
01003 {
01004 const planning_models::KinematicModel::LinkModel *link = kmodel_->getLinkModel(link_name);
01005 if(link == NULL) {
01006 ROS_WARN_STREAM("No link " << link_name << " with attached object " << object_name);
01007 return false;
01008 }
01009 bodiesLock();
01010
01011 if(link_attached_objects_.find(link_name) == link_attached_objects_.end() ||
01012 link_attached_objects_[link_name].find(object_name) == link_attached_objects_[link_name].end())
01013 {
01014 ROS_WARN_STREAM("No attached body " << object_name << " attached to link " << link_name);
01015 bodiesUnlock();
01016 return false;
01017 }
01018
01019 static_object_map_[object_name] = link_attached_objects_[link_name][object_name];
01020 link_attached_objects_[link_name].erase(object_name);
01021
01022 const planning_models::KinematicModel::AttachedBodyModel* att = NULL;
01023 for (unsigned int i = 0 ; i < link->getAttachedBodyModels().size() ; ++i) {
01024 if(link->getAttachedBodyModels()[i]->getName() == object_name) {
01025 att = link->getAttachedBodyModels()[i];
01026 break;
01027 }
01028 }
01029
01030 if(att == NULL) {
01031 ROS_WARN_STREAM("Something seriously out of sync");
01032 bodiesUnlock();
01033 return false;
01034 }
01035 std::vector<shapes::Shape*> shapes = shapes::cloneShapeVector(att->getShapes());
01036 std::vector<tf::Transform> poses;
01037 for(unsigned int i = 0; i < att->getAttachedBodyFixedTransforms().size(); i++) {
01038 poses.push_back(link_pose*att->getAttachedBodyFixedTransforms()[i]);
01039 }
01040 kmodel_->clearLinkAttachedBodyModel(link_name, object_name);
01041 ode_collision_model_->lock();
01042
01043 ode_collision_model_->updateAttachedBodies();
01044
01045 ode_collision_model_->addObjects(object_name, shapes, poses);
01046 ode_collision_model_->unlock();
01047 bodiesUnlock();
01048 return true;
01049 }
01050
01051 void planning_environment::CollisionModels::applyLinkPaddingToCollisionSpace(const std::vector<arm_navigation_msgs::LinkPadding>& link_padding) {
01052 if(link_padding.empty()) return;
01053
01054 std::map<std::string, double> link_padding_map;
01055
01056 for(std::vector<arm_navigation_msgs::LinkPadding>::const_iterator it = link_padding.begin();
01057 it != link_padding.end();
01058 it++) {
01059 std::vector<std::string> svec1;
01060 if(kmodel_->getModelGroup((*it).link_name)) {
01061 svec1 = kmodel_->getModelGroup((*it).link_name)->getGroupLinkNames();
01062 } else {
01063 svec1.push_back((*it).link_name);
01064 }
01065 for(std::vector<std::string>::iterator stit1 = svec1.begin();
01066 stit1 != svec1.end();
01067 stit1++) {
01068 link_padding_map[(*stit1)] = (*it).padding;
01069 }
01070 }
01071
01072 ode_collision_model_->lock();
01073 ode_collision_model_->setAlteredLinkPadding(link_padding_map);
01074 ode_collision_model_->unlock();
01075 }
01076
01077 void planning_environment::CollisionModels::getCurrentLinkPadding(std::vector<arm_navigation_msgs::LinkPadding>& link_padding)
01078 {
01079 convertFromLinkPaddingMapToLinkPaddingVector(ode_collision_model_->getCurrentLinkPaddingMap(), link_padding);
01080 }
01081
01082 bool planning_environment::CollisionModels::applyOrderedCollisionOperationsToCollisionSpace(const arm_navigation_msgs::OrderedCollisionOperations &ord, bool print) {
01083
01084 ode_collision_model_->lock();
01085 collision_space::EnvironmentModel::AllowedCollisionMatrix acm = ode_collision_model_->getDefaultAllowedCollisionMatrix();;
01086 ode_collision_model_->unlock();
01087
01088 std::vector<std::string> o_strings;
01089 getCollisionObjectNames(o_strings);
01090 std::vector<std::string> a_strings;
01091 getAttachedCollisionObjectNames(a_strings);
01092
01093 bool ok = applyOrderedCollisionOperationsListToACM(ord, o_strings, a_strings, kmodel_, acm);
01094
01095 if(!ok) {
01096 ROS_WARN_STREAM("Bad collision operations");
01097 }
01098
01099 if(print) {
01100
01101 }
01102
01103 ode_collision_model_->lock();
01104 ode_collision_model_->setAlteredCollisionMatrix(acm);
01105 ode_collision_model_->unlock();
01106 return true;
01107 }
01108
01109 bool planning_environment::CollisionModels::disableCollisionsForNonUpdatedLinks(const std::string& group_name,
01110 bool use_default)
01111 {
01112 kmodel_->sharedLock();
01113 const planning_models::KinematicModel::JointModelGroup* joint_model_group = kmodel_->getModelGroup(group_name);
01114 collision_space::EnvironmentModel::AllowedCollisionMatrix acm;
01115 if(use_default) {
01116 acm = ode_collision_model_->getDefaultAllowedCollisionMatrix();
01117 } else {
01118 acm = ode_collision_model_->getCurrentAllowedCollisionMatrix();
01119 }
01120 if(joint_model_group == NULL) {
01121 ROS_WARN_STREAM("No joint group " << group_name);
01122 kmodel_->sharedUnlock();
01123 return false;
01124 }
01125
01126 std::vector<std::string> updated_link_names = joint_model_group->getUpdatedLinkModelNames();
01127 std::map<std::string, bool> updated_link_map;
01128 for(unsigned int i = 0; i < updated_link_names.size(); i++) {
01129 updated_link_map[updated_link_names[i]] = true;
01130 }
01131 std::vector<std::string> all_link_names;
01132 kmodel_->getLinkModelNames(all_link_names);
01133
01134 std::vector<std::string> non_group_names;
01135 for(unsigned int i = 0; i < all_link_names.size(); i++) {
01136
01137 if(acm.hasEntry(all_link_names[i]) && updated_link_map.find(all_link_names[i]) == updated_link_map.end()) {
01138 non_group_names.push_back(all_link_names[i]);
01139 }
01140 }
01141 std::vector<const planning_models::KinematicModel::AttachedBodyModel*> att_bodies = kmodel_->getAttachedBodyModels();
01142 for(unsigned int i = 0; i < att_bodies.size(); i++) {
01143 if(updated_link_map.find(att_bodies[i]->getAttachedLinkModel()->getName()) == updated_link_map.end()) {
01144 non_group_names.push_back(att_bodies[i]->getName());
01145 }
01146 }
01147
01148
01149 for(std::map<std::string, bodies::BodyVector*>::const_iterator it = static_object_map_.begin();
01150 it != static_object_map_.end();
01151 it++) {
01152 non_group_names.push_back(it->first);
01153 }
01154
01155
01156 if(acm.hasEntry(COLLISION_MAP_NAME)) {
01157 non_group_names.push_back(COLLISION_MAP_NAME);
01158 }
01159
01160
01161 if(!acm.changeEntry(non_group_names, non_group_names, true)) {
01162 ROS_INFO_STREAM("Some problem changing entries");
01163 kmodel_->sharedUnlock();
01164 return false;
01165 }
01166 setAlteredAllowedCollisionMatrix(acm);
01167
01168 kmodel_->sharedUnlock();
01169 return true;
01170 }
01171
01172 bool planning_environment::CollisionModels::setAlteredAllowedCollisionMatrix(const collision_space::EnvironmentModel::AllowedCollisionMatrix& acm)
01173 {
01174 ode_collision_model_->lock();
01175 ode_collision_model_->setAlteredCollisionMatrix(acm);
01176 ode_collision_model_->unlock();
01177 return true;
01178 }
01179
01180 const collision_space::EnvironmentModel::AllowedCollisionMatrix& planning_environment::CollisionModels::getCurrentAllowedCollisionMatrix() const
01181 {
01182 return ode_collision_model_->getCurrentAllowedCollisionMatrix();
01183 }
01184
01185 const collision_space::EnvironmentModel::AllowedCollisionMatrix& planning_environment::CollisionModels::getDefaultAllowedCollisionMatrix() const
01186 {
01187 return ode_collision_model_->getDefaultAllowedCollisionMatrix();
01188 }
01189
01190 void planning_environment::CollisionModels::getLastCollisionMap(arm_navigation_msgs::CollisionMap& cmap) const
01191 {
01192 bodiesLock();
01193 cmap.header.frame_id = getWorldFrameId();
01194 cmap.header.stamp = ros::Time::now();
01195 cmap.boxes.clear();
01196 for(unsigned int i = 0; i < collision_map_shapes_.size(); i++) {
01197 if (collision_map_shapes_[i]->type == shapes::BOX) {
01198 const shapes::Box* box = static_cast<const shapes::Box*>(collision_map_shapes_[i]);
01199 arm_navigation_msgs::OrientedBoundingBox obb;
01200 obb.extents.x = box->size[0];
01201 obb.extents.y = box->size[1];
01202 obb.extents.z = box->size[2];
01203 const tf::Vector3 &c = collision_map_poses_[i].getOrigin();
01204 obb.center.x = c.x();
01205 obb.center.y = c.y();
01206 obb.center.z = c.z();
01207 const tf::Quaternion q = collision_map_poses_[i].getRotation();
01208 obb.angle = q.getAngle();
01209 const tf::Vector3 axis = q.getAxis();
01210 obb.axis.x = axis.x();
01211 obb.axis.y = axis.y();
01212 obb.axis.z = axis.z();
01213 cmap.boxes.push_back(obb);
01214 }
01215 }
01216 bodiesUnlock();
01217 }
01218
01219 void planning_environment::CollisionModels::getCollisionSpaceCollisionMap(arm_navigation_msgs::CollisionMap& cmap) const
01220 {
01221 bodiesLock();
01222 ode_collision_model_->lock();
01223 cmap.header.frame_id = getWorldFrameId();
01224 cmap.header.stamp = ros::Time::now();
01225 cmap.boxes.clear();
01226
01227 const collision_space::EnvironmentObjects::NamespaceObjects &no = ode_collision_model_->getObjects()->getObjects(COLLISION_MAP_NAME);
01228 const unsigned int n = no.shape.size();
01229 for (unsigned int i = 0 ; i < n ; ++i) {
01230 if (no.shape[i]->type == shapes::BOX) {
01231 const shapes::Box* box = static_cast<const shapes::Box*>(no.shape[i]);
01232 arm_navigation_msgs::OrientedBoundingBox obb;
01233 obb.extents.x = box->size[0];
01234 obb.extents.y = box->size[1];
01235 obb.extents.z = box->size[2];
01236 const tf::Vector3 &c = no.shape_pose[i].getOrigin();
01237 obb.center.x = c.x();
01238 obb.center.y = c.y();
01239 obb.center.z = c.z();
01240 const tf::Quaternion q = no.shape_pose[i].getRotation();
01241 obb.angle = q.getAngle();
01242 const tf::Vector3 axis = q.getAxis();
01243 obb.axis.x = axis.x();
01244 obb.axis.y = axis.y();
01245 obb.axis.z = axis.z();
01246 cmap.boxes.push_back(obb);
01247 }
01248 }
01249 ode_collision_model_->unlock();
01250 bodiesUnlock();
01251 }
01252
01253 void planning_environment::CollisionModels::revertAllowedCollisionToDefault() {
01254 ode_collision_model_->lock();
01255 ode_collision_model_->revertAlteredCollisionMatrix();
01256 ode_collision_model_->unlock();
01257 }
01258
01259 void planning_environment::CollisionModels::revertCollisionSpacePaddingToDefault() {
01260 ode_collision_model_->lock();
01261 ode_collision_model_->revertAlteredLinkPadding();
01262 ode_collision_model_->unlock();
01263 }
01264
01265 void planning_environment::CollisionModels::getCollisionSpaceAllowedCollisions(arm_navigation_msgs::AllowedCollisionMatrix& ret_matrix) const {
01266
01267 convertFromACMToACMMsg(ode_collision_model_->getCurrentAllowedCollisionMatrix(),
01268 ret_matrix);
01269 }
01270
01271 void planning_environment::CollisionModels::getCollisionSpaceCollisionObjects(std::vector<arm_navigation_msgs::CollisionObject> &omap) const
01272 {
01273 bodiesLock();
01274 ode_collision_model_->lock();
01275 omap.clear();
01276 const collision_space::EnvironmentObjects *eo = ode_collision_model_->getObjects();
01277 std::vector<std::string> ns = eo->getNamespaces();
01278 for (unsigned int i = 0 ; i < ns.size() ; ++i)
01279 {
01280 if (ns[i] == COLLISION_MAP_NAME)
01281 continue;
01282 const collision_space::EnvironmentObjects::NamespaceObjects &no = eo->getObjects(ns[i]);
01283 const unsigned int n = no.shape.size();
01284
01285 arm_navigation_msgs::CollisionObject o;
01286 o.header.frame_id = getWorldFrameId();
01287 o.header.stamp = ros::Time::now();
01288 o.id = ns[i];
01289 o.operation.operation = arm_navigation_msgs::CollisionObjectOperation::ADD;
01290 for (unsigned int j = 0 ; j < n ; ++j) {
01291 arm_navigation_msgs::Shape obj;
01292 if (constructObjectMsg(no.shape[j], obj)) {
01293 geometry_msgs::Pose pose;
01294 tf::poseTFToMsg(no.shape_pose[j], pose);
01295 o.shapes.push_back(obj);
01296 o.poses.push_back(pose);
01297 }
01298 }
01299 if(static_object_map_.find(ns[i]) == static_object_map_.end()) {
01300 ROS_WARN_STREAM("No matching internal object named " << ns[i]);
01301 } else {
01302 o.padding = static_object_map_.find(ns[i])->second->getPadding();
01303 }
01304 omap.push_back(o);
01305 }
01306 ode_collision_model_->unlock();
01307 bodiesUnlock();
01308 }
01309
01310 void planning_environment::CollisionModels::getCollisionSpaceAttachedCollisionObjects(std::vector<arm_navigation_msgs::AttachedCollisionObject> &avec) const
01311 {
01312 avec.clear();
01313
01314 bodiesLock();
01315 ode_collision_model_->lock();
01316
01317 std::vector<const planning_models::KinematicModel::AttachedBodyModel*> att_vec = kmodel_->getAttachedBodyModels();
01318 for(unsigned int i = 0; i < att_vec.size(); i++)
01319 {
01320 arm_navigation_msgs::AttachedCollisionObject ao;
01321 ao.object.header.frame_id = att_vec[i]->getAttachedLinkModel()->getName();
01322 ao.object.header.stamp = ros::Time::now();
01323 ao.link_name = att_vec[i]->getAttachedLinkModel()->getName();
01324 double attached_padd = ode_collision_model_->getCurrentLinkPadding("attached");
01325 for(unsigned int j = 0; j < att_vec[i]->getShapes().size(); j++) {
01326 arm_navigation_msgs::Shape shape;
01327 constructObjectMsg(att_vec[i]->getShapes()[j], shape, attached_padd);
01328 geometry_msgs::Pose pose;
01329 tf::poseTFToMsg(att_vec[i]->getAttachedBodyFixedTransforms()[j], pose);
01330 ao.object.shapes.push_back(shape);
01331 ao.object.poses.push_back(pose);
01332 }
01333 ao.touch_links = att_vec[i]->getTouchLinks();
01334 ao.object.id = att_vec[i]->getName();
01335 if(link_attached_objects_.find(ao.link_name) == link_attached_objects_.end()) {
01336 ROS_WARN_STREAM("No matching attached objects for link " << ao.link_name);
01337 } else if(link_attached_objects_.find(ao.link_name)->second.find(ao.object.id) ==
01338 link_attached_objects_.find(ao.link_name)->second.end()) {
01339 ROS_WARN_STREAM("No matching attached objects for link " << ao.link_name << " object " << ao.object.id);
01340 } else {
01341 ao.object.padding = link_attached_objects_.find(ao.link_name)->second.find(ao.object.id)->second->getPadding();
01342 }
01343 avec.push_back(ao);
01344 }
01345 ode_collision_model_->unlock();
01346 bodiesUnlock();
01347 }
01348
01349 bool planning_environment::CollisionModels::isKinematicStateInCollision(const planning_models::KinematicState& state)
01350 {
01351 ode_collision_model_->lock();
01352 ode_collision_model_->updateRobotModel(&state);
01353 bool in_coll = ode_collision_model_->isCollision();
01354 ode_collision_model_->unlock();
01355 return in_coll;
01356 }
01357
01358 bool planning_environment::CollisionModels::isKinematicStateInSelfCollision(const planning_models::KinematicState& state)
01359 {
01360 ode_collision_model_->lock();
01361 ode_collision_model_->updateRobotModel(&state);
01362 bool in_coll = ode_collision_model_->isSelfCollision();
01363 ode_collision_model_->unlock();
01364 return in_coll;
01365 }
01366
01367 bool planning_environment::CollisionModels::isKinematicStateInEnvironmentCollision(const planning_models::KinematicState& state)
01368 {
01369 ode_collision_model_->lock();
01370 ode_collision_model_->updateRobotModel(&state);
01371 bool in_coll = ode_collision_model_->isEnvironmentCollision();
01372 ode_collision_model_->unlock();
01373 return in_coll;
01374 }
01375
01376 bool planning_environment::CollisionModels::isKinematicStateInObjectCollision(const planning_models::KinematicState &state,
01377 const std::string& object_name) {
01378 ode_collision_model_->lock();
01379 ode_collision_model_->updateRobotModel(&state);
01380 bool in_coll = ode_collision_model_->isObjectRobotCollision(object_name);
01381 ode_collision_model_->unlock();
01382 return in_coll;
01383 }
01384
01385 bool planning_environment::CollisionModels::isObjectInCollision(const std::string& object_name) {
01386 ode_collision_model_->lock();
01387 bool in_coll = ode_collision_model_->isObjectInEnvironmentCollision(object_name);
01388 ode_collision_model_->unlock();
01389 return in_coll;
01390 }
01391
01392 void planning_environment::CollisionModels::getAllCollisionsForState(const planning_models::KinematicState& state,
01393 std::vector<arm_navigation_msgs::ContactInformation>& contacts,
01394 unsigned int num_per_pair)
01395 {
01396 ode_collision_model_->lock();
01397 ode_collision_model_->updateRobotModel(&state);
01398 std::vector<collision_space::EnvironmentModel::Contact> coll_space_contacts;
01399 ros::WallTime n1 = ros::WallTime::now();
01400 ode_collision_model_->getAllCollisionContacts(coll_space_contacts,
01401 num_per_pair);
01402 ros::WallTime n2 = ros::WallTime::now();
01403 ROS_DEBUG_STREAM("Got " << coll_space_contacts.size() << " collisions in " << (n2-n1).toSec());
01404 for(unsigned int i = 0; i < coll_space_contacts.size(); i++) {
01405 arm_navigation_msgs::ContactInformation contact_info;
01406 contact_info.header.frame_id = getWorldFrameId();
01407 collision_space::EnvironmentModel::Contact& contact = coll_space_contacts[i];
01408 contact_info.contact_body_1 = contact.body_name_1;
01409 contact_info.contact_body_2 = contact.body_name_2;
01410 if(contact.body_type_1 == collision_space::EnvironmentModel::LINK) {
01411 contact_info.body_type_1 = arm_navigation_msgs::ContactInformation::ROBOT_LINK;
01412 } else if(contact.body_type_1 == collision_space::EnvironmentModel::ATTACHED) {
01413 contact_info.body_type_1 = arm_navigation_msgs::ContactInformation::ATTACHED_BODY;
01414 } else {
01415 contact_info.body_type_1 = arm_navigation_msgs::ContactInformation::OBJECT;
01416 }
01417 if(contact.body_type_2 == collision_space::EnvironmentModel::LINK) {
01418 contact_info.body_type_2 = arm_navigation_msgs::ContactInformation::ROBOT_LINK;
01419 } else if(contact.body_type_2 == collision_space::EnvironmentModel::ATTACHED) {
01420 contact_info.body_type_2 = arm_navigation_msgs::ContactInformation::ATTACHED_BODY;
01421 } else {
01422 contact_info.body_type_2 = arm_navigation_msgs::ContactInformation::OBJECT;
01423 }
01424 contact_info.position.x = contact.pos.x();
01425 contact_info.position.y = contact.pos.y();
01426 contact_info.position.z = contact.pos.z();
01427 contacts.push_back(contact_info);
01428 }
01429 ode_collision_model_->unlock();
01430 }
01431
01432 void planning_environment::CollisionModels::getAllEnvironmentCollisionsForObject(const std::string& object_name,
01433 std::vector<arm_navigation_msgs::ContactInformation>& contacts,
01434 unsigned int num_per_pair) {
01435 ode_collision_model_->lock();
01436 std::vector<collision_space::EnvironmentModel::Contact> coll_space_contacts;
01437 ode_collision_model_->getAllObjectEnvironmentCollisionContacts(object_name, coll_space_contacts, num_per_pair);
01438 for(unsigned int i = 0; i < coll_space_contacts.size(); i++) {
01439 arm_navigation_msgs::ContactInformation contact_info;
01440 contact_info.header.frame_id = getWorldFrameId();
01441 collision_space::EnvironmentModel::Contact& contact = coll_space_contacts[i];
01442 contact_info.contact_body_1 = contact.body_name_1;
01443 contact_info.contact_body_2 = contact.body_name_2;
01444 if(contact.body_type_1 == collision_space::EnvironmentModel::LINK) {
01445 contact_info.body_type_1 = arm_navigation_msgs::ContactInformation::ROBOT_LINK;
01446 } else if(contact.body_type_1 == collision_space::EnvironmentModel::ATTACHED) {
01447 contact_info.body_type_1 = arm_navigation_msgs::ContactInformation::ATTACHED_BODY;
01448 } else {
01449 contact_info.body_type_1 = arm_navigation_msgs::ContactInformation::OBJECT;
01450 }
01451 if(contact.body_type_2 == collision_space::EnvironmentModel::LINK) {
01452 contact_info.body_type_2 = arm_navigation_msgs::ContactInformation::ROBOT_LINK;
01453 } else if(contact.body_type_2 == collision_space::EnvironmentModel::ATTACHED) {
01454 contact_info.body_type_2 = arm_navigation_msgs::ContactInformation::ATTACHED_BODY;
01455 } else {
01456 contact_info.body_type_2 = arm_navigation_msgs::ContactInformation::OBJECT;
01457 }
01458 contact_info.position.x = contact.pos.x();
01459 contact_info.position.y = contact.pos.y();
01460 contact_info.position.z = contact.pos.z();
01461 contacts.push_back(contact_info);
01462 }
01463 ode_collision_model_->unlock();
01464
01465 }
01466
01467 bool planning_environment::CollisionModels::isKinematicStateValid(const planning_models::KinematicState& state,
01468 const std::vector<std::string>& joint_names,
01469 arm_navigation_msgs::ArmNavigationErrorCodes& error_code,
01470 const arm_navigation_msgs::Constraints goal_constraints,
01471 const arm_navigation_msgs::Constraints path_constraints,
01472 bool verbose)
01473 {
01474 if(!state.areJointsWithinBounds(joint_names)) {
01475 if(verbose) {
01476 for(unsigned int j = 0; j < joint_names.size(); j++) {
01477 if(!state.isJointWithinBounds(joint_names[j])) {
01478 std::pair<double, double> bounds;
01479 state.getJointState(joint_names[j])->getJointModel()->getVariableBounds(joint_names[j], bounds);
01480 double val = state.getJointState(joint_names[j])->getJointStateValues()[0];
01481 ROS_DEBUG_STREAM("Joint " << joint_names[j] << " out of bounds. " <<
01482 " value: " << val <<
01483 " low: " << bounds.first << " diff low: " << val-bounds.first << " high: " << bounds.second
01484 << " diff high: " << val-bounds.second);
01485 }
01486 }
01487 }
01488 error_code.val = error_code.JOINT_LIMITS_VIOLATED;
01489 return false;
01490 }
01491 if(!doesKinematicStateObeyConstraints(state, path_constraints, false)) {
01492 if(verbose) {
01493 doesKinematicStateObeyConstraints(state, path_constraints, true);
01494 }
01495 error_code.val = error_code.PATH_CONSTRAINTS_VIOLATED;
01496 return false;
01497 }
01498 if(!doesKinematicStateObeyConstraints(state, goal_constraints, false)) {
01499 if(verbose) {
01500 doesKinematicStateObeyConstraints(state, goal_constraints, true);
01501 }
01502 error_code.val = error_code.GOAL_CONSTRAINTS_VIOLATED;
01503 return false;
01504 }
01505 if(isKinematicStateInCollision(state)) {
01506 error_code.val = error_code.COLLISION_CONSTRAINTS_VIOLATED;
01507 if(verbose) {
01508 std::vector<arm_navigation_msgs::ContactInformation> contacts;
01509 getAllCollisionsForState(state, contacts,1);
01510 if(contacts.size() == 0) {
01511 ROS_WARN_STREAM("Collision reported but no contacts");
01512 }
01513 for(unsigned int i = 0; i < contacts.size(); i++) {
01514 ROS_DEBUG_STREAM("Collision between " << contacts[i].contact_body_1
01515 << " and " << contacts[i].contact_body_2);
01516 }
01517 }
01518 return false;
01519 }
01520 error_code.val = error_code.SUCCESS;
01521 return true;
01522 }
01523
01524 bool planning_environment::CollisionModels::isJointTrajectoryValid(const arm_navigation_msgs::PlanningScene& planning_scene,
01525 const trajectory_msgs::JointTrajectory &trajectory,
01526 const arm_navigation_msgs::Constraints& goal_constraints,
01527 const arm_navigation_msgs::Constraints& path_constraints,
01528 arm_navigation_msgs::ArmNavigationErrorCodes& error_code,
01529 std::vector<arm_navigation_msgs::ArmNavigationErrorCodes>& trajectory_error_codes,
01530 const bool evaluate_entire_trajectory)
01531 {
01532 if(planning_scene_set_) {
01533 ROS_WARN("Must revert planning scene before checking trajectory with planning scene");
01534 return false;
01535 }
01536
01537 planning_models::KinematicState* state = setPlanningScene(planning_scene);
01538
01539 if(state == NULL) {
01540 ROS_WARN("Planning scene invalid in isTrajectoryValid");
01541 return false;
01542 }
01543
01544 bool ok = isJointTrajectoryValid(*state, trajectory, goal_constraints, path_constraints, error_code, trajectory_error_codes, evaluate_entire_trajectory);
01545 revertPlanningScene(state);
01546 return ok;
01547 }
01548
01549
01550 bool planning_environment::CollisionModels::isJointTrajectoryValid(planning_models::KinematicState& state,
01551 const trajectory_msgs::JointTrajectory &trajectory,
01552 const arm_navigation_msgs::Constraints& goal_constraints,
01553 const arm_navigation_msgs::Constraints& path_constraints,
01554 arm_navigation_msgs::ArmNavigationErrorCodes& error_code,
01555 std::vector<arm_navigation_msgs::ArmNavigationErrorCodes>& trajectory_error_codes,
01556 const bool evaluate_entire_trajectory)
01557 {
01558 error_code.val = error_code.SUCCESS;
01559 trajectory_error_codes.clear();
01560
01561
01562 std::map<std::string, double> joint_value_map;
01563
01564
01565 std::vector<planning_models::KinematicState::JointState*> joints(trajectory.joint_names.size());
01566 for (unsigned int j = 0 ; j < joints.size() ; ++j)
01567 {
01568 joints[j] = state.getJointState(trajectory.joint_names[j]);
01569 if (joints[j] == NULL)
01570 {
01571 ROS_ERROR("Unknown joint '%s' found on path", trajectory.joint_names[j].c_str());
01572 error_code.val = error_code.INVALID_TRAJECTORY;
01573 return false;
01574 } else {
01575 joint_value_map[joints[j]->getName()] = 0.0;
01576 }
01577 }
01578
01579
01580 for (unsigned int j = 0 ; j < trajectory.points.front().positions.size(); j++)
01581 {
01582 joint_value_map[trajectory.joint_names[j]] = trajectory.points.front().positions[j];
01583 }
01584 state.setKinematicState(joint_value_map);
01585
01586
01587 if(!doesKinematicStateObeyConstraints(state, path_constraints)) {
01588 error_code.val = error_code.START_STATE_VIOLATES_PATH_CONSTRAINTS;
01589 if(!evaluate_entire_trajectory) {
01590 return false;
01591 }
01592 }
01593
01594
01595 ode_collision_model_->updateRobotModel(&state);
01596 if(ode_collision_model_->isCollision()) {
01597 error_code.val = error_code.START_STATE_IN_COLLISION;
01598 if(!evaluate_entire_trajectory) {
01599 return false;
01600 }
01601 }
01602
01603
01604
01605
01606 joint_value_map.clear();
01607 std::vector<std::string> goal_joint_names;
01608 for(unsigned int i = 0; i < goal_constraints.joint_constraints.size(); i++) {
01609 goal_joint_names.push_back(goal_constraints.joint_constraints[i].joint_name);
01610 joint_value_map[goal_joint_names.back()] = goal_constraints.joint_constraints[i].position;
01611 }
01612 state.setKinematicState(joint_value_map);
01613 if(!state.areJointsWithinBounds(goal_joint_names)) {
01614 error_code.val = error_code.INVALID_GOAL_JOINT_CONSTRAINTS;
01615 return false;
01616 }
01617
01618 joint_value_map.clear();
01619
01620 for (unsigned int j = 0 ; j < trajectory.points.back().positions.size(); j++)
01621 {
01622 joint_value_map[trajectory.joint_names[j]] = trajectory.points.back().positions[j];
01623 }
01624 state.setKinematicState(joint_value_map);
01625 if(!doesKinematicStateObeyConstraints(state, goal_constraints)) {
01626 error_code.val = error_code.GOAL_CONSTRAINTS_VIOLATED;
01627 return false;
01628 }
01629
01630
01631 arm_navigation_msgs::Constraints emp_goal_constraints;
01632 for(unsigned int i = 0; i < trajectory.points.size(); i++) {
01633 arm_navigation_msgs::ArmNavigationErrorCodes suc;
01634 suc.val = error_code.SUCCESS;
01635 trajectory_error_codes.push_back(suc);
01636 for (unsigned int j = 0 ; j < trajectory.points[i].positions.size(); j++)
01637 {
01638 joint_value_map[trajectory.joint_names[j]] = trajectory.points[i].positions[j];
01639 }
01640 state.setKinematicState(joint_value_map);
01641
01642 if(!isKinematicStateValid(state, trajectory.joint_names, suc,
01643 emp_goal_constraints, path_constraints)) {
01644
01645 error_code = suc;
01646 trajectory_error_codes.back() = suc;
01647 if(!evaluate_entire_trajectory) {
01648 return false;
01649 }
01650 }
01651 trajectory_error_codes.back() = suc;
01652 }
01653 return(error_code.val == error_code.SUCCESS);
01654 }
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703 double planning_environment::CollisionModels::getTotalTrajectoryJointLength(planning_models::KinematicState& state,
01704 const trajectory_msgs::JointTrajectory& jtraj) const
01705 {
01706 std::map<std::string, double> all_joint_state_values;
01707 state.getKinematicStateValues(all_joint_state_values);
01708
01709 std::map<std::string, double> joint_positions;
01710 for(unsigned int i = 0; i < jtraj.joint_names.size(); i++) {
01711 joint_positions[jtraj.joint_names[i]] = all_joint_state_values[jtraj.joint_names[i]];
01712 }
01713 double total_path_length = 0.0;
01714 for(unsigned int i = 0; i < jtraj.points.size(); i++) {
01715 for(unsigned int j = 0; j < jtraj.joint_names.size(); j++) {
01716 joint_positions[jtraj.joint_names[j]] = jtraj.points[i].positions[j];
01717 if(i != jtraj.points.size()-1) {
01718 total_path_length += fabs(jtraj.points[i+1].positions[j]-joint_positions[jtraj.joint_names[j]]);
01719 }
01720 }
01721 }
01722 return total_path_length;
01723 }
01724
01725
01726
01727 void planning_environment::CollisionModels::getCollisionMapAsMarkers(visualization_msgs::MarkerArray& arr,
01728 const std_msgs::ColorRGBA& color,
01729 const ros::Duration& lifetime)
01730 {
01731 visualization_msgs::Marker mark;
01732 mark.type = visualization_msgs::Marker::CUBE_LIST;
01733 mark.color.a = 1.0;
01734 mark.lifetime = lifetime;
01735 mark.ns = "collision_map_markers";
01736 mark.id = 0;
01737 mark.header.frame_id = getWorldFrameId();
01738 mark.header.stamp = ros::Time::now();
01739 const collision_space::EnvironmentObjects::NamespaceObjects &no = ode_collision_model_->getObjects()->getObjects(COLLISION_MAP_NAME);
01740 const unsigned int n = no.shape.size();
01741 for (unsigned int i = 0 ; i < n ; ++i) {
01742 if (no.shape[i]->type == shapes::BOX) {
01743 const shapes::Box* box = static_cast<const shapes::Box*>(no.shape[i]);
01744
01745 if(i == 0) {
01746 mark.scale.x = box->size[0];
01747 mark.scale.y = box->size[0];
01748 mark.scale.z = box->size[0];
01749 }
01750 const tf::Vector3 &c = no.shape_pose[i].getOrigin();
01751 geometry_msgs::Point point;
01752 point.x = c.x();
01753 point.y = c.y();
01754 point.z = c.z();
01755 std_msgs::ColorRGBA color;
01756 color.r = fmin(fmax(fabs(point.z)/0.5, 0.10), 1.0);
01757 color.g = fmin(fmax(fabs(point.z)/1.0, 0.20), 1.0);
01758 color.b = fmin(fmax(fabs(point.z)/1.5, 0.50), 1.0);
01759 mark.colors.push_back(color);
01760 mark.points.push_back(point);
01761 }
01762 }
01763 arr.markers.push_back(mark);
01764 }
01765
01766 void planning_environment::CollisionModels::getAllCollisionPointMarkers(const planning_models::KinematicState& state,
01767 visualization_msgs::MarkerArray& arr,
01768 const std_msgs::ColorRGBA& color,
01769 const ros::Duration& lifetime)
01770 {
01771 std::vector<arm_navigation_msgs::ContactInformation> coll_info_vec;
01772 getAllCollisionsForState(state,coll_info_vec,1);
01773 getCollisionMarkersFromContactInformation(coll_info_vec,
01774 getWorldFrameId(),
01775 arr,
01776 color,
01777 lifetime);
01778 }
01779
01780 void planning_environment::CollisionModels::getStaticCollisionObjectMarkers(visualization_msgs::MarkerArray& arr,
01781 const std::string& name,
01782 const std_msgs::ColorRGBA& color,
01783 const ros::Duration& lifetime) const
01784 {
01785 std::vector<arm_navigation_msgs::CollisionObject> static_objects;
01786 getCollisionSpaceCollisionObjects(static_objects);
01787
01788 for(unsigned int i = 0; i < static_objects.size(); i++) {
01789 for(unsigned int j = 0; j < static_objects[i].shapes.size(); j++) {
01790 visualization_msgs::Marker mk;
01791 mk.header.frame_id = getWorldFrameId();
01792 mk.header.stamp = ros::Time::now();
01793 if(name.empty()) {
01794 mk.ns = static_objects[i].id;
01795 } else {
01796 mk.ns = name;
01797 }
01798 mk.id = j;
01799 mk.action = visualization_msgs::Marker::ADD;
01800 mk.pose = static_objects[i].poses[j];
01801 mk.color.a = color.a;
01802 if(mk.color.a == 0.0) {
01803 mk.color.a = 1.0;
01804 }
01805 mk.color.r = color.r;
01806 mk.color.g = color.g;
01807 mk.color.b = color.b;
01808 setMarkerShapeFromShape(static_objects[i].shapes[j], mk);
01809 mk.lifetime = lifetime;
01810 arr.markers.push_back(mk);
01811 }
01812 }
01813 }
01814 void planning_environment::CollisionModels::getAttachedCollisionObjectMarkers(const planning_models::KinematicState& state,
01815 visualization_msgs::MarkerArray& arr,
01816 const std::string& name,
01817 const std_msgs::ColorRGBA& color,
01818 const ros::Duration& lifetime,
01819 const bool show_padded,
01820 const std::vector<std::string>* link_names) const
01821
01822 {
01823 ode_collision_model_->lock();
01824 std::vector<arm_navigation_msgs::AttachedCollisionObject> attached_objects;
01825 getCollisionSpaceAttachedCollisionObjects(attached_objects);
01826
01827 ode_collision_model_->updateRobotModel(&state);
01828
01829 std::map<std::string, std::vector<tf::Transform> > att_pose_map;
01830 ode_collision_model_->getAttachedBodyPoses(att_pose_map);
01831
01832 for(unsigned int i = 0; i < attached_objects.size(); i++) {
01833 if(link_names != NULL) {
01834 bool found = false;
01835 for(unsigned int j = 0; j < link_names->size(); j++) {
01836 if(attached_objects[i].link_name == (*link_names)[j]) {
01837 found = true;
01838 break;
01839 }
01840 }
01841 if(!found) {
01842 continue;
01843 }
01844 }
01845
01846 if(att_pose_map.find(attached_objects[i].object.id) == att_pose_map.end()) {
01847 ROS_WARN_STREAM("No collision space poses for " << attached_objects[i].object.id);
01848 continue;
01849 }
01850 if(att_pose_map[attached_objects[i].object.id].size() !=
01851 attached_objects[i].object.shapes.size()) {
01852 ROS_WARN_STREAM("Size mismatch between poses size " << att_pose_map[attached_objects[i].object.id].size()
01853 << " and shapes size " << attached_objects[i].object.shapes.size());
01854 continue;
01855 }
01856 for(unsigned int j = 0; j < attached_objects[i].object.shapes.size(); j++) {
01857 visualization_msgs::Marker mk;
01858 mk.header.frame_id = getWorldFrameId();
01859 mk.header.stamp = ros::Time::now();
01860 if(name.empty()) {
01861 mk.ns = attached_objects[i].object.id;
01862 } else {
01863 mk.ns = name;
01864 }
01865 mk.id = j;
01866 mk.action = visualization_msgs::Marker::ADD;
01867 tf::poseTFToMsg(att_pose_map[attached_objects[i].object.id][j], mk.pose);
01868 mk.color.a = color.a;
01869 if(mk.color.a == 0.0) {
01870 mk.color.a = 1.0;
01871 }
01872 mk.color.r = color.r;
01873 mk.color.g = color.g;
01874 mk.color.b = color.b;
01875 mk.lifetime = lifetime;
01876 setMarkerShapeFromShape(attached_objects[i].object.shapes[j], mk);
01877 arr.markers.push_back(mk);
01878 }
01879 }
01880 ode_collision_model_->unlock();
01881 }
01882
01883 void planning_environment::CollisionModels::getPlanningSceneGivenState(const planning_models::KinematicState& state,
01884 arm_navigation_msgs::PlanningScene& planning_scene)
01885 {
01886 convertKinematicStateToRobotState(state, ros::Time::now(), getWorldFrameId(), planning_scene.robot_state);
01887 convertFromACMToACMMsg(getCurrentAllowedCollisionMatrix(), planning_scene.allowed_collision_matrix);
01888
01889 getCurrentLinkPadding(planning_scene.link_padding);
01890 getCollisionSpaceCollisionObjects(planning_scene.collision_objects);
01891 getCollisionSpaceAttachedCollisionObjects(planning_scene.attached_collision_objects);
01892 getCollisionSpaceCollisionMap(planning_scene.collision_map);
01893 }
01894
01895 void planning_environment::CollisionModels::getAllCollisionSpaceObjectMarkers(const planning_models::KinematicState& state,
01896 visualization_msgs::MarkerArray& arr,
01897 const std::string& name,
01898 const std_msgs::ColorRGBA& static_color,
01899 const std_msgs::ColorRGBA& attached_color,
01900 const ros::Duration& lifetime)
01901 {
01902 getStaticCollisionObjectMarkers(arr, name, static_color, lifetime);
01903 getAttachedCollisionObjectMarkers(state, arr, name, attached_color, lifetime);
01904 }
01905
01906 void planning_environment::CollisionModels::getRobotMarkersGivenState(const planning_models::KinematicState& state,
01907 visualization_msgs::MarkerArray& arr,
01908 const std_msgs::ColorRGBA& color,
01909 const std::string& name,
01910 const ros::Duration& lifetime,
01911 const std::vector<std::string>* names,
01912 const double scale,
01913 const bool show_collision_models) const
01914 {
01915 boost::shared_ptr<urdf::Model> robot_model = getParsedDescription();
01916
01917 std::vector<std::string> link_names;
01918 if(names == NULL)
01919 {
01920 kmodel_->getLinkModelNames(link_names);
01921 }
01922 else
01923 {
01924 link_names = *names;
01925 }
01926
01927 for(unsigned int i = 0; i < link_names.size(); i++)
01928 {
01929 boost::shared_ptr<const urdf::Link> urdf_link = robot_model->getLink(link_names[i]);
01930
01931 if(!urdf_link)
01932 {
01933 ROS_INFO_STREAM("Invalid urdf name " << link_names[i]);
01934 continue;
01935 }
01936
01937 if(show_collision_models && !urdf_link->collision && !urdf_link->visual)
01938 {
01939 continue;
01940 }
01941 if(!show_collision_models && !urdf_link->visual)
01942 {
01943 continue;
01944 }
01945 const urdf::Geometry *geom = NULL;
01946 if(show_collision_models && urdf_link->collision) {
01947 geom = urdf_link->collision->geometry.get();
01948 } else if(urdf_link->visual) {
01949 geom = urdf_link->visual->geometry.get();
01950 }
01951
01952 if(!geom)
01953 {
01954 continue;
01955 }
01956
01957 const urdf::Mesh *mesh = dynamic_cast<const urdf::Mesh*> (geom);
01958 const urdf::Box *box = dynamic_cast<const urdf::Box*> (geom);
01959 const urdf::Sphere *sphere = dynamic_cast<const urdf::Sphere*> (geom);
01960 const urdf::Cylinder *cylinder = dynamic_cast<const urdf::Cylinder*> (geom);
01961
01962 const planning_models::KinematicState::LinkState* ls = state.getLinkState(link_names[i]);
01963
01964 if(ls == NULL)
01965 {
01966 ROS_WARN_STREAM("No link state for name " << names << " though there's a mesh");
01967 continue;
01968 }
01969
01970 visualization_msgs::Marker mark;
01971 mark.header.frame_id = getWorldFrameId();
01972 mark.header.stamp = ros::Time::now();
01973 mark.ns = name;
01974 mark.id = i;
01975 mark.lifetime = lifetime;
01976 tf::poseTFToMsg(ls->getGlobalCollisionBodyTransform(), mark.pose);
01977 mark.color = color;
01978
01979 if(mesh)
01980 {
01981 if(mesh->filename.empty())
01982 {
01983 continue;
01984 }
01985 mark.type = mark.MESH_RESOURCE;
01986 mark.scale.x = mesh->scale.x*scale;
01987 mark.scale.y = mesh->scale.y*scale;
01988 mark.scale.z = mesh->scale.z*scale;
01989 mark.mesh_resource = mesh->filename;
01990 }
01991 else if(box)
01992 {
01993 mark.type = mark.CUBE;
01994 mark.scale.x = box->dim.x;
01995 mark.scale.y = box->dim.y;
01996 mark.scale.z = box->dim.z;
01997 }
01998 else if(cylinder)
01999 {
02000 mark.type = mark.CYLINDER;
02001 mark.scale.x = cylinder->radius;
02002 mark.scale.y = cylinder->radius;
02003 mark.scale.z = cylinder->length;
02004 } else if(sphere) {
02005 mark.type = mark.SPHERE;
02006 mark.scale.x = mark.scale.y = mark.scale.z = sphere->radius;
02007 } else {
02008 ROS_WARN_STREAM("Unknown object type for link " << link_names[i]);
02009 continue;
02010 }
02011 arr.markers.push_back(mark);
02012 }
02013 }
02014
02015 void planning_environment::CollisionModels::getRobotPaddedMarkersGivenState(const planning_models::KinematicState& state,
02016 visualization_msgs::MarkerArray& arr,
02017 const std_msgs::ColorRGBA& color,
02018 const std::string& name,
02019 const ros::Duration& lifetime,
02020 const std::vector<std::string>* names) const
02021 {
02022 std::vector<std::string> link_names;
02023 if(names == NULL)
02024 {
02025 kmodel_->getLinkModelNames(link_names);
02026 }
02027 else
02028 {
02029 link_names = *names;
02030 }
02031 for(unsigned int i = 0; i < link_names.size(); i++) {
02032 const planning_models::KinematicState::LinkState* ls = state.getLinkState(link_names[i]);
02033 if(ls->getLinkModel()->getLinkShape() == NULL) continue;
02034
02035 const tf::Transform& trans = ls->getGlobalCollisionBodyTransform();
02036
02037 visualization_msgs::Marker mark;
02038 mark.header.frame_id = getWorldFrameId();
02039 mark.header.stamp = ros::Time::now();
02040 mark.ns = name;
02041 mark.id = i;
02042 mark.color = color;
02043 mark.lifetime = lifetime;
02044 tf::poseTFToMsg(trans, mark.pose);
02045
02046 double padding = 0.0;
02047 if(getCurrentLinkPaddingMap().find(ls->getName()) !=
02048 getCurrentLinkPaddingMap().end()) {
02049 padding = getCurrentLinkPaddingMap().find(ls->getName())->second;
02050 }
02051 setMarkerShapeFromShape(ls->getLinkModel()->getLinkShape(), mark, padding);
02052 arr.markers.push_back(mark);
02053 }
02054 }
02055
02056 void planning_environment::CollisionModels::getGroupAndUpdatedJointMarkersGivenState(const planning_models::KinematicState& state,
02057 visualization_msgs::MarkerArray& arr,
02058 const std::string& group_name,
02059 const std_msgs::ColorRGBA& group_color,
02060 const std_msgs::ColorRGBA& updated_color,
02061 const ros::Duration& lifetime) const {
02062
02063 const planning_models::KinematicModel::JointModelGroup* jmg = kmodel_->getModelGroup(group_name);
02064
02065 if(jmg == NULL) {
02066 ROS_WARN_STREAM("No group " << group_name << " for visualization");
02067 return;
02068 }
02069
02070 std::vector<std::string> group_link_names = jmg->getGroupLinkNames();
02071 getRobotMarkersGivenState(state,
02072 arr,
02073 group_color,
02074 group_name,
02075 lifetime,
02076 &group_link_names);
02077
02078 std::vector<std::string> updated_link_model_names = jmg->getUpdatedLinkModelNames();
02079 std::map<std::string, bool> dont_include;
02080 for(unsigned int i = 0; i < group_link_names.size(); i++) {
02081 dont_include[group_link_names[i]] = true;
02082 }
02083
02084 std::vector<std::string> ex_list;
02085 for(unsigned int i = 0; i < updated_link_model_names.size(); i++) {
02086 if(dont_include.find(updated_link_model_names[i]) == dont_include.end()) {
02087 ex_list.push_back(updated_link_model_names[i]);
02088 }
02089 }
02090 getRobotMarkersGivenState(state,
02091 arr,
02092 updated_color,
02093 group_name+"_updated_links",
02094 lifetime,
02095 &ex_list);
02096
02097 }
02098
02099
02100 void planning_environment::CollisionModels::writePlanningSceneBag(const std::string& filename,
02101 const arm_navigation_msgs::PlanningScene& planning_scene) const
02102 {
02103 rosbag::Bag bag;
02104 bag.open(filename, rosbag::bagmode::Write);
02105
02106 ros::Time t = planning_scene.robot_state.joint_state.header.stamp;
02107 bag.write("planning_scene", t, planning_scene);
02108 bag.close();
02109 }
02110
02111 bool planning_environment::CollisionModels::readPlanningSceneBag(const std::string& filename,
02112 arm_navigation_msgs::PlanningScene& planning_scene) const
02113 {
02114 rosbag::Bag bag;
02115 try {
02116 bag.open(filename, rosbag::bagmode::Read);
02117 } catch(rosbag::BagException) {
02118 ROS_WARN_STREAM("Could not open bag file " << filename);
02119 return false;
02120 }
02121
02122 std::vector<std::string> topics;
02123 topics.push_back("planning_scene");
02124
02125 rosbag::View view(bag, rosbag::TopicQuery(topics));
02126
02127 bool has_one = false;
02128 BOOST_FOREACH(rosbag::MessageInstance const m, view)
02129 {
02130 arm_navigation_msgs::PlanningScene::ConstPtr ps = m.instantiate<arm_navigation_msgs::PlanningScene>();
02131 if(ps != NULL) {
02132 planning_scene = *ps;
02133 has_one = true;
02134 }
02135 }
02136 if(!has_one) {
02137 ROS_WARN_STREAM("Filename " << filename << " does not seem to contain a planning scene");
02138 return false;
02139 }
02140 return true;
02141 }
02142
02143 bool planning_environment::CollisionModels::appendMotionPlanRequestToPlanningSceneBag(const std::string& filename,
02144 const std::string& topic_name,
02145 const arm_navigation_msgs::MotionPlanRequest& req)
02146 {
02147 rosbag::Bag bag;
02148 try {
02149 bag.open(filename, rosbag::bagmode::Append);
02150 } catch(rosbag::BagException) {
02151 ROS_WARN_STREAM("Could not append to bag file " << filename);
02152 return false;
02153 }
02154 ros::Time t = req.start_state.joint_state.header.stamp;
02155 bag.write(topic_name, ros::Time::now(), req);
02156 bag.close();
02157 return true;
02158 }
02159
02160 bool planning_environment::CollisionModels::loadMotionPlanRequestsInPlanningSceneBag(const std::string& filename,
02161 const std::string& topic_name,
02162 std::vector<arm_navigation_msgs::MotionPlanRequest>& motion_plan_reqs){
02163 rosbag::Bag bag;
02164 try {
02165 bag.open(filename, rosbag::bagmode::Read);
02166 } catch(rosbag::BagException) {
02167 ROS_WARN_STREAM("Could not open bag file " << filename);
02168 return false;
02169 }
02170
02171 std::vector<std::string> topics;
02172 topics.push_back(topic_name);
02173
02174 rosbag::View view(bag, rosbag::TopicQuery(topics));
02175
02176 BOOST_FOREACH(rosbag::MessageInstance const m, view)
02177 {
02178 arm_navigation_msgs::MotionPlanRequest::ConstPtr mpr = m.instantiate<arm_navigation_msgs::MotionPlanRequest>();
02179 if(mpr != NULL) {
02180 motion_plan_reqs.push_back(*mpr);
02181 }
02182 }
02183 if(motion_plan_reqs.size() == 0) {
02184 ROS_WARN_STREAM("No MotionPlanRequest messages with topic name " << topic_name << " in " << filename);
02185 return false;
02186 }
02187 return true;
02188 }
02189
02190 bool planning_environment::CollisionModels::loadJointTrajectoriesInPlanningSceneBag(const std::string& filename,
02191 const std::string& topic_name,
02192 std::vector<trajectory_msgs::JointTrajectory>& traj_vec){
02193 rosbag::Bag bag;
02194 try {
02195 bag.open(filename, rosbag::bagmode::Read);
02196 } catch(rosbag::BagException) {
02197 ROS_WARN_STREAM("Could not open bag file " << filename);
02198 return false;
02199 }
02200
02201 std::vector<std::string> topics;
02202 topics.push_back(topic_name);
02203
02204 rosbag::View view(bag, rosbag::TopicQuery(topics));
02205
02206 BOOST_FOREACH(rosbag::MessageInstance const m, view)
02207 {
02208 trajectory_msgs::JointTrajectory::ConstPtr jt = m.instantiate<trajectory_msgs::JointTrajectory>();
02209 if(jt != NULL) {
02210 traj_vec.push_back(*jt);
02211 }
02212 }
02213 if(traj_vec.size() == 0) {
02214 ROS_WARN_STREAM("No JointTrajectory messages with topic name " << topic_name << " in " << filename);
02215 return false;
02216 }
02217 return true;
02218 }
02219
02220 bool planning_environment::CollisionModels::appendJointTrajectoryToPlanningSceneBag(const std::string& filename,
02221 const std::string& topic_name,
02222 const trajectory_msgs::JointTrajectory& traj)
02223 {
02224 rosbag::Bag bag;
02225 try {
02226 bag.open(filename, rosbag::bagmode::Append);
02227 } catch(rosbag::BagException) {
02228 ROS_WARN_STREAM("Could not append to bag file " << filename);
02229 return false;
02230 }
02231 bag.write(topic_name, ros::Time::now(), traj);
02232 bag.close();
02233 return true;
02234 }
02235