CollisionInterface.cpp
Go to the documentation of this file.
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   /* If the trace of the matrix is greater than zero, then
00082   perform an "instant" calculation.
00083   Important note wrt. rouning errors: */
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     /*If the trace of the matrix is equal to zero then identify
00096     which major diagonal element has the greatest value.
00097     Deending on this, calculate the following:*/
00098 
00099     if ( m.element(0,0) > m.element(1,1) && m.element(0,0) > m.element(2,2) )  {        // Column 0:
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) ) {                     // Column 1:
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 {                                            // Column 2:
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 Filling this service:
00308 
00309 [tabletop_collision_map_processing/TabletopCollisionMapProcessing]:
00310 tabletop_object_detector/TabletopDetectionResult detection_result
00311   int32 NO_CLOUD_RECEIVED=1
00312   int32 NO_TABLE=2
00313   int32 OTHER_ERROR=3
00314   int32 SUCCESS=4
00315   tabletop_object_detector/Table table
00316     geometry_msgs/PoseStamped pose
00317       Header header
00318         uint32 seq
00319         time stamp
00320         string frame_id
00321       geometry_msgs/Pose pose
00322         geometry_msgs/Point position
00323           float64 x
00324           float64 y
00325           float64 z
00326         geometry_msgs/Quaternion orientation
00327           float64 x
00328           float64 y
00329           float64 z
00330           float64 w
00331     float32 x_min
00332     float32 x_max
00333     float32 y_min
00334     float32 y_max
00335   sensor_msgs/PointCloud[] clusters
00336     Header header
00337       uint32 seq
00338       time stamp
00339       string frame_id
00340     geometry_msgs/Point32[] points
00341       float32 x
00342       float32 y
00343       float32 z
00344     sensor_msgs/ChannelFloat32[] channels
00345       string name
00346       float32[] values
00347   household_objects_database_msgs/DatabaseModelPose[] models
00348     int32 model_id
00349     geometry_msgs/PoseStamped pose
00350       Header header
00351         uint32 seq
00352         time stamp
00353         string frame_id
00354        geometry_msgs/Pose pose
00355         geometry_msgs/Point position
00356           float64 x
00357           float64 y
00358           float64 z
00359         geometry_msgs/Quaternion orientation
00360           float64 x
00361           float64 y
00362           float64 z
00363           float64 w
00364   int32[] cluster_model_indices
00365   int32 result
00366 
00367 bool reset_collision_models
00368 bool reset_attached_models
00369 bool reset_static_map
00370 bool take_static_collision_map
00371 string desired_frame
00372 
00373 */
00374 /*  SegmentPrototype* cluster = (SegmentPrototype*)(current_object->GetElement(0, DESCRIPTOR_SEGMPROTO));
00375   if(cluster == NULL)
00376   {
00377     // TODO check for shapemodels?
00378     return;
00379   }
00380 
00381   tabletop_collision_map_processing::TabletopCollisionMapProcessing processing_srv;
00382 
00383   processing_srv.request.detection_result.result = 4; // = SUCCESS
00384   processing_srv.request.detection_result.table = SegmentPrototypeToTable(cluster, m_base_link_id);
00385   if(current_object->GetObjectPose() != NULL)
00386   {
00387     processing_srv.request.detection_result.clusters.push_back(cluster->GetPointCloud(current_object->GetObjectPose()->m_uniqueID));
00388     household_objects_database_msgs::DatabaseModelPose model_pose;
00389     model_pose.pose.pose = RelPoseToRosPose(current_object->GetObjectPose(), m_base_link_id);
00390     model_pose.pose.header.stamp = ros::Time::now();
00391     model_pose.pose.header.frame_id = "/base_link"; //TODO fix this... id is known, must be retranslated to f** tf
00392     processing_srv.request.detection_result.models.push_back(model_pose);
00393     processing_srv.request.detection_result.cluster_model_indices.push_back(0);
00394   }
00395   else
00396   {
00397     ROS_ERROR("Trying to add a non-located object to the collision\n");
00398     return;
00399   }
00400 
00401 
00402   processing_srv.request.reset_collision_models = true;
00403   processing_srv.request.reset_attached_models = true;
00404   processing_srv.request.reset_static_map = true;
00405   processing_srv.request.take_static_collision_map = true;
00406   processing_srv.request.desired_frame = "base_link";
00407   if (!m_collision_processing_srv.call(processing_srv))
00408   {
00409     ROS_ERROR("Collision map processing service failed");
00410     return;
00411   }
00412   std::cout << "Detected " << processing_srv.response.graspable_objects.size() << " graspable object(s):\n";
00413   printObjects(objects_info_.graspable_objects, objects_info_.collision_object_names);*/
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends Defines


cop_collision_interface
Author(s): Ulrich Friedrich Klank
autogenerated on Thu May 23 2013 15:25:32