point.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008 Radu Bogdan Rusu <rusu -=- cs.tum.edu>
00003  *
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  *     * Redistributions of source code must retain the above copyright
00010  *       notice, this list of conditions and the following disclaimer.
00011  *     * Redistributions in binary form must reproduce the above copyright
00012  *       notice, this list of conditions and the following disclaimer in the
00013  *       documentation and/or other materials provided with the distribution.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00025  * POSSIBILITY OF SUCH DAMAGE.
00026  *
00027  * $Id$
00028  *
00029  */
00030 
00033 #ifndef _CLOUD_GEOMETRY_POINT_H_
00034 #define _CLOUD_GEOMETRY_POINT_H_
00035 
00036 // ROS includes
00037 #include <sensor_msgs/PointCloud.h>
00038 #include <geometry_msgs/Polygon.h>
00039 #include <geometry_msgs/Point32.h>
00040 #include <geometry_msgs/Point.h>
00041 #include <geometry_msgs/Vector3.h>
00042 
00043 #include <Eigen/Core>
00044 
00045 #include <cfloat>
00046 
00047 namespace cloud_geometry
00048 {
00049 
00051   struct Leaf
00052   {
00053     float centroid_x, centroid_y, centroid_z;
00054     unsigned short nr_points;
00055   };
00056 
00057 
00059 
00064   inline bool
00065     checkPointEqual (const geometry_msgs::Point32 &p1, const geometry_msgs::Point32 &p2, double eps = 1e-10)
00066   {
00067     if (
00068         (fabs (p1.x - p2.x) < eps) && (fabs (p1.y - p2.y) < eps) && (fabs (p1.z - p2.z) < eps)
00069         )
00070       return (true);
00071     return (false);
00072   }
00073 
00074   int getChannelIndex (const sensor_msgs::PointCloud &points, std::string channel_name);
00075   int getChannelIndex (sensor_msgs::PointCloudConstPtr points, std::string channel_name);
00076 
00078 
00083   inline void
00084     getPointAsFloatArray (const sensor_msgs::PointCloud &points, int index, std::vector<float> &array)
00085   {
00086     // Resize for XYZ (3) + NR_CHANNELS
00087     if (array.size () != 3 + points.channels.size ())
00088       array.resize (3 + points.channels.size ());
00089     array[0] = points.points[index].x;
00090     array[1] = points.points[index].y;
00091     array[2] = points.points[index].z;
00092 
00093     for (unsigned int d = 0; d < points.channels.size (); d++)
00094       array[3 + d] = points.channels[d].values[index];
00095   }
00096 
00098 
00104   inline void
00105     getPointAsFloatArray (const sensor_msgs::PointCloud &points, int index, std::vector<float> &array, int nr_channels)
00106   {
00107     // Resize for XYZ (3) + NR_CHANNELS
00108     if ((int)array.size () != 3 + nr_channels)
00109       array.resize (3 + nr_channels);
00110     array[0] = points.points[index].x;
00111     array[1] = points.points[index].y;
00112     array[2] = points.points[index].z;
00113 
00114     for (int d = 0; d < nr_channels; d++)
00115       array[3 + d] = points.channels[d].values[index];
00116   }
00117 
00119 
00126   inline void
00127     getPointAsFloatArray (const sensor_msgs::PointCloud &points, int index, std::vector<float> &array, int start_channel, int end_channel)
00128   {
00129     // Resize for XYZ (3) + NR_CHANNELS
00130     if ((int)array.size () != 3 + end_channel - start_channel)
00131       array.resize (3 + end_channel - start_channel);
00132     array[0] = points.points[index].x;
00133     array[1] = points.points[index].y;
00134     array[2] = points.points[index].z;
00135 
00136     for (int d = start_channel; d < end_channel; d++)
00137       array[3 + d - start_channel] = points.channels[d].values[index];
00138   }
00139 
00141 
00148   inline void
00149     getPointAsFloatArray (const sensor_msgs::PointCloud &points, int index, std::vector<float> &array, std::vector<int> channels)
00150   {
00151     if (channels.size () > points.channels.size ())
00152       return;
00153     // Resize for XYZ (3) + NR_CHANNELS
00154     if (array.size () != 3 + channels.size ())
00155       array.resize (3 + channels.size ());
00156     array[0] = points.points[index].x;
00157     array[1] = points.points[index].y;
00158     array[2] = points.points[index].z;
00159 
00160     for (unsigned int d = 0; d < channels.size (); d++)
00161       array[3 + d] = points.channels[channels.at (d)].values[index];
00162   }
00163 
00165 
00169   inline geometry_msgs::Point32
00170     cross (const geometry_msgs::Point32 &p1, const geometry_msgs::Point32 &p2)
00171   {
00172     geometry_msgs::Point32 r;
00173     r.x = p1.y * p2.z - p1.z * p2.y;
00174     r.y = p1.z * p2.x - p1.x * p2.z;
00175     r.z = p1.x * p2.y - p1.y * p2.x;
00176     return (r);
00177   }
00178 
00180 
00184   inline geometry_msgs::Point32
00185     cross (const std::vector<double> &p1, const geometry_msgs::Point32 &p2)
00186   {
00187     geometry_msgs::Point32 r;
00188     r.x = p1.at (1) * p2.z - p1.at (2) * p2.y;
00189     r.y = p1.at (2) * p2.x - p1.at (0) * p2.z;
00190     r.z = p1.at (0) * p2.y - p1.at (1) * p2.x;
00191     return (r);
00192   }
00193 
00195 
00199   inline geometry_msgs::Point32
00200     cross (const geometry_msgs::Point32 &p1, const std::vector<double> &p2)
00201   {
00202     geometry_msgs::Point32 r;
00203     r.x = p2.at (1) * p1.z - p2.at (2) * p1.y;
00204     r.y = p2.at (2) * p1.x - p2.at (0) * p1.z;
00205     r.z = p2.at (0) * p1.y - p2.at (1) * p1.x;
00206     return (r);
00207   }
00208 
00210 
00215   inline void
00216     cross (const std::vector<double> &p1, const std::vector<double> &p2, std::vector<double> &p3)
00217   {
00218     if (p3.size () != 3)
00219       p3.resize (3);
00220     p3[0] = p1.at (1) * p2.at (2) - p1.at (2) * p2.at (1);
00221     p3[1] = p1.at (2) * p2.at (0) - p1.at (0) * p2.at (2);
00222     p3[2] = p1.at (0) * p2.at (1) - p1.at (1) * p2.at (0);
00223   }
00224 
00226 
00230   inline double
00231     dot (const geometry_msgs::Point32 &p1, const geometry_msgs::Point32 &p2)
00232   {
00233     return (p1.x * p2.x + p1.y * p2.y + p1.z * p2.z);
00234   }
00235 
00237 
00241   inline double
00242     dot (const geometry_msgs::Point &p1, const geometry_msgs::Point &p2)
00243   {
00244     return (p1.x * p2.x + p1.y * p2.y + p1.z * p2.z);
00245   }
00246 
00248 
00252   inline double
00253     dot (const geometry_msgs::Point32 &p1, const geometry_msgs::Point &p2)
00254   {
00255     return (p1.x * p2.x + p1.y * p2.y + p1.z * p2.z);
00256   }
00257 
00259 
00263   inline double
00264     dot (const geometry_msgs::Point &p1, const geometry_msgs::Point32 &p2)
00265   {
00266     return (p1.x * p2.x + p1.y * p2.y + p1.z * p2.z);
00267   }
00268 
00270 
00274   inline double
00275     dot (const geometry_msgs::Point32 &p1, const geometry_msgs::Vector3 &p2)
00276   {
00277     return (p1.x * p2.x + p1.y * p2.y + p1.z * p2.z);
00278   }
00279 
00281 
00285   inline double
00286     dot (const geometry_msgs::Vector3 &p1, const geometry_msgs::Point32 &p2)
00287   {
00288     return (p1.x * p2.x + p1.y * p2.y + p1.z * p2.z);
00289   }
00290 
00292 
00296   inline double
00297     dot (const geometry_msgs::Vector3 &p1, const geometry_msgs::Vector3 &p2)
00298   {
00299     return (p1.x * p2.x + p1.y * p2.y + p1.z * p2.z);
00300   }
00301 
00303 
00307   inline double
00308     dot (const std::vector<double> &p1, const std::vector<double> &p2)
00309   {
00310     return (p1.at (0) * p2.at (0) + p1.at (1) * p2.at (1) + p1.at (2) * p2.at (2));
00311   }
00312 
00314 
00318   inline void
00319     normalizePoint (const geometry_msgs::Point32 &p, geometry_msgs::Point32 &q)
00320   {
00321     // Calculate the 2-norm: norm (x) = sqrt (sum (abs (v)^2))
00322     double n_norm = sqrt (p.x * p.x + p.y * p.y + p.z * p.z);
00323     q.x = p.x / n_norm;
00324     q.y = p.y / n_norm;
00325     q.z = p.z / n_norm;
00326   }
00327 
00329 
00332   inline void
00333     normalizePoint (geometry_msgs::Point32 &p)
00334   {
00335     normalizePoint (p, p);
00336   }
00337 
00338   void getPointIndicesAxisParallelNormals (const sensor_msgs::PointCloud &points, int nx, int ny, int nz, double eps_angle,
00339                                            const geometry_msgs::Point32 &axis, std::vector<int> &indices);
00340   void getPointIndicesAxisPerpendicularNormals (const sensor_msgs::PointCloud &points, int nx, int ny, int nz, double eps_angle,
00341                                                 const geometry_msgs::Point32 &axis, std::vector<int> &indices);
00342 
00343   void downsamplePointCloud (const sensor_msgs::PointCloud &points, const std::vector<int> &indices, sensor_msgs::PointCloud &points_down, geometry_msgs::Point leaf_size,
00344                              std::vector<Leaf> &leaves, int d_idx, double cut_distance = DBL_MAX);
00345 
00346   void downsamplePointCloud (const sensor_msgs::PointCloud &points, sensor_msgs::PointCloud &points_down, geometry_msgs::Point leaf_size,
00347                              std::vector<Leaf> &leaves, int d_idx, double cut_distance = DBL_MAX);
00348 
00349   void downsamplePointCloud (sensor_msgs::PointCloudConstPtr points, sensor_msgs::PointCloud &points_down, geometry_msgs::Point leaf_size,
00350                              std::vector<Leaf> &leaves, int d_idx, double cut_distance = DBL_MAX);
00351 
00352   void downsamplePointCloud (const sensor_msgs::PointCloud &points, sensor_msgs::PointCloud &points_down, geometry_msgs::Point leaf_size);
00353 
00355 
00360   inline void
00361     getCoordinateSystemOnPlane (const std::vector<double> &plane_coeff, Eigen::Vector3d &u, Eigen::Vector3d &v)
00362   {
00363     // Initialize normalized u vector with "random" values not parallel with normal
00364     u (1) = 0;
00365     if (fabs (plane_coeff.at (0)) != 1)
00366     {
00367       u (0) = 1;
00368       u (2) = 0;
00369     }
00370     else
00371     {
00372       u (0) = 0;
00373       u (2) = 1;
00374     }
00375 
00376     // Compute the v vector and normalize it
00377     v (0) = plane_coeff.at (1) * u (2) - plane_coeff.at (2) * u (1);
00378     v (1) = plane_coeff.at (2) * u (0) - plane_coeff.at (0) * u (2);
00379     v (2) = plane_coeff.at (0) * u (1) - plane_coeff.at (1) * u (0);
00380     double v_length = sqrt (v (0) * v (0) + v (1) * v (1) + v (2) * v (2));
00381     v (0) /= v_length;
00382     v (1) /= v_length;
00383     v (2) /= v_length;
00384 
00385     // Recompute u and normalize it
00386     u (0) = v (1) * plane_coeff.at (2) - v (2) * plane_coeff.at (1);
00387     u (1) = v (2) * plane_coeff.at (0) - v (0) * plane_coeff.at (2);
00388     u (2) = v (0) * plane_coeff.at (1) - v (1) * plane_coeff.at (0);
00389     double u_length = sqrt (u (0) * u (0) + u (1) * u (1) + u (2) * u (2));
00390     u (0) /= u_length;
00391     u (1) /= u_length;
00392     u (2) /= u_length;
00393   }
00394 
00395   std::string getAvailableChannels (const sensor_msgs::PointCloud &cloud);
00396   std::string getAvailableChannels (const sensor_msgs::PointCloudConstPtr& cloud);
00397 
00398   void getPointCloud (const sensor_msgs::PointCloud &input, const std::vector<int> &indices, sensor_msgs::PointCloud &output);
00399   void getPointCloudOutside (const sensor_msgs::PointCloud &input, std::vector<int> indices, sensor_msgs::PointCloud &output);
00400 
00402 
00405   inline void
00406     cerr_p (const geometry_msgs::Point32 &p)
00407   {
00408     std::cerr << p.x << " " << p.y << " " << p.z << std::endl;
00409   }
00410   inline void
00411     cerr_p (const std::vector<double> &p)
00412   {
00413     for (unsigned int i = 0; i < p.size () - 1; i++)
00414       std::cerr << p[i] << " ";
00415     std::cerr << p[p.size () - 1] << std::endl;
00416   }
00417 
00419 
00422   inline void
00423     cerr_poly (const geometry_msgs::Polygon &poly)
00424   {
00425     for (unsigned int i = 0; i < poly.points.size (); i++)
00426     {
00427       std::cerr << poly.points[i].x << " " << poly.points[i].y << " " << poly.points[i].z << std::endl;
00428     }
00429   }
00430 
00431 }
00432 
00433 #endif


door_handle_detector
Author(s): Radu Bogdan Rusu, Marius
autogenerated on Wed Dec 11 2013 14:17:01