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
00044 #include <ros/ros.h>
00045 #include <tf/tf.h>
00046 #include <tf/transform_listener.h>
00047
00048 #include <visualization_msgs/Marker.h>
00049 #include <geometric_shapes/shapes.h>
00050 #include <geometric_shapes_msgs/Shape.h>
00051 #include <mapping_msgs/CollisionMap.h>
00052 #include <planning_environment_msgs/GetCollisionObjects.h>
00053
00054 #include <iostream>
00055 #include <sstream>
00056 #include <string>
00057 #include <map>
00058
00059 static const std::string GET_OBJECTS_SERVICE_NAME = "get_collision_objects";
00060 static const std::string COLLISION_MARKER_TOPIC = "collision_model_markers";
00061
00062 static const unsigned int FAILURE_MAX = 5;
00063
00064 class DisplayPlannerCollisionModel
00065 {
00066 public:
00067
00068 DisplayPlannerCollisionModel(void): nh_("~")
00069 {
00070 ros::NodeHandle root_node;
00071
00072 nh_.param<std::string>("prefix", prefix_, "environment_server");
00073 nh_.param<bool>("skip_collision_map", skip_collision_map_, false);
00074
00075 visualizationMarkerPublisher_ = root_node.advertise<visualization_msgs::Marker>(COLLISION_MARKER_TOPIC+prefix_, 10240);
00076
00077 if(!skip_collision_map_) {
00078 collision_map_publisher_ = root_node.advertise<mapping_msgs::CollisionMap>("collision_rebroadcast_"+prefix_, 10240);
00079 }
00080
00081 std::string service_name = prefix_+"/"+GET_OBJECTS_SERVICE_NAME;
00082
00083 ROS_INFO_STREAM("Going to wait for service " << service_name);
00084
00085 ros::service::waitForService(service_name);
00086
00087 ROS_INFO_STREAM("Connected to " << service_name);
00088
00089 get_objects_service_client_ = root_node.serviceClient<planning_environment_msgs::GetCollisionObjects>(service_name);
00090
00091 object_color_.a = 0.5;
00092 object_color_.r = 0.1;
00093 object_color_.g = 0.8;
00094 object_color_.b = 0.3;
00095
00096 attached_color_.a = 0.5;
00097 attached_color_.r = 0.6;
00098 attached_color_.g = 0.4;
00099 attached_color_.b = 0.3;
00100
00101 failure_count_= 0;
00102
00103 }
00104
00105 virtual ~DisplayPlannerCollisionModel(void)
00106 {
00107 }
00108
00109 void run(void)
00110 {
00111 unsigned int update = 0;
00112
00113 ros::Rate r(4);
00114
00115 while(ros::NodeHandle().ok()) {
00116 ros::spinOnce();
00117 if(++update%4 == 0) {
00118 publishMapObjects();
00119 }
00120 r.sleep();
00121 }
00122 }
00123
00124 protected:
00125
00126 void publishMapObjects() {
00127
00128 planning_environment_msgs::GetCollisionObjects::Request req;
00129 planning_environment_msgs::GetCollisionObjects::Response res;
00130
00131 req.include_points = !skip_collision_map_;
00132
00133 bool serviceOk = get_objects_service_client_.call(req,res);
00134
00135 if(!serviceOk) {
00136 failure_count_++;
00137 if(failure_count_ < FAILURE_MAX) {
00138 ROS_WARN("Display failed to call get objects service");
00139 }
00140 } else {
00141 failure_count_ = 0;
00142 }
00143 if(failure_count_ > 0 && failure_count_ < FAILURE_MAX) {
00144 ROS_WARN("Display failed to call get objects service");
00145 }
00146
00147 if(res.points.boxes.size() != 0) {
00148 ROS_DEBUG_STREAM("Publishing " << res.points.boxes.size() << " points.");
00149 collision_map_publisher_.publish(res.points);
00150 }
00151
00152 ROS_DEBUG_STREAM("Got " << res.collision_objects.size() << " objects from collision space");
00153 ROS_DEBUG_STREAM("Got " << res.attached_collision_objects.size() << " attached objects from collision space");
00154
00155 std::map<std::string, unsigned int> current_num;
00156
00157
00158 for(std::map<std::string, unsigned int>::iterator it = cur_collision_objects_.begin();
00159 it != cur_collision_objects_.end();
00160 it++) {
00161 current_num[it->first] = 0;
00162 }
00163
00164 for(std::vector<mapping_msgs::CollisionObject>::iterator it = res.collision_objects.begin();
00165 it != res.collision_objects.end();
00166 it++) {
00167 current_num[(*it).id] = (*it).shapes.size();
00168 }
00169
00170 std::vector<std::string> er_ids;
00171 std::map<std::string, unsigned int>::iterator it = cur_collision_objects_.begin();
00172 while(it != cur_collision_objects_.end()) {
00173
00174 if(current_num[it->first] < it->second) {
00175 mapping_msgs::CollisionObject obj;
00176 obj.header.frame_id = "base_link";
00177 obj.header.stamp = ros::Time::now();
00178 std::string id = prefix_+"---"+it->first;
00179 obj.operation.operation = mapping_msgs::CollisionObjectOperation::REMOVE;
00180 publishObjects(obj, id, object_color_, it->second);
00181
00182 if(current_num[it->first] == 0) {
00183 er_ids.push_back(it->first);
00184 }
00185 }
00186 it++;
00187 }
00188 for(std::vector<std::string>::iterator ir = er_ids.begin();
00189 ir != er_ids.end();
00190 ir++) {
00191 cur_collision_objects_.erase(*ir);
00192 }
00193
00194 for(std::vector<mapping_msgs::CollisionObject>::iterator it = res.collision_objects.begin();
00195 it != res.collision_objects.end();
00196 it++) {
00197 cur_collision_objects_[(*it).id] = (*it).shapes.size();
00198 std::string id = prefix_+"---"+(*it).id;
00199 publishObjects(*it, id, object_color_);
00200 }
00201
00202
00203 current_num.clear();
00204
00205
00206 for(std::map<std::string, unsigned int>::iterator it = cur_attached_objects_.begin();
00207 it != cur_attached_objects_.end();
00208 it++) {
00209 current_num[it->first] = 0;
00210 }
00211
00212 for(std::vector<mapping_msgs::AttachedCollisionObject>::iterator it = res.attached_collision_objects.begin();
00213 it != res.attached_collision_objects.end();
00214 it++) {
00215 std::string id = (*it).link_name+"+"+(*it).object.id;
00216 current_num[id] = (*it).object.shapes.size();
00217 }
00218
00219 er_ids.clear();
00220 it = cur_attached_objects_.begin();
00221 while(it != cur_attached_objects_.end()) {
00222
00223 if(current_num[it->first] < it->second) {
00224 mapping_msgs::CollisionObject obj;
00225 obj.header.frame_id = "base_link";
00226 obj.header.stamp = ros::Time::now();
00227 std::string id = prefix_+"---"+it->first;
00228 obj.operation.operation = mapping_msgs::CollisionObjectOperation::REMOVE;
00229 publishObjects(obj, id, attached_color_, it->second);
00230
00231 if(current_num[it->first] == 0) {
00232 er_ids.push_back(it->first);
00233 }
00234 }
00235 it++;
00236 }
00237 for(std::vector<std::string>::iterator ir = er_ids.begin();
00238 ir != er_ids.end();
00239 ir++) {
00240 cur_attached_objects_.erase(*ir);
00241 }
00242
00243 for(std::vector<mapping_msgs::AttachedCollisionObject>::iterator it = res.attached_collision_objects.begin();
00244 it != res.attached_collision_objects.end();
00245 it++) {
00246 std::string id1 = (*it).link_name+"+"+(*it).object.id;
00247 cur_attached_objects_[id1] = (*it).object.shapes.size();
00248 std::string id2 = prefix_+"---"+id1;
00249 publishObjects((*it).object, id2, attached_color_);
00250 }
00251 }
00252
00253 void publishObjects(const mapping_msgs::CollisionObject& collisionObject, const std::string id, const std_msgs::ColorRGBA color, unsigned int num = 0) {
00254 visualization_msgs::Marker mk;
00255
00256 if (collisionObject.operation.operation == mapping_msgs::CollisionObjectOperation::REMOVE) {
00257 for(unsigned int i = 0; i < num; i++) {
00258 mk.ns = id;
00259 mk.id = i;
00260 mk.header = collisionObject.header;
00261 mk.header.stamp = ros::Time::now();
00262 mk.action = visualization_msgs::Marker::DELETE;
00263 mk.color = color;
00264 visualizationMarkerPublisher_.publish(mk);
00265 ROS_DEBUG_STREAM("Sending delete for " << mk.ns << " id " << i);
00266 }
00267 return;
00268 }
00269
00270 if (collisionObject.operation.operation == mapping_msgs::CollisionObjectOperation::ADD) {
00271 for(unsigned int i = 0; i < collisionObject.shapes.size(); i++) {
00272 mk.ns = id;
00273 mk.id = i;
00274 mk.header = collisionObject.header;
00275 mk.header.stamp = ros::Time::now();
00276 mk.action = visualization_msgs::Marker::ADD;
00277 setObject(collisionObject.shapes[i], mk);
00278 mk.pose = collisionObject.poses[i];
00279 mk.color = color;
00280 visualizationMarkerPublisher_.publish(mk);
00281 }
00282 }
00283 }
00284
00285 private:
00286
00287 void setObject(const geometric_shapes_msgs::Shape &obj, visualization_msgs::Marker &mk)
00288 {
00289 switch (obj.type)
00290 {
00291 case geometric_shapes_msgs::Shape::SPHERE:
00292 mk.type = visualization_msgs::Marker::SPHERE;
00293 mk.scale.x = mk.scale.y = mk.scale.z = obj.dimensions[0] * 2.0;
00294 break;
00295
00296 case geometric_shapes_msgs::Shape::BOX:
00297 mk.type = visualization_msgs::Marker::CUBE;
00298 mk.scale.x = obj.dimensions[0];
00299 mk.scale.y = obj.dimensions[1];
00300 mk.scale.z = obj.dimensions[2];
00301 break;
00302
00303 case geometric_shapes_msgs::Shape::CYLINDER:
00304 mk.type = visualization_msgs::Marker::CYLINDER;
00305 mk.scale.x = obj.dimensions[0] * 2.0;
00306 mk.scale.y = obj.dimensions[0] * 2.0;
00307 mk.scale.z = obj.dimensions[1];
00308 break;
00309
00310 case geometric_shapes_msgs::Shape::MESH:
00311 mk.type = visualization_msgs::Marker::LINE_LIST;
00312 mk.scale.x = mk.scale.y = mk.scale.z = 0.001;
00313 {
00314 unsigned int nt = obj.triangles.size() / 3;
00315 for (unsigned int i = 0 ; i < nt ; ++i)
00316 {
00317 mk.points.push_back(obj.vertices[obj.triangles[3*i]]);
00318 mk.points.push_back(obj.vertices[obj.triangles[3*i+ 1]]);
00319 mk.points.push_back(obj.vertices[obj.triangles[3*i]]);
00320 mk.points.push_back(obj.vertices[obj.triangles[3*i+2]]);
00321 mk.points.push_back(obj.vertices[obj.triangles[3*i+1]]);
00322 mk.points.push_back(obj.vertices[obj.triangles[3*i+2]]);
00323 }
00324 }
00325
00326 break;
00327
00328 default:
00329 ROS_ERROR("Unknown object type: %d", (int)obj.type);
00330 }
00331 }
00332
00333 void setObject(const shapes::Shape *obj, visualization_msgs::Marker &mk)
00334 {
00335 switch (obj->type)
00336 {
00337 case shapes::SPHERE:
00338 mk.type = visualization_msgs::Marker::SPHERE;
00339 mk.scale.x = mk.scale.y = mk.scale.z = static_cast<const shapes::Sphere*>(obj)->radius * 2.0;
00340 break;
00341
00342 case shapes::BOX:
00343 mk.type = visualization_msgs::Marker::CUBE;
00344 {
00345 const double *size = static_cast<const shapes::Box*>(obj)->size;
00346 mk.scale.x = size[0];
00347 mk.scale.y = size[1];
00348 mk.scale.z = size[2];
00349 }
00350 break;
00351
00352 case shapes::CYLINDER:
00353 mk.type = visualization_msgs::Marker::CYLINDER;
00354 mk.scale.x = static_cast<const shapes::Cylinder*>(obj)->radius * 2.0;
00355 mk.scale.y = mk.scale.x;
00356 mk.scale.z = static_cast<const shapes::Cylinder*>(obj)->length;
00357 break;
00358
00359 case shapes::MESH:
00360 mk.type = visualization_msgs::Marker::LINE_LIST;
00361 mk.scale.x = mk.scale.y = mk.scale.z = 0.001;
00362 {
00363 const shapes::Mesh *mesh = static_cast<const shapes::Mesh*>(obj);
00364 unsigned int nt = mesh->triangleCount / 3;
00365 for (unsigned int i = 0 ; i < nt ; ++i)
00366 {
00367 unsigned int v = mesh->triangles[3*i];
00368 geometry_msgs::Point pt1;
00369 pt1.x = mesh->vertices[v];
00370 pt1.y = mesh->vertices[v+1];
00371 pt1.z = mesh->vertices[v+2];
00372 mk.points.push_back(pt1);
00373
00374 v = mesh->triangles[3*i + 1];
00375 geometry_msgs::Point pt2;
00376 pt2.x = mesh->vertices[v];
00377 pt2.y = mesh->vertices[v+1];
00378 pt2.z = mesh->vertices[v+2];
00379 mk.points.push_back(pt2);
00380
00381 mk.points.push_back(pt1);
00382
00383 v = mesh->triangles[3*i + 2];
00384 geometry_msgs::Point pt3;
00385 pt3.x = mesh->vertices[v];
00386 pt3.y = mesh->vertices[v+1];
00387 pt3.z = mesh->vertices[v+2];
00388 mk.points.push_back(pt3);
00389
00390 mk.points.push_back(pt2);
00391 mk.points.push_back(pt3);
00392 }
00393 }
00394
00395 break;
00396
00397 default:
00398 ROS_ERROR("Unknown object type: %d", (int)obj->type);
00399 }
00400 }
00401
00402 void sendPoint(int id, const std::string &ns, double x, double y, double z, double radius, const std::string& frame_id, const ros::Time &stamp)
00403 {
00404 visualization_msgs::Marker mk;
00405 mk.header.frame_id = frame_id;
00406 mk.header.stamp = stamp;
00407
00408 mk.id = id;
00409 mk.type = visualization_msgs::Marker::SPHERE;
00410 mk.action = visualization_msgs::Marker::ADD;
00411
00412 mk.pose.position.x = x;
00413 mk.pose.position.y = y;
00414 mk.pose.position.z = z;
00415 mk.pose.orientation.w = 1.0;
00416
00417 mk.scale.x = mk.scale.y = mk.scale.z = radius * 2.0;
00418
00419 mk.color.a = 1.0;
00420 mk.color.r = 0.9;
00421 mk.color.g = 0.1;
00422 mk.color.b = 0.1;
00423 mk.lifetime = ros::Duration(10.0);
00424
00425 visualizationMarkerPublisher_.publish(mk);
00426 }
00427
00428 ros::NodeHandle nh_;
00429 tf::TransformListener tf_;
00430 ros::Publisher visualizationMarkerPublisher_;
00431 ros::ServiceClient get_objects_service_client_;
00432 bool skip_collision_map_;
00433 std::map<std::string, unsigned int> cur_collision_objects_;
00434 std::map<std::string, unsigned int> cur_attached_objects_;
00435 ros::Publisher collision_map_publisher_;
00436 std::string prefix_;
00437 std_msgs::ColorRGBA object_color_;
00438 std_msgs::ColorRGBA attached_color_;
00439 unsigned int failure_count_;
00440 };
00441
00442 int main(int argc, char **argv)
00443 {
00444 ros::init(argc, argv, "display_planner_collision_model");
00445
00446 DisplayPlannerCollisionModel disp;
00447 disp.run();
00448
00449 return 0;
00450 }