00001
00002 extern volatile bool g_stopall;
00003 #define NO_MAIN_PRG
00004
00005 #include "CollisionInterface.h"
00006
00007
00008 #include "Signature.h"
00009 #include "SegmentPrototype.h"
00010
00011 using namespace cop;
00012
00013
00014 void SetShape( arm_navigation_msgs::Shape& sout, const GeometricShape& shape);
00015
00016 typedef struct
00017 {
00018 double x;
00019 double y;
00020 double z;
00021 }
00022 Point3D;
00023
00024 geometry_msgs::Pose RelPoseToRosPose(RelPose* relpose, LocatedObjectID_t rel = 4)
00025 {
00026 geometry_msgs::Pose pose;
00027 Matrix m = relpose->GetMatrix(rel);
00028 pose.position.x = m.element(0,3);
00029 pose.position.y = m.element(1,3);
00030 pose.position.z = m.element(2,3);
00031
00032
00033 double trace = m.element(0,0) + m.element(1,1) + m.element(2,2);
00034 if(trace > 0) {
00035 double s = 0.5 / sqrt(1.0 + trace);
00036 pose.orientation.w = 0.25 / s;
00037 pose.orientation.x = (m.element(2,1) - m.element(1,2)) * s;
00038 pose.orientation.y = (m.element(0,2) - m.element(2,0)) * s;
00039 pose.orientation.z = (m.element(1,0) - m.element(0,1)) * s;
00040 } else {
00041 if (m.element(0,0) > m.element(1,1) && m.element(0,0) > m.element(2,2)) {
00042 double s = 0.5 / sqrt(1.0 + m.element(0,0) - m.element(1,1) - m.element(2,2));
00043 pose.orientation.w = (m.element(2,1) - m.element(1,2)) * s;
00044 pose.orientation.x = 0.25 / s;
00045 pose.orientation.y = (m.element(0,1) + m.element(1,0)) * s;
00046 pose.orientation.z = (m.element(0,2) + m.element(2,0)) * s;
00047 } else if (m.element(1,1) > m.element(2,2)) {
00048 double s = 0.5 / sqrt(1.0 + m.element(1,1) - m.element(0,0) - m.element(2,2));
00049 pose.orientation.w = (m.element(0,2) - m.element(2,0)) * s;
00050 pose.orientation.x = (m.element(0,1) + m.element(1,0)) * s;
00051 pose.orientation.y = 0.25 / s;
00052 pose.orientation.z = (m.element(1,2) + m.element(2,1)) * s;
00053 } else {
00054 double s = 0.5 / sqrt(1.0 + m.element(2,2) - m.element(0,0) - m.element(1,1));
00055 pose.orientation.w = (m.element(1,0) - m.element(0,1)) * s;
00056 pose.orientation.x = (m.element(0,2) + m.element(2,0)) * s;
00057 pose.orientation.y = (m.element(1,2) + m.element(2,1)) * s;
00058 pose.orientation.z = 0.25 / s;
00059 }
00060 }
00061 return pose;
00062 }
00063
00064
00065
00066
00067 geometry_msgs::Pose RelPoseToRosPose____obs(RelPose* relpose, LocatedObjectID_t rel = 4)
00068 {
00069 geometry_msgs::Pose pose;
00070 Matrix m = relpose->GetMatrix(rel);
00071 pose.position.x = m.element(0,3);
00072 pose.position.y = m.element(1,3);
00073 pose.position.z = m.element(2,3);
00074
00078 double S, T = 1 + m.element(0,0) + m.element(1,1) + m.element(2,2);
00079
00080
00081
00082
00083
00084 if ( T > 0.00000001 )
00085 {
00086 S = sqrt(T) * 2;
00087 pose.orientation.x = ( m.element(1,2) - m.element(2,1) ) / S;
00088 pose.orientation.y = ( m.element(2,0) - m.element(0,2) ) / S;
00089 pose.orientation.z = ( m.element(0,1) - m.element(1,0) ) / S;
00090 pose.orientation.w = 0.25 * S;
00091 }
00092 else
00093 {
00094
00095
00096
00097
00098
00099 if ( m.element(0,0) > m.element(1,1) && m.element(0,0) > m.element(2,2) ) {
00100 S = sqrt( 1.0 + m.element(0,0) - m.element(1,1) - m.element(2,2) ) * 2;
00101 pose.orientation.x = 0.25 * S;
00102 pose.orientation.y = (m.element(0,1) + m.element(1,0) ) / S;
00103 pose.orientation.z = (m.element(2,0) + m.element(0,2) ) / S;
00104 pose.orientation.w = (m.element(1,2) - m.element(2,1) ) / S;
00105 } else if ( m.element(1,1) > m.element(2,2) ) {
00106 S = sqrt( 1.0 + m.element(1,1) - m.element(0,0) - m.element(2,2) ) * 2;
00107 pose.orientation.x = (m.element(0,1) + m.element(1,0) ) / S;
00108 pose.orientation.y = 0.25 * S;
00109 pose.orientation.z = (m.element(1,2) + m.element(2,1) ) / S;
00110 pose.orientation.w = (m.element(2,0) - m.element(0,2) ) / S;
00111 } else {
00112 S = sqrt( 1.0 + m.element(2,2) - m.element(0,0) - m.element(1,1) ) * 2;
00113 pose.orientation.x = (m.element(2,0) + m.element(0,2) ) / S;
00114 pose.orientation.y = (m.element(1,2) + m.element(2,1) ) / S;
00115 pose.orientation.z = 0.25 * S;
00116 pose.orientation.w = (m.element(0,1) - m.element(1,0) ) / S;
00117 }
00118 }
00119
00120 return pose;
00121 }
00122
00123
00124 tabletop_object_detector::Table SegmentPrototypeToTable(SegmentPrototype* cluster, LocatedObjectID_t base_link_id)
00125 {
00149 tabletop_object_detector::Table ret;
00150 ret.pose.header.stamp = ros::Time::now();
00151 ret.pose.header.frame_id = "/base_link";
00152 std::pair<LocatedObjectID_t, sensor_msgs::PointCloud> locpcd = cluster->GetTable();
00153 if(locpcd.first == 0)
00154 {
00155 printf("No table\n");
00156 return ret;
00157 }
00158 RelPose* pose = RelPoseFactory::FRelPose(locpcd.first);
00159 if(pose == NULL)
00160 {
00161 printf("No table \n");
00162 return ret;
00163 }
00164 ret.pose.pose = RelPoseToRosPose(pose, base_link_id);
00165 ret.x_min = 10000000;
00166 ret.y_min = 10000000;
00167 ret.x_max = -10000000;
00168 ret.y_max = -10000000;
00169 for(size_t i = 0; i < locpcd.second.points.size(); i++)
00170 {
00171 if(locpcd.second.points[i].x < ret.x_min)
00172 {
00173 ret.x_min = locpcd.second.points[i].x;
00174 }
00175 if(locpcd.second.points[i].x > ret.x_max)
00176 {
00177 ret.x_max = locpcd.second.points[i].x;
00178 }
00179 if(locpcd.second.points[i].y < ret.y_min)
00180 {
00181 ret.y_min = locpcd.second.points[i].y;
00182 }
00183 if(locpcd.second.points[i].y > ret.y_max)
00184 {
00185 ret.y_max = locpcd.second.points[i].y;
00186 }
00187 }
00188 RelPoseFactory::FreeRelPose(&pose);
00189
00190 return ret;
00191 }
00192
00193 bool CollisionInterface::AddCollisionCB(vision_srvs::cop_add_collision::Request& msg, vision_srvs::cop_add_collision::Response& answer)
00194 {
00195 Signature* sig = m_myCop.s_sigDb->GetSignatureByID(msg.object_id);
00196 if(sig == NULL)
00197 {
00198 ROS_ERROR("Wrong object ID %ld\n", msg.object_id);
00199 return false;
00200 }
00201 std::string collisionname = AddCollisionObject(sig, answer.added_object, true);
00202 if(collisionname.length() > 0)
00203 {
00204 answer.collisionname = collisionname;
00205 return true;
00206 }
00207 return false;
00208 }
00209
00210 bool comparePointX(const PointShape &pt1, const PointShape &pt2)
00211 {
00212 return pt1.x < pt2.x;
00213 }
00214
00215 bool comparePointY(const PointShape &pt1, const PointShape &pt2)
00216 {
00217 return pt1.y < pt2.y;
00218 }
00219
00220 bool comparePointZ(const PointShape &pt1, const PointShape &pt2)
00221 {
00222 return pt1.z < pt2.z;
00223 }
00224
00225 std::string CollisionInterface::AddCollisionObject(Signature* sig, arm_navigation_msgs::CollisionObject &object, bool ignore_pcd)
00226 {
00227 if(sig == NULL)
00228 {
00229 ROS_ERROR("Wrong object ID\n");
00230 return "";
00231 }
00232 ROS_INFO("Got signature with %ld elems", sig->CountElems());
00233 GeometricShape shape;
00234 shape.type = 0;
00235 bool hasShape = false;
00236
00237 for(size_t id = 0; id < sig->CountElems(); id++)
00238 {
00239 Descriptor* elem = (Descriptor*)sig->GetElement (id, ELEM);
00240 printf("Descriptor: %s\n", elem->GetNodeName().c_str());
00241 if(elem->GetShape(shape))
00242 {
00243 if(ignore_pcd && shape.type==4)
00244 {
00245 shape.type = arm_navigation_msgs::Shape::BOX;
00246 shape.dimensions.resize(3);
00247
00248 shape.dimensions[0] =
00249 (std::max_element(shape.vertices.begin(), shape.vertices.end(), &comparePointX)->x
00250 - std::min_element(shape.vertices.begin(), shape.vertices.end(), &comparePointX)->x) * 1.1;
00251 shape.dimensions[1] =
00252 (std::max_element(shape.vertices.begin(), shape.vertices.end(), &comparePointY)->y
00253 - std::min_element(shape.vertices.begin(), shape.vertices.end(), &comparePointY)->y) * 1.1;
00254 shape.dimensions[2] =
00255 (std::max_element(shape.vertices.begin(), shape.vertices.end(), &comparePointZ)->z
00256 - std::min_element(shape.vertices.begin(), shape.vertices.end(), &comparePointZ)->z) * 1.1;
00257
00258 shape.triangles.clear();
00259 shape.vertices.clear();
00260 }
00261 hasShape = true;
00262 printf("has shape\n");
00263 }
00264 else
00265 {
00266 printf("has NO shape (but hasSahpe = %s)\n", hasShape ? "true" : "false");
00267 }
00268 }
00269
00270 arm_navigation_msgs::Shape answer_shape;
00271 if(hasShape)
00272 {
00273 SetShape(answer_shape, shape);
00274 }
00275 else
00276 {
00277 ROS_INFO("No Shape found");
00278 return "";
00279 }
00280
00281 char objectid[90];
00282 sprintf(objectid, "Object%ld", sig->m_ID);
00283 object.id = objectid;
00284 object.operation.operation = arm_navigation_msgs::CollisionObjectOperation::ADD;
00285 object.header.frame_id = "map";
00286 object.header.stamp = ros::Time::now();
00287 if(sig->GetObjectPose() == NULL)
00288 {
00289 ROS_ERROR("Object not localized, can not add it to collision map");
00290 return "";
00291 }
00292 geometry_msgs::Pose pose = RelPoseToRosPose(sig->GetObjectPose(), 1);
00293 object.poses.push_back(pose);
00294 object.shapes.push_back(answer_shape);
00295
00296
00297 m_object_in_map_pub.publish(object);
00298
00299
00300 return objectid;
00301
00302 }
00303
00304 void CollisionInterface::ResetCollisionMap(Signature* current_object)
00305 {
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 }
00415
00416 void SetShape( arm_navigation_msgs::Shape& sout, const GeometricShape& shape)
00417 {
00418 sout.type = shape.type;
00419 size_t i;
00420 for(i = 0; i < shape.dimensions.size(); i++ )
00421 {
00422 sout.dimensions.push_back(shape.dimensions[i]);
00423 }
00424 for(i = 0; i < shape.triangles.size(); i++ )
00425 {
00426 sout.triangles.push_back(shape.triangles[i]);
00427 }
00428 for(i = 0; i < shape.vertices.size(); i++)
00429 {
00430 geometry_msgs::Point p;
00431 p.x = shape.vertices[i].x;
00432 p.y = shape.vertices[i].y;
00433 p.z = shape.vertices[i].z;
00434 sout.vertices.push_back(p);
00435 }
00436
00437 }
00438
00439 bool CollisionInterface::GetGeometricShape(vision_srvs::cop_get_object_shape::Request &msg, vision_srvs::cop_get_object_shape::Response &answer)
00440 {
00441 ROS_INFO("In CollisionInterface::GetGeometricShape");
00442 Signature* sig = m_myCop.s_sigDb->GetSignatureByID(msg.object_id);
00443 if(sig == NULL)
00444 {
00445 ROS_ERROR("Wrong object ID\n");
00446 return false;
00447 }
00448 ROS_INFO("Got signature");
00449 GeometricShape shape;
00450 shape.type = 0;
00451 bool hasShape = false;
00452 for(size_t id = 0; id < sig->CountElems(); id++)
00453 {
00454 Descriptor* elem = (Descriptor*)sig->GetElement (id, ELEM);
00455 if(elem->GetShape(shape))
00456 hasShape = true;
00457 }
00458 if(hasShape)
00459 {
00460 SetShape(answer.shape, shape);
00461 }
00462 else
00463 {
00464 ROS_INFO("No Shape found");
00465 return false;
00466 }
00467 return true;
00468 }