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/monitors/collision_space_monitor.h"
00038 #include "planning_environment/util/construct_object.h"
00039 #include <geometry_msgs/PointStamped.h>
00040 #include <geometry_msgs/PoseStamped.h>
00041 #include <geometric_shapes/shape_operations.h>
00042 #include <boost/bind.hpp>
00043 #include <climits>
00044 #include <sstream>
00045
00046 static const std::string GET_COLLISION_OBJECTS_SERVICE_NAME = "get_collision_objects";
00047 static const std::string GET_CURRENT_ALLOWED_COLLISION_MATRIX_SERVICE_NAME = "get_current_allowed_collision_matrix";
00048 static const std::string SET_ALLOWED_COLLISIONS_SERVICE_NAME="set_allowed_collisions";
00049 static const std::string REVERT_ALLOWED_COLLISIONS_SERVICE_NAME="revert_allowed_collisions";
00050
00051 namespace planning_environment
00052 {
00053
00054 static inline double maxCoord(const geometry_msgs::Point32 &point)
00055 {
00056 return std::max(std::max(point.x, point.y), point.z);
00057 }
00058 }
00059
00060 void planning_environment::CollisionSpaceMonitor::setupCSM(void)
00061 {
00062 envMonitorStarted_ = false;
00063 onBeforeMapUpdate_ = NULL;
00064 onAfterMapUpdate_ = NULL;
00065 onCollisionObjectUpdate_ = NULL;
00066 onAfterAttachCollisionObject_ = NULL;
00067
00068 collisionMapFilter_ = NULL;
00069 collisionMapUpdateFilter_ = NULL;
00070 collisionObjectFilter_ = NULL;
00071
00072 collisionMapSubscriber_ = NULL;
00073 collisionMapUpdateSubscriber_ = NULL;
00074 collisionObjectSubscriber_ = NULL;
00075
00076 haveMap_ = false;
00077 use_collision_map_ = false;
00078
00079 collisionSpace_ = cm_->getODECollisionModel().get();
00080 collisionSpace_->clearObjects("points");
00081 nh_.param<double>("pointcloud_padd", pointcloud_padd_, 0.02);
00082 nh_.param<double>("object_scale", scale_, 1.0);
00083 nh_.param<double>("object_padd", padd_, 0.02);
00084
00085 }
00086
00087 void planning_environment::CollisionSpaceMonitor::startEnvironmentMonitor(void)
00088 {
00089 if (envMonitorStarted_)
00090 return;
00091
00092 if(use_collision_map_) {
00093 collisionMapSubscriber_ = new message_filters::Subscriber<mapping_msgs::CollisionMap>(root_handle_, "collision_map", 1);
00094 collisionMapFilter_ = new tf::MessageFilter<mapping_msgs::CollisionMap>(*collisionMapSubscriber_, *tf_, getWorldFrameId(), 1);
00095 collisionMapFilter_->registerCallback(boost::bind(&CollisionSpaceMonitor::collisionMapCallback, this, _1));
00096 ROS_DEBUG("Listening to collision_map using message notifier with target frame %s", collisionMapFilter_->getTargetFramesString().c_str());
00097
00098 collisionMapUpdateSubscriber_ = new message_filters::Subscriber<mapping_msgs::CollisionMap>(root_handle_, "collision_map_update", 1024);
00099 collisionMapUpdateFilter_ = new tf::MessageFilter<mapping_msgs::CollisionMap>(*collisionMapUpdateSubscriber_, *tf_, getWorldFrameId(), 1);
00100 collisionMapUpdateFilter_->registerCallback(boost::bind(&CollisionSpaceMonitor::collisionMapUpdateCallback, this, _1));
00101 ROS_DEBUG("Listening to collision_map_update using message notifier with target frame %s", collisionMapUpdateFilter_->getTargetFramesString().c_str());
00102 }
00103
00104 collisionObjectSubscriber_ = new message_filters::Subscriber<mapping_msgs::CollisionObject>(root_handle_, "collision_object", 1024);
00105 collisionObjectFilter_ = new tf::MessageFilter<mapping_msgs::CollisionObject>(*collisionObjectSubscriber_, *tf_, getWorldFrameId(), 1024);
00106 collisionObjectFilter_->registerCallback(boost::bind(&CollisionSpaceMonitor::collisionObjectCallback, this, _1));
00107 ROS_DEBUG("Listening to object_in_map using message notifier with target frame %s", collisionMapUpdateFilter_->getTargetFramesString().c_str());
00108
00109
00110 attachedCollisionObjectSubscriber_ = new message_filters::Subscriber<mapping_msgs::AttachedCollisionObject>(root_handle_, "attached_collision_object", 1024);
00111 attachedCollisionObjectSubscriber_->registerCallback(boost::bind(&CollisionSpaceMonitor::attachObjectCallback, this, _1));
00112
00113 advertiseServices();
00114
00115 envMonitorStarted_ = true;
00116 }
00117
00118 void planning_environment::CollisionSpaceMonitor::advertiseServices() {
00119 KinematicModelStateMonitor::advertiseServices();
00120 get_objects_service_ = ros::NodeHandle("~").advertiseService(GET_COLLISION_OBJECTS_SERVICE_NAME, &CollisionSpaceMonitor::getObjectsService, this);
00121 get_current_collision_map_service_ = ros::NodeHandle("~").advertiseService(GET_CURRENT_ALLOWED_COLLISION_MATRIX_SERVICE_NAME, &CollisionSpaceMonitor::getCurrentAllowedCollisionsService, this);
00122 set_allowed_collisions_service_ = ros::NodeHandle("~").advertiseService(SET_ALLOWED_COLLISIONS_SERVICE_NAME, &CollisionSpaceMonitor::setAllowedCollisionsService, this);
00123 revert_allowed_collisions_service_ = ros::NodeHandle("~").advertiseService(REVERT_ALLOWED_COLLISIONS_SERVICE_NAME, &CollisionSpaceMonitor::revertAllowedCollisionMatrixToDefaultService, this);
00124 }
00125
00126 void planning_environment::CollisionSpaceMonitor::setUseCollisionMap(bool use_collision_map) {
00127 if(use_collision_map_ == use_collision_map) return;
00128
00129 use_collision_map_ = use_collision_map;
00130
00131 if(!envMonitorStarted_) return;
00132
00133 if(use_collision_map_) {
00134 collisionMapSubscriber_ = new message_filters::Subscriber<mapping_msgs::CollisionMap>(root_handle_, "collision_map", 1);
00135 collisionMapFilter_ = new tf::MessageFilter<mapping_msgs::CollisionMap>(*collisionMapSubscriber_, *tf_, getWorldFrameId(), 1);
00136 collisionMapFilter_->registerCallback(boost::bind(&CollisionSpaceMonitor::collisionMapCallback, this, _1));
00137 ROS_DEBUG("Listening to collision_map using message notifier with target frame %s", collisionMapFilter_->getTargetFramesString().c_str());
00138
00139 collisionMapUpdateSubscriber_ = new message_filters::Subscriber<mapping_msgs::CollisionMap>(root_handle_, "collision_map_update", 1);
00140 collisionMapUpdateFilter_ = new tf::MessageFilter<mapping_msgs::CollisionMap>(*collisionMapUpdateSubscriber_, *tf_, getWorldFrameId(), 1);
00141 collisionMapUpdateFilter_->registerCallback(boost::bind(&CollisionSpaceMonitor::collisionMapUpdateCallback, this, _1));
00142 ROS_DEBUG("Listening to collision_map_update using message notifier with target frame %s", collisionMapUpdateFilter_->getTargetFramesString().c_str());
00143 } else {
00144 if(collisionMapUpdateFilter_) {
00145 delete collisionMapUpdateFilter_;
00146 collisionMapUpdateFilter_ = NULL;
00147 }
00148 if(collisionMapUpdateSubscriber_) {
00149 delete collisionMapUpdateSubscriber_;
00150 collisionMapUpdateSubscriber_ = NULL;
00151 }
00152 if(collisionMapFilter_) {
00153 delete collisionMapFilter_;
00154 collisionMapFilter_ = NULL;
00155 }
00156
00157 if(collisionMapSubscriber_) {
00158 delete collisionMapSubscriber_;
00159 collisionMapSubscriber_ = NULL;
00160 }
00161 }
00162 }
00163
00164 void planning_environment::CollisionSpaceMonitor::stopEnvironmentMonitor(void)
00165 {
00166 if (!envMonitorStarted_)
00167 return;
00168
00169 if(collisionMapUpdateFilter_) {
00170 delete collisionMapUpdateFilter_;
00171 collisionMapUpdateFilter_ = NULL;
00172 }
00173 if(collisionMapUpdateSubscriber_) {
00174 delete collisionMapUpdateSubscriber_;
00175 collisionMapUpdateSubscriber_ = NULL;
00176 }
00177 if(collisionMapFilter_) {
00178 delete collisionMapFilter_;
00179 collisionMapFilter_ = NULL;
00180 }
00181
00182 if(collisionMapSubscriber_) {
00183 delete collisionMapSubscriber_;
00184 collisionMapSubscriber_ = NULL;
00185 }
00186
00187 if(collisionObjectFilter_) {
00188 delete collisionObjectFilter_;
00189 collisionObjectFilter_ = NULL;
00190 }
00191
00192 if(collisionObjectSubscriber_) {
00193 delete collisionObjectSubscriber_;
00194 collisionObjectSubscriber_ = NULL;
00195 }
00196
00197 if(attachedCollisionObjectSubscriber_) {
00198 delete attachedCollisionObjectSubscriber_;
00199 attachedCollisionObjectSubscriber_ = NULL;
00200 }
00201
00202 for (std::map<std::string, KnownObject*>::iterator it = collisionObjects_.begin() ; it != collisionObjects_.end() ; ++it)
00203 delete it->second;
00204
00205 for(unsigned int i = 0; i < last_collision_map_shapes_.size(); i++) {
00206 delete last_collision_map_shapes_[i];
00207 }
00208
00209 ROS_DEBUG("Environment state is no longer being monitored");
00210
00211 envMonitorStarted_ = false;
00212 }
00213
00214 bool planning_environment::CollisionSpaceMonitor::isMapUpdated(double sec) const
00215 {
00216 if(sec < 1e-5)
00217 {
00218 return false;
00219 }
00220
00221
00222 if(lastMapUpdate_ > ros::TIME_MIN && ros::Time::now() < ros::Time(sec))
00223 {
00224 return true;
00225 }
00226
00227
00228 if (lastMapUpdate_ < ros::Time::now()-ros::Duration(sec))
00229 {
00230 return false;
00231 }
00232
00233 return true;
00234 }
00235
00236 void planning_environment::CollisionSpaceMonitor::waitForMap(void) const
00237 {
00238 if(!use_collision_map_) {
00239 ROS_INFO("Not subscribing to map so not waiting");
00240 return;
00241 }
00242 int s = 0;
00243 while (nh_.ok() && !haveMap())
00244 {
00245 if (s == 0)
00246 ROS_INFO("Waiting for map ...");
00247 s = (s + 1) % 40;
00248 ros::spinOnce();
00249 ros::Duration().fromSec(0.05).sleep();
00250 }
00251 if (haveMap())
00252 ROS_INFO("Map received!");
00253 }
00254
00255 void planning_environment::CollisionSpaceMonitor::collisionMapUpdateCallback(const mapping_msgs::CollisionMapConstPtr &collisionMap)
00256 {
00257 if (collisionMap->boxes.size() > 0)
00258 updateCollisionSpace(collisionMap, false);
00259 }
00260
00261 void planning_environment::CollisionSpaceMonitor::collisionMapCallback(const mapping_msgs::CollisionMapConstPtr &collisionMap)
00262 {
00263 updateCollisionSpace(collisionMap, true);
00264 }
00265
00266 void planning_environment::CollisionSpaceMonitor::collisionMapAsSpheres(const mapping_msgs::CollisionMapConstPtr &collisionMap,
00267 std::vector<shapes::Shape*> &spheres, std::vector<btTransform> &poses)
00268 {
00269
00270 bool transform = collisionMap->header.frame_id != getWorldFrameId();
00271 const int n = collisionMap->boxes.size();
00272
00273 spheres.resize(n);
00274 poses.resize(n);
00275
00276 if (transform)
00277 {
00278 std::string target = getWorldFrameId();
00279 bool err = false;
00280
00281
00282 for (int i = 0 ; i < n ; ++i)
00283 {
00284 geometry_msgs::PointStamped psi;
00285 psi.header = collisionMap->header;
00286 psi.point.x = collisionMap->boxes[i].center.x;
00287 psi.point.y = collisionMap->boxes[i].center.y;
00288 psi.point.z = collisionMap->boxes[i].center.z;
00289
00290 geometry_msgs::PointStamped pso;
00291 try
00292 {
00293 tf_->transformPoint(target, psi, pso);
00294 }
00295 catch(...)
00296 {
00297 err = true;
00298 pso = psi;
00299 }
00300
00301 poses[i].setIdentity();
00302 poses[i].setOrigin(btVector3(pso.point.x, pso.point.y, pso.point.z));
00303 spheres[i] = new shapes::Sphere(maxCoord(collisionMap->boxes[i].extents) * 0.867 + pointcloud_padd_);
00304 }
00305
00306 if (err)
00307 ROS_ERROR("Some errors encountered in transforming the collision map to frame '%s' from frame '%s'", target.c_str(), collisionMap->header.frame_id.c_str());
00308 }
00309 else
00310 {
00311
00312
00313 for (int i = 0 ; i < n ; ++i)
00314 {
00315 poses[i].setIdentity();
00316 poses[i].setOrigin(btVector3(collisionMap->boxes[i].center.x, collisionMap->boxes[i].center.y, collisionMap->boxes[i].center.z));
00317 spheres[i] = new shapes::Sphere(maxCoord(collisionMap->boxes[i].extents) * 0.867 + pointcloud_padd_);
00318 }
00319 }
00320 }
00321
00322 void planning_environment::CollisionSpaceMonitor::collisionMapAsBoxes(const mapping_msgs::CollisionMapConstPtr &collisionMap,
00323 std::vector<shapes::Shape*> &boxes, std::vector<btTransform> &poses)
00324 {
00325 collisionMapAsBoxes(*collisionMap, boxes, poses);
00326 }
00327
00328 void planning_environment::CollisionSpaceMonitor::collisionMapAsBoxes(const mapping_msgs::CollisionMap& collisionMap,
00329 std::vector<shapes::Shape*> &boxes, std::vector<btTransform> &poses)
00330 {
00331
00332
00333 bool transform = collisionMap.header.frame_id != getWorldFrameId();
00334 const int n = collisionMap.boxes.size();
00335
00336 double pd = 2.0 * pointcloud_padd_;
00337
00338 boxes.resize(n);
00339 poses.resize(n);
00340
00341 if (transform)
00342 {
00343 std::string target = getWorldFrameId();
00344 bool err = false;
00345
00346
00347 for (int i = 0 ; i < n ; ++i)
00348 {
00349 geometry_msgs::PointStamped psi;
00350 psi.header = collisionMap.header;
00351 psi.point.x = collisionMap.boxes[i].center.x;
00352 psi.point.y = collisionMap.boxes[i].center.y;
00353 psi.point.z = collisionMap.boxes[i].center.z;
00354
00355 geometry_msgs::PointStamped pso;
00356 try
00357 {
00358 tf_->transformPoint(target, psi, pso);
00359 }
00360 catch(...)
00361 {
00362 err = true;
00363 pso = psi;
00364 }
00365
00366 poses[i].setRotation(btQuaternion(btVector3(collisionMap.boxes[i].axis.x, collisionMap.boxes[i].axis.y, collisionMap.boxes[i].axis.z), collisionMap.boxes[i].angle));
00367 poses[i].setOrigin(btVector3(pso.point.x, pso.point.y, pso.point.z));
00368 boxes[i] = new shapes::Box(collisionMap.boxes[i].extents.x + pd, collisionMap.boxes[i].extents.y + pd, collisionMap.boxes[i].extents.z + pd);
00369 }
00370
00371 if (err)
00372 ROS_ERROR("Some errors encountered in transforming the collision map to frame '%s' from frame '%s'", target.c_str(), collisionMap.header.frame_id.c_str());
00373 }
00374 else
00375 {
00376
00377
00378 for (int i = 0 ; i < n ; ++i)
00379 {
00380 poses[i].setRotation(btQuaternion(btVector3(collisionMap.boxes[i].axis.x, collisionMap.boxes[i].axis.y, collisionMap.boxes[i].axis.z), collisionMap.boxes[i].angle));
00381 poses[i].setOrigin(btVector3(collisionMap.boxes[i].center.x, collisionMap.boxes[i].center.y, collisionMap.boxes[i].center.z));
00382 boxes[i] = new shapes::Box(collisionMap.boxes[i].extents.x + pd, collisionMap.boxes[i].extents.y + pd, collisionMap.boxes[i].extents.z + pd);
00383 }
00384 }
00385 }
00386
00387 void planning_environment::CollisionSpaceMonitor::updateStaticObjectBodies(const mapping_msgs::CollisionObjectConstPtr &collisionObject) {
00388 collision_objects_lock_.lock();
00389 if (collisionObject->operation.operation == mapping_msgs::CollisionObjectOperation::ADD) {
00390 KnownObject* kb = new KnownObject();
00391 for(unsigned int i = 0; i < collisionObject->shapes.size(); i++) {
00392
00393 shapes::Shape *shape = planning_environment::constructObject(collisionObject->shapes[i]);
00394 if (shape) {
00395 bool err = false;
00396 geometry_msgs::PoseStamped psi;
00397 geometry_msgs::PoseStamped pso;
00398 psi.pose = collisionObject->poses[i];
00399 psi.header = collisionObject->header;
00400 try {
00401 tf_->transformPose(getWorldFrameId(), psi, pso);
00402 } catch(tf::TransformException& ex) {
00403 ROS_ERROR("Unable to transform object '%s' in frame '%s' to frame '%s' Exception: %s", collisionObject->id.c_str(), collisionObject->header.frame_id.c_str(), getWorldFrameId().c_str(), ex.what()); err = true;
00404 }
00405
00406 if (!err) {
00407 btTransform pose;
00408 tf::poseMsgToTF(pso.pose, pose);
00409 bodies::Body* body = bodies::createBodyFromShape(shape);
00410 body->setScale(scale_);
00411 body->setPadding(padd_);
00412 kb->addBodyWithPose(body, pose);
00413 }
00414 delete shape;
00415 }
00416 }
00417
00418 if(collisionObjects_.find(collisionObject->id) != collisionObjects_.end()) {
00419 delete collisionObjects_[collisionObject->id];
00420 collisionObjects_.erase(collisionObject->id);
00421 }
00422 collisionObjects_[collisionObject->id] = kb;
00423 ROS_INFO("Added object '%s' with to list of known objects", collisionObject->id.c_str());
00424 } else {
00425 if(collisionObject->id == "all") {
00426 for(std::map<std::string, KnownObject*>::iterator it = collisionObjects_.begin();
00427 it != collisionObjects_.end();
00428 it++) {
00429 delete it->second;
00430 }
00431 collisionObjects_.clear();
00432 } else if (collisionObjects_.find(collisionObject->id) != collisionObjects_.end()) {
00433 delete collisionObjects_[collisionObject->id];
00434 collisionObjects_.erase(collisionObject->id);
00435 } else
00436 ROS_WARN("Object '%s' is not in list of known objects", collisionObject->id.c_str());
00437 }
00438 collision_objects_lock_.unlock();
00439 setCollisionSpace();
00440 }
00441
00442 void planning_environment::CollisionSpaceMonitor::maskCollisionMapForCollisionObjects(std::vector<shapes::Shape*>& shapes,
00443 std::vector<btTransform>& poses,
00444 std::vector<bool>& mask)
00445 {
00446
00447 btVector3 sensor_pos(0, 0, 0);
00448
00449 if(shapes.size() != poses.size()) {
00450 ROS_WARN("Unequal number shapes and poses");
00451 return;
00452 }
00453 if(shapes.size() != mask.size()) {
00454 ROS_WARN("Unequal number shapes and mask");
00455 return;
00456 }
00457
00458 std::vector<shapes::Shape*>::iterator shapeit = shapes.begin();
00459 std::vector<btTransform>::iterator poseit = poses.begin();
00460 std::vector<bool>::iterator maskit = mask.begin();
00461
00462 collision_objects_lock_.lock();
00463 while(shapeit != shapes.end()) {
00464 btVector3 pt = (*poseit).getOrigin();
00465 btVector3 dir(sensor_pos - pt);
00466 dir.normalize();
00467 bool inside = false;
00468 for (std::map<std::string, KnownObject*>::iterator it = collisionObjects_.begin() ; !inside && it != collisionObjects_.end() ; ++it) {
00469 KnownObject* ko = it->second;
00470 for (unsigned int j = 0 ; !inside && j < ko->bodies.size(); ++j) {
00471 if(ko->bodies.size() != ko->bspheres.size() ||
00472 ko->bodies.size() != ko->rsquares.size()) {
00473 ROS_ERROR_STREAM("Bad sizes " << ko->bodies.size() << " " << ko->bspheres.size()
00474 << " " << ko->rsquares.size());
00475 continue;
00476 }
00477 if (ko->bspheres[j].center.distance2(pt) < ko->rsquares[j]) {
00478 if(ko->bodies[j]->containsPoint(pt)) {
00479 inside = true;
00480 }
00481
00482
00483
00484 }
00485 }
00486 }
00487 *maskit = !inside;
00488 shapeit++;
00489 poseit++;
00490 maskit++;
00491 }
00492 collision_objects_lock_.unlock();
00493 }
00494
00495 void planning_environment::CollisionSpaceMonitor::updateCollisionSpace(const mapping_msgs::CollisionMapConstPtr &collisionMap, bool clear)
00496 {
00497 collision_map_lock_.lock();
00498 for(unsigned int i = 0; i < last_collision_map_shapes_.size(); i++) {
00499 delete last_collision_map_shapes_[i];
00500 }
00501 last_collision_map_shapes_.clear();
00502 last_collision_map_poses_.clear();
00503 last_collision_map_object_mask_.clear();
00504
00505 collisionMapAsBoxes(*collisionMap, last_collision_map_shapes_, last_collision_map_poses_);
00506 last_collision_map_object_mask_.resize(last_collision_map_shapes_.size(), true);
00507 lastMapUpdate_ = collisionMap->header.stamp;
00508 collision_map_lock_.unlock();
00509 haveMap_ = true;
00510 }
00511
00512 void planning_environment::CollisionSpaceMonitor::setCollisionSpace() {
00513
00514 if(haveMap_) {
00515 getEnvironmentModel()->lock();
00516 collision_map_lock_.lock();
00517
00518
00519 ros::WallTime startTime = ros::WallTime::now();
00520
00521 maskCollisionMapForCollisionObjects(last_collision_map_shapes_, last_collision_map_poses_, last_collision_map_object_mask_);
00522
00523 std::vector<shapes::Shape*> unmasked_shapes;
00524 std::vector<btTransform> unmasked_poses;
00525
00526 for(unsigned int i = 0; i < last_collision_map_shapes_.size(); i++) {
00527 if(last_collision_map_object_mask_[i]) {
00528 unmasked_shapes.push_back(shapes::cloneShape(last_collision_map_shapes_[i]));
00529 unmasked_poses.push_back(last_collision_map_poses_[i]);
00530 }
00531 }
00532
00533 ROS_DEBUG_STREAM("Before filter we had " << last_collision_map_shapes_.size() << " points and now we have " << unmasked_shapes.size() << " points.");
00534
00535 collision_map_lock_.unlock();
00536
00537 getEnvironmentModel()->clearObjects("points");
00538 if(unmasked_shapes.size() == 0) {
00539 ROS_DEBUG("There don't appear to be any points to set in the collision map");
00540 }
00541 getEnvironmentModel()->addObjects("points", unmasked_shapes, unmasked_poses);
00542 double tupd = (ros::WallTime::now() - startTime).toSec();
00543 ROS_DEBUG("Updated map model in %f seconds", tupd);
00544 getEnvironmentModel()->unlock();
00545 }
00546 }
00547
00548 void planning_environment::CollisionSpaceMonitor::collisionObjectCallback(const mapping_msgs::CollisionObjectConstPtr &collisionObject)
00549 {
00550 if (collisionObject->operation.operation == mapping_msgs::CollisionObjectOperation::ADD)
00551 {
00552 std::vector<shapes::Shape*> shapes;
00553 std::vector<btTransform> poses;
00554 bool shapes_ok = true;
00555 for(unsigned int i = 0; i < collisionObject->shapes.size(); i++) {
00556
00557
00558 shapes::Shape *shape = constructObject(collisionObject->shapes[i]);
00559 if (shape)
00560 {
00561 bool err = false;
00562 geometry_msgs::PoseStamped psi;
00563 geometry_msgs::PoseStamped pso;
00564 psi.pose = collisionObject->poses[i];
00565
00566 psi.header = collisionObject->header;
00567 try
00568 {
00569 tf_->transformPose(getWorldFrameId(), psi, pso);
00570 }
00571 catch(...)
00572 {
00573 err = true;
00574 }
00575
00576 if (err) {
00577 ROS_ERROR("Unable to transform object in ns %s num %d in frame %s to frame %s", collisionObject->id.c_str(), i, collisionObject->header.frame_id.c_str(), getWorldFrameId().c_str());
00578 shapes_ok = false;
00579 }
00580 else
00581 {
00582 btTransform pose;
00583 tf::poseMsgToTF(pso.pose, pose);
00584 ROS_DEBUG_STREAM("Object is at " << pose.getOrigin().x() << " " << pose.getOrigin().y());
00585 shapes.push_back(shape);
00586 poses.push_back(pose);
00587 }
00588 }
00589 }
00590 if(shapes_ok) {
00591 getEnvironmentModel()->lock();
00592 getEnvironmentModel()->clearObjects(collisionObject->id);
00593 getEnvironmentModel()->addObjects(collisionObject->id, shapes, poses);
00594 getEnvironmentModel()->unlock();
00595 ROS_INFO("Added %u object to namespace %s in collision space", (unsigned int)shapes.size(),collisionObject->id.c_str());
00596 } else {
00597 ROS_INFO_STREAM("Some shape in object " << collisionObject->id << " not ok, so not adding shape to collision space");
00598 }
00599 }
00600 else
00601 {
00602
00603 getEnvironmentModel()->lock();
00604 if(collisionObject->id == "all") {
00605 ROS_INFO("Clearing all collision objects");
00606 getEnvironmentModel()->clearObjects();
00607 } else {
00608 getEnvironmentModel()->clearObjects(collisionObject->id);
00609 }
00610 getEnvironmentModel()->unlock();
00611 ROS_INFO("Removed object '%s' from collision space", collisionObject->id.c_str());
00612 }
00613
00614 updateStaticObjectBodies(collisionObject);
00615
00616 if (onCollisionObjectUpdate_)
00617 onCollisionObjectUpdate_(collisionObject);
00618
00619 }
00620
00621 bool planning_environment::CollisionSpaceMonitor::attachObjectCallback(const mapping_msgs::AttachedCollisionObjectConstPtr &attached_object)
00622 {
00623 ROS_INFO("Calling attached object callback");
00624
00625 bool result = true;
00626
00627 getEnvironmentModel()->lock();
00628
00629 if(attached_object->link_name == "all") {
00630 if(attached_object->object.operation.operation != mapping_msgs::CollisionObjectOperation::REMOVE) {
00631 ROS_WARN("Can't perform any action for all attached bodies except remove");
00632 getEnvironmentModel()->unlock();
00633 return false;
00634 }
00635
00636 getKinematicModel()->clearAllAttachedBodyModels();
00637 getEnvironmentModel()->updateAttachedBodies();
00638 if(onAfterAttachCollisionObject_ != NULL) {
00639 onAfterAttachCollisionObject_(attached_object);
00640 }
00641 ROS_INFO("All attached bodies cleared");
00642 getEnvironmentModel()->unlock();
00643 return true;
00644 }
00645
00646 const planning_models::KinematicModel::LinkModel *link = getKinematicModel()->getLinkModel(attached_object->link_name);
00647
00648 if(!link) {
00649 ROS_WARN_STREAM("Can't find link " << attached_object->link_name << " indicated by attach message");
00650 getEnvironmentModel()->unlock();
00651 return false;
00652 }
00653
00654 unsigned int n = attached_object->object.shapes.size();
00655
00656 const mapping_msgs::CollisionObject& obj = attached_object->object;
00657
00658 if(n == 0) {
00659 if(obj.operation.operation == mapping_msgs::CollisionObjectOperation::REMOVE) {
00660
00661 getKinematicModel()->clearLinkAttachedBodyModels(link->getName());
00662 getEnvironmentModel()->updateAttachedBodies();
00663
00664 ROS_INFO_STREAM("Should have cleared all objects attached to " << link->getName());
00665
00666 if (onAfterAttachCollisionObject_ != NULL) {
00667 onAfterAttachCollisionObject_(attached_object);
00668 }
00669 getEnvironmentModel()->unlock();
00670 return true;
00671 } else if (obj.operation.operation == mapping_msgs::CollisionObjectOperation::ADD){
00672 ROS_INFO("Remove must also be specified to delete all attached bodies");
00673 getEnvironmentModel()->unlock();
00674 return false;
00675 }
00676 }
00677
00678 bool delAtEnd = false;
00679 bool addAtEnd = false;
00680
00681 const planning_models::KinematicModel::AttachedBodyModel* att = NULL;
00682 for (unsigned int i = 0 ; i < link->getAttachedBodyModels().size() ; ++i) {
00683 if(link->getAttachedBodyModels()[i]->getName() == obj.id) {
00684 att = link->getAttachedBodyModels()[i];
00685 break;
00686 }
00687 }
00688
00689 std::vector<btTransform> link_frame_poses;
00690 std::vector<shapes::Shape*> shapes;
00691
00692 if(obj.operation.operation == mapping_msgs::CollisionObjectOperation::DETACH_AND_ADD_AS_OBJECT) {
00693 if(att == NULL) {
00694 ROS_WARN_STREAM("No attached object found for detach with id " << obj.id);
00695 } else {
00696 getEnvironmentModel()->clearObjects(obj.id);
00697 std::vector<shapes::Shape*> shapes_temp;
00698 for(unsigned int i = 0; i < att->getShapes().size(); i++) {
00699 shapes_temp.push_back(shapes::cloneShape(att->getShapes()[i]));
00700 }
00701
00702 planning_models::KinematicState state(getKinematicModel());
00703 setStateValuesFromCurrentValues(state);
00704 const planning_models::KinematicState::AttachedBodyState* att_state = state.getAttachedBodyState(att->getName());
00705 getEnvironmentModel()->addObjects(obj.id, shapes_temp, att_state->getGlobalCollisionBodyTransforms());
00706 ROS_INFO_STREAM("Adding in attached object as regular object " << obj.id);
00707 delAtEnd = true;
00708 }
00709 } else if(obj.operation.operation == mapping_msgs::CollisionObjectOperation::ATTACH_AND_REMOVE_AS_OBJECT) {
00710 const collision_space::EnvironmentObjects *eo = getEnvironmentModel()->getObjects();
00711 std::vector<std::string> ns = eo->getNamespaces();
00712 bool found = false;
00713 for (unsigned int i = 0 ; i < ns.size() ; ++i) {
00714 if(ns[i] == obj.id) {
00715 found = true;
00716 const collision_space::EnvironmentObjects::NamespaceObjects &no = eo->getObjects(ns[i]);
00717 for(unsigned int j = 0; j < no.shape.size(); j++) {
00718 geometry_msgs::PoseStamped p1;
00719 geometry_msgs::PoseStamped p2;
00720 tf::poseTFToMsg(no.shapePose[j], p1.pose);
00721 std::string err_string;
00722 ros::Time tm;
00723 if (tf_->getLatestCommonTime(attached_object->link_name, getWorldFrameId(), tm, &err_string) == tf::NO_ERROR) {
00724 p1.header.stamp = tm;
00725 p1.header.frame_id = getWorldFrameId();
00726 tf_->transformPose(attached_object->link_name, p1, p2);
00727 } else {
00728 ROS_WARN_STREAM("No common time between " << attached_object->link_name << " and " << getWorldFrameId());
00729 }
00730 btTransform bt;
00731 tf::poseMsgToTF(p2.pose, bt);
00732 link_frame_poses.push_back(bt);
00733 shapes.push_back(shapes::cloneShape(no.shape[j]));
00734 }
00735 getEnvironmentModel()->clearObjects(obj.id);
00736 ROS_INFO_STREAM("Clearing object " << obj.id << " before attach");
00737 addAtEnd = true;
00738 break;
00739 }
00740 }
00741 if(!found) {
00742 ROS_WARN_STREAM("Couldn't find object " << obj.id << " for attach and remove");
00743 }
00744 } else if(obj.operation.operation == mapping_msgs::CollisionObjectOperation::REMOVE) {
00745 delAtEnd = true;
00746 } else {
00747
00748 for(unsigned int i = 0; i < obj.shapes.size(); i++) {
00749 geometry_msgs::PoseStamped pose;
00750 geometry_msgs::PoseStamped poseP;
00751 pose.pose = obj.poses[i];
00752 pose.header = obj.header;
00753 bool err = false;
00754 std::string err_string;
00755 ros::Time tm;
00756 if (tf_->getLatestCommonTime(attached_object->link_name, pose.header.frame_id, tm, &err_string) == tf::NO_ERROR) {
00757 pose.header.stamp = tm;
00758 try {
00759 tf_->transformPose(attached_object->link_name, pose, poseP);
00760 } catch(tf::TransformException& ex) {
00761 err = true;
00762 ROS_ERROR("Unable to transform object to be attached from frame %s to frame %s. TF said: %s", obj.header.frame_id.c_str(), attached_object->link_name.c_str(),ex.what());
00763 }
00764 } else {
00765 ROS_WARN_STREAM("No common time between " << attached_object->link_name << " and " << pose.header.frame_id);
00766 err = true;
00767 }
00768 if (err) {
00769 continue;
00770 }
00771
00772 shapes::Shape *shape = constructObject(obj.shapes[i]);
00773 if (!shape) {
00774 continue;
00775 }
00776 btTransform bt;
00777 tf::poseMsgToTF(poseP.pose, bt);
00778 link_frame_poses.push_back(bt);
00779 shapes.push_back(shape);
00780 addAtEnd = true;
00781
00782 if(att != NULL) {
00783 delAtEnd = true;
00784 }
00785 }
00786 }
00787
00788 bool hasCur = (att != NULL);
00789
00790
00791 if(delAtEnd) {
00792
00793 if(!hasCur) {
00794 ROS_WARN("Can't delete what we don't have");
00795 } else {
00796
00797 getKinematicModel()->clearLinkAttachedBodyModel(link->getName(), obj.id);
00798 ROS_INFO_STREAM("Removing attached body associated with " << obj.id);
00799 }
00800 }
00801 if(addAtEnd) {
00802
00803 std::vector<std::string> touch_links = attached_object->touch_links;
00804 if(find(touch_links.begin(),touch_links.end(), link->getName()) == touch_links.end()) {
00805 touch_links.push_back(link->getName());
00806 }
00807
00808 planning_models::KinematicModel::AttachedBodyModel* ab =
00809 new planning_models::KinematicModel::AttachedBodyModel(link, obj.id,
00810 link_frame_poses,
00811 touch_links,
00812 shapes);
00813 getKinematicModel()->addAttachedBodyModel(link->getName(),
00814 ab);
00815 ROS_INFO_STREAM("Trying to add attached body id " << obj.id << " to link " << link->getName());
00816 }
00817
00818 getEnvironmentModel()->updateAttachedBodies();
00819
00820 if (onAfterAttachCollisionObject_ != NULL)
00821 onAfterAttachCollisionObject_(attached_object);
00822
00823 getEnvironmentModel()->unlock();
00824 return result;
00825 }
00826
00827 bool planning_environment::CollisionSpaceMonitor::computeAllowedContact(const motion_planning_msgs::AllowedContactSpecification &allowed_contact,
00828 collision_space::EnvironmentModel::AllowedContact &allowedContact) const
00829 {
00830 shapes::Shape *shape = constructObject(allowed_contact.shape);
00831 if (shape)
00832 {
00833 boost::shared_ptr<bodies::Body> body(bodies::createBodyFromShape(shape));
00834 geometry_msgs::PoseStamped pose;
00835 tf_->transformPose(getWorldFrameId(), allowed_contact.pose_stamped, pose);
00836 btTransform tr;
00837 tf::poseMsgToTF(pose.pose, tr);
00838 body->setPose(tr);
00839 allowedContact.bound = body;
00840 allowedContact.links = allowed_contact.link_names;
00841 allowedContact.depth = allowed_contact.penetration_depth;
00842 delete shape;
00843 return true;
00844 }
00845 else
00846 return false;
00847 }
00848
00849 void planning_environment::CollisionSpaceMonitor::recoverCollisionMap(mapping_msgs::CollisionMap &cmap)
00850 {
00851 recoverCollisionMap(getEnvironmentModel(), cmap);
00852 }
00853
00854 void planning_environment::CollisionSpaceMonitor::recoverCollisionMap(const collision_space::EnvironmentModel *env, mapping_msgs::CollisionMap &cmap)
00855 {
00856 getEnvironmentModel()->lock();
00857
00858 cmap.header.frame_id = getWorldFrameId();
00859 cmap.header.stamp = ros::Time::now();
00860 cmap.boxes.clear();
00861
00862 const collision_space::EnvironmentObjects::NamespaceObjects &no = env->getObjects()->getObjects("points");
00863 const unsigned int n = no.shape.size();
00864
00865
00866 for (unsigned int i = 0 ; i < n ; ++i)
00867 if (no.shape[i]->type == shapes::BOX)
00868 {
00869 const shapes::Box* box = static_cast<const shapes::Box*>(no.shape[i]);
00870 mapping_msgs::OrientedBoundingBox obb;
00871 obb.extents.x = box->size[0];
00872 obb.extents.y = box->size[1];
00873 obb.extents.z = box->size[2];
00874
00875
00876
00877 const btVector3 &c = no.shapePose[i].getOrigin();
00878 obb.center.x = c.x();
00879 obb.center.y = c.y();
00880 obb.center.z = c.z();
00881 const btQuaternion q = no.shapePose[i].getRotation();
00882 obb.angle = q.getAngle();
00883 const btVector3 axis = q.getAxis();
00884 obb.axis.x = axis.x();
00885 obb.axis.y = axis.y();
00886 obb.axis.z = axis.z();
00887 cmap.boxes.push_back(obb);
00888 }
00889 getEnvironmentModel()->unlock();
00890 }
00891
00892 bool planning_environment::CollisionSpaceMonitor::getObjectsService(planning_environment_msgs::GetCollisionObjects::Request &req,
00893 planning_environment_msgs::GetCollisionObjects::Response &res) {
00894 getEnvironmentModel()->lock();
00895
00896 recoverCollisionObjects(getEnvironmentModel(), res.collision_objects);
00897 if(req.include_points) {
00898 recoverCollisionMap(getEnvironmentModel(),res.points);
00899 }
00900 recoverAttachedCollisionObjects(getEnvironmentModel(), res.attached_collision_objects);
00901
00902 getEnvironmentModel()->unlock();
00903 return true;
00904 }
00905
00906 void planning_environment::CollisionSpaceMonitor::recoverCollisionObjects(std::vector<mapping_msgs::CollisionObject> &omap)
00907 {
00908 recoverCollisionObjects(getEnvironmentModel(), omap);
00909 }
00910
00911 void planning_environment::CollisionSpaceMonitor::recoverCollisionObjects(const collision_space::EnvironmentModel *env, std::vector<mapping_msgs::CollisionObject> &omap)
00912 {
00913 getEnvironmentModel()->lock();
00914 omap.clear();
00915 const collision_space::EnvironmentObjects *eo = env->getObjects();
00916 std::vector<std::string> ns = eo->getNamespaces();
00917 for (unsigned int i = 0 ; i < ns.size() ; ++i)
00918 {
00919 if (ns[i] == "points")
00920 continue;
00921 const collision_space::EnvironmentObjects::NamespaceObjects &no = eo->getObjects(ns[i]);
00922 const unsigned int n = no.shape.size();
00923
00924 mapping_msgs::CollisionObject o;
00925 o.header.frame_id = getWorldFrameId();
00926 o.header.stamp = lastJointStateUpdate();
00927 o.id = ns[i];
00928 o.operation.operation = mapping_msgs::CollisionObjectOperation::ADD;
00929 for (unsigned int j = 0 ; j < n ; ++j) {
00930 geometric_shapes_msgs::Shape obj;
00931 if (constructObjectMsg(no.shape[j], obj)) {
00932 geometry_msgs::Pose pose;
00933 tf::poseTFToMsg(no.shapePose[j], pose);
00934 o.shapes.push_back(obj);
00935 o.poses.push_back(pose);
00936 }
00937 }
00938 omap.push_back(o);
00939 }
00940 getEnvironmentModel()->unlock();
00941 }
00942
00943 void planning_environment::CollisionSpaceMonitor::recoverAttachedCollisionObjects(std::vector<mapping_msgs::AttachedCollisionObject> &avec)
00944 {
00945 recoverAttachedCollisionObjects(getEnvironmentModel(), avec);
00946 }
00947
00948 void planning_environment::CollisionSpaceMonitor::recoverAttachedCollisionObjects(const collision_space::EnvironmentModel *env, std::vector<mapping_msgs::AttachedCollisionObject> &avec)
00949 {
00950 getEnvironmentModel()->lock();
00951
00952 planning_models::KinematicState state(getKinematicModel());
00953 setStateValuesFromCurrentValues(state);
00954 getEnvironmentModel()->updateRobotModel(&state);
00955
00956 avec.clear();
00957
00958 const std::vector<const planning_models::KinematicModel::AttachedBodyModel*>& att_vec = env->getAttachedBodies();
00959 for(unsigned int i = 0; i < att_vec.size(); i++)
00960 {
00961 mapping_msgs::AttachedCollisionObject ao;
00962 ao.object.header.frame_id = getWorldFrameId();
00963 ao.object.header.stamp = ros::Time::now();
00964 ao.link_name = att_vec[i]->getAttachedLinkModel()->getName();
00965 double attached_padd = env->getCurrentLinkPadding("attached");
00966 for(unsigned int j = 0; j < att_vec[i]->getShapes().size(); j++) {
00967 geometric_shapes_msgs::Shape shape;
00968 constructObjectMsg(att_vec[i]->getShapes()[j], shape, attached_padd);
00969 geometry_msgs::Pose pose;
00970 planning_models::KinematicState::AttachedBodyState* att_state = state.getAttachedBodyState(att_vec[i]->getName());
00971 if(att_state == NULL) {
00972 ROS_WARN_STREAM("No attached body state for attached body model " << att_vec[i]->getName());
00973 }
00974 tf::poseTFToMsg(att_state->getGlobalCollisionBodyTransforms()[j], pose);
00975 ao.object.shapes.push_back(shape);
00976 ao.object.poses.push_back(pose);
00977 }
00978 ao.touch_links = att_vec[i]->getTouchLinks();
00979 ao.object.id = att_vec[i]->getName();
00980 avec.push_back(ao);
00981 }
00982 getEnvironmentModel()->unlock();
00983 }
00984
00985 bool planning_environment::CollisionSpaceMonitor::getCurrentAllowedCollisionsService(planning_environment_msgs::GetAllowedCollisionMatrix::Request& req,
00986 planning_environment_msgs::GetAllowedCollisionMatrix::Response& res) {
00987 std::vector<std::vector<bool> > matrix;
00988 std::map<std::string, unsigned int> ind;
00989
00990 getEnvironmentModel()->lock();
00991 getEnvironmentModel()->getCurrentAllowedCollisionMatrix(matrix, ind);
00992 getEnvironmentModel()->unlock();
00993
00994
00995
00996 unsigned int i = 0;
00997 res.matrix.link_names.resize(ind.size());
00998 res.matrix.entries.resize(ind.size());
00999 for(std::map<std::string, unsigned int>::iterator it = ind.begin();
01000 it != ind.end();
01001 it++,i++) {
01002 res.matrix.link_names[i] = it->first;
01003 res.matrix.entries[i].enabled.resize(matrix[it->second].size());
01004 unsigned int j = 0;
01005 for(std::map<std::string, unsigned int>::iterator it2 = ind.begin();
01006 it2 != ind.end();
01007 it2++,j++) {
01008 res.matrix.entries[i].enabled[j] = matrix[it->second][it2->second];
01009 }
01010 }
01011 return true;
01012 }
01013
01014 bool planning_environment::CollisionSpaceMonitor::setAllowedCollisionsService(planning_environment_msgs::SetAllowedCollisions::Request& req,
01015 planning_environment_msgs::SetAllowedCollisions::Response& res)
01016 {
01017 getEnvironmentModel()->lock();
01018 bool ok = applyOrderedCollisionOperationsToCollisionSpace(req.ord);
01019 if(!ok) {
01020 ROS_WARN("Can't apply ordered collision operations");
01021 getEnvironmentModel()->unlock();
01022 return false;
01023 }
01024 planning_environment_msgs::GetAllowedCollisionMatrix::Request greq;
01025 planning_environment_msgs::GetAllowedCollisionMatrix::Response gres;
01026 getCurrentAllowedCollisionsService(greq,gres);
01027 res.matrix = gres.matrix;
01028 getEnvironmentModel()->unlock();
01029 return true;
01030 }
01031
01032 bool planning_environment::CollisionSpaceMonitor::revertAllowedCollisionMatrixToDefaultService(std_srvs::Empty::Request& req,
01033 std_srvs::Empty::Response& res) {
01034 getEnvironmentModel()->lock();
01035 revertAllowedCollisionToDefault();
01036 getEnvironmentModel()->unlock();
01037 return true;
01038 }
01039
01040 bool planning_environment::CollisionSpaceMonitor::applyOrderedCollisionOperationsToCollisionSpace(const motion_planning_msgs::OrderedCollisionOperations &ord, bool print) {
01041
01042
01043 std::vector<std::vector<bool> > curAllowed;
01044 std::map<std::string, unsigned int> vecIndices;
01045 getEnvironmentModel()->lock();
01046 getEnvironmentModel()->getDefaultAllowedCollisionMatrix(curAllowed, vecIndices);
01047 getEnvironmentModel()->unlock();
01048
01049 motion_planning_msgs::OrderedCollisionOperations expanded;
01050 expandOrderedCollisionOperations(ord, expanded);
01051
01052
01053
01054
01055 bool ok = applyOrderedCollisionOperationsToMatrix(expanded, curAllowed, vecIndices);
01056
01057 if(print) {
01058 printAllowedCollisionMatrix(curAllowed, vecIndices);
01059 }
01060
01061 getEnvironmentModel()->lock();
01062 getEnvironmentModel()->setAllowedCollisionMatrix(curAllowed, vecIndices);
01063 getEnvironmentModel()->unlock();
01064 return ok;
01065 }
01066
01067 bool planning_environment::CollisionSpaceMonitor::applyOrderedCollisionOperationsToMatrix(const motion_planning_msgs::OrderedCollisionOperations &ord,
01068 std::vector<std::vector<bool> > &curAllowed,
01069 std::map<std::string, unsigned int> &vecIndices) {
01070 size_t all_size = curAllowed.size();
01071
01072 for(size_t i = 0; i < ord.collision_operations.size(); i++) {
01073
01074 bool allowed = (ord.collision_operations[i].operation == motion_planning_msgs::CollisionOperation::DISABLE);
01075
01076 if(ord.collision_operations[i].object1 == ord.collision_operations[i].COLLISION_SET_ALL &&
01077 ord.collision_operations[i].object2 == ord.collision_operations[i].COLLISION_SET_ALL) {
01078
01079 for(size_t j = 0; j < all_size; j++) {
01080 for(size_t k = 0; k < all_size; k++) {
01081 curAllowed[j][k] = allowed;
01082 }
01083 }
01084 } else if(ord.collision_operations[i].object1 == ord.collision_operations[i].COLLISION_SET_ALL ||
01085 ord.collision_operations[i].object2 == ord.collision_operations[i].COLLISION_SET_ALL) {
01086
01087 std::string other;
01088 if(ord.collision_operations[i].object1 == ord.collision_operations[i].COLLISION_SET_ALL) {
01089 other = ord.collision_operations[i].object2;
01090 } else {
01091 other = ord.collision_operations[i].object1;
01092 }
01093 if(vecIndices.find(other) == vecIndices.end()) {
01094 continue;
01095 }
01096 unsigned int obj_ind = vecIndices.find(other)->second;
01097 for(size_t j = 0; j < all_size; j++) {
01098 curAllowed[obj_ind][j] = allowed;
01099 curAllowed[j][obj_ind] = allowed;
01100 }
01101 } else {
01102
01103 if(vecIndices.find(ord.collision_operations[i].object1) == vecIndices.end() ||
01104 vecIndices.find(ord.collision_operations[i].object2) == vecIndices.end()) {
01105 continue;
01106 }
01107 unsigned int obj1ind = vecIndices.find(ord.collision_operations[i].object1)->second;
01108 unsigned int obj2ind = vecIndices.find(ord.collision_operations[i].object2)->second;
01109 curAllowed[obj1ind][obj2ind] = allowed;
01110 curAllowed[obj2ind][obj1ind] = allowed;
01111 }
01112 }
01113 return true;
01114 }
01115
01116
01117 void planning_environment::CollisionSpaceMonitor::revertAllowedCollisionToDefault() {
01118
01119 getEnvironmentModel()->lock();
01120 getEnvironmentModel()->revertAllowedCollisionMatrix();
01121 getEnvironmentModel()->unlock();
01122 }
01123
01124 void planning_environment::CollisionSpaceMonitor::applyLinkPaddingToCollisionSpace(const std::vector<motion_planning_msgs::LinkPadding>& link_padding) {
01125 if(link_padding.empty()) return;
01126
01127 const std::map<std::string, std::vector<std::string > >& group_link_map = rm_->getPlanningGroupLinks();
01128 std::map<std::string, double> link_padding_map;
01129
01130 for(std::vector<motion_planning_msgs::LinkPadding>::const_iterator it = link_padding.begin();
01131 it != link_padding.end();
01132 it++) {
01133 std::vector<std::string> svec1;
01134 if(group_link_map.find((*it).link_name) != group_link_map.end()) {
01135 svec1 = group_link_map.find((*it).link_name)->second;
01136 } else {
01137 svec1.push_back((*it).link_name);
01138 }
01139 for(std::vector<std::string>::iterator stit1 = svec1.begin();
01140 stit1 != svec1.end();
01141 stit1++) {
01142 link_padding_map[(*stit1)] = (*it).padding;
01143 }
01144 }
01145
01146 getEnvironmentModel()->lock();
01147 getEnvironmentModel()->setRobotLinkPadding(link_padding_map);
01148 getEnvironmentModel()->unlock();
01149
01150 }
01151
01152 void planning_environment::CollisionSpaceMonitor::revertCollisionSpacePaddingToDefault() {
01153 getEnvironmentModel()->lock();
01154 getEnvironmentModel()->revertRobotLinkPadding();
01155 getEnvironmentModel()->unlock();
01156 }
01157
01158 bool planning_environment::CollisionSpaceMonitor::expandOrderedCollisionOperations(const motion_planning_msgs::OrderedCollisionOperations &ord,
01159 motion_planning_msgs::OrderedCollisionOperations &ex) {
01160 getEnvironmentModel()->lock();
01161
01162 std::vector<std::string> o_strings;
01163 std::vector<mapping_msgs::CollisionObject> ovec;
01164 recoverCollisionObjects(getEnvironmentModel(), ovec);
01165 for(std::vector<mapping_msgs::CollisionObject>::iterator it = ovec.begin();
01166 it != ovec.end();
01167 it++) {
01168 o_strings.push_back((*it).id);
01169 }
01170
01171 o_strings.push_back("points");
01172
01173 getKinematicModel()->sharedLock();
01174 std::vector<std::string> a_strings;
01175 const std::vector<const planning_models::KinematicModel::AttachedBodyModel*>& att_vec = getEnvironmentModel()->getAttachedBodies();
01176 for(unsigned int i = 0; i < att_vec.size(); i++)
01177 {
01178 a_strings.push_back(att_vec[i]->getName());
01179 }
01180 getKinematicModel()->sharedUnlock();
01181
01182 const std::map<std::string, std::vector<std::string > >& group_link_map = rm_->getPlanningGroupLinks();
01183
01184 ex = ord;
01185 std::vector<motion_planning_msgs::CollisionOperation>::iterator it = ex.collision_operations.begin();
01186 while(it != ex.collision_operations.end()) {
01187 std::vector<std::string> svec1;
01188 std::vector<std::string> svec2;
01189 bool special1 = false;
01190 bool special2 = false;
01191 if((*it).object1 == (*it).COLLISION_SET_OBJECTS) {
01192 svec1 = o_strings;
01193 special1 = true;
01194 }
01195 if((*it).object2 == (*it).COLLISION_SET_OBJECTS) {
01196 svec2 = o_strings;
01197 special2 = true;
01198 }
01199 if((*it).object1 == (*it).COLLISION_SET_ATTACHED_OBJECTS) {
01200 svec1 = a_strings;
01201 if(a_strings.empty()) {
01202 ROS_DEBUG_STREAM("No attached bodies");
01203 } else {
01204 ROS_DEBUG_STREAM("Setting first vec to all attached bodies, first entry " << a_strings[0]);
01205 }
01206 special1 = true;
01207 }
01208 if((*it).object2 == (*it).COLLISION_SET_ATTACHED_OBJECTS) {
01209 svec2 = a_strings;
01210 if(a_strings.empty()) {
01211 ROS_DEBUG_STREAM("No attached bodies");
01212 } else {
01213 ROS_DEBUG_STREAM("Setting second vec to all attached bodies, first entry " << a_strings[0]);
01214 }
01215 special2 = true;
01216 }
01217 if(group_link_map.find((*it).object1) != group_link_map.end()) {
01218 svec1 = group_link_map.find((*it).object1)->second;
01219 special1 = true;
01220 }
01221 if(group_link_map.find((*it).object2) != group_link_map.end()) {
01222 svec2 = group_link_map.find((*it).object2)->second;
01223 special2 = true;
01224 }
01225 if(!special1) {
01226 svec1.push_back((*it).object1);
01227 }
01228 if(!special2) {
01229 svec2.push_back((*it).object2);
01230 }
01231
01232 int32_t op = (*it).operation;
01233
01234
01235 it = ex.collision_operations.erase(it);
01236
01237
01238
01239
01240
01241
01242 for(std::vector<std::string>::iterator stit1 = svec1.begin();
01243 stit1 != svec1.end();
01244 stit1++) {
01245 for(std::vector<std::string>::iterator stit2 = svec2.begin();
01246 stit2 != svec2.end();
01247 stit2++) {
01248 motion_planning_msgs::CollisionOperation coll;
01249 coll.object1 = (*stit1);
01250 coll.object2 = (*stit2);
01251 coll.operation = op;
01252 it = ex.collision_operations.insert(it,coll);
01253 it++;
01254 }
01255 }
01256 }
01257 for(it = ex.collision_operations.begin(); it != ex.collision_operations.end();it++) {
01258 ROS_DEBUG_STREAM("Expanded coll " << (*it).object1 << " " << (*it).object2 << " op " << (*it).operation);
01259 }
01260 getEnvironmentModel()->unlock();
01261 return true;
01262 }
01263
01264
01265 void planning_environment::CollisionSpaceMonitor::printAllowedCollisionMatrix(const std::vector<std::vector<bool> > &curAllowed,
01266 const std::map<std::string, unsigned int> &vecIndices) const {
01267 size_t all_size = curAllowed.size();
01268 for(unsigned int i = 0; i < vecIndices.size(); i++) {
01269 std::string n;
01270 for(std::map<std::string, unsigned int>::const_iterator it = vecIndices.begin();
01271 it != vecIndices.end();
01272 it++) {
01273 if(it->second == i) {
01274 n = it->first;
01275 }
01276 }
01277 if(n.empty()) {
01278 ROS_WARN_STREAM("Can't find index " << i << " in vecIndex");
01279 return;
01280 }
01281 std::cout << std::setw(40) << n;
01282 std::cout << " | ";
01283 for(size_t j = 0; j < all_size; j++) {
01284 std::cout << std::setw(3) << curAllowed[i][j];
01285 }
01286 std::cout << std::endl;
01287 }
01288 }
01289
01290 void planning_environment::CollisionSpaceMonitor::addAttachedCollisionObjects(std::vector<std::string>& svec) const {
01291
01292 getKinematicModel()->sharedLock();
01293
01294 std::vector<std::string>::iterator stit = svec.begin();
01295 while(stit != svec.end()) {
01296 const std::vector<const planning_models::KinematicModel::AttachedBodyModel*> att_vec = getEnvironmentModel()->getAttachedBodies(*stit);
01297
01298 stit++;
01299 for(std::vector<const planning_models::KinematicModel::AttachedBodyModel*>::const_iterator ait = att_vec.begin();
01300 ait != att_vec.end();
01301 ait++) {
01302 ROS_DEBUG_STREAM("Adding attached collision object " << (*ait)->getName() << " to list");
01303 stit = svec.insert(stit,(*ait)->getName());
01304 }
01305 }
01306
01307 getKinematicModel()->sharedUnlock();
01308 }