utils.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /***********************************************************************
  2. * Software License Agreement (BSD License)
  3. *
  4. * Copyright 2011-2024 Jose Luis Blanco (joseluisblancoc@gmail.com).
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. *************************************************************************/
  28. #include <cstdlib>
  29. #include <iostream>
  30. #include <vector>
  31. template <typename T>
  32. struct PointCloud
  33. {
  34. struct Point
  35. {
  36. T x, y, z;
  37. };
  38. using coord_t = T; //!< The type of each coordinate
  39. std::vector<Point> pts;
  40. // Must return the number of data points
  41. inline size_t kdtree_get_point_count() const { return pts.size(); }
  42. // Returns the dim'th component of the idx'th point in the class:
  43. // Since this is inlined and the "dim" argument is typically an immediate
  44. // value, the
  45. // "if/else's" are actually solved at compile time.
  46. inline T kdtree_get_pt(const size_t idx, const size_t dim) const
  47. {
  48. if (dim == 0)
  49. return pts[idx].x;
  50. else if (dim == 1)
  51. return pts[idx].y;
  52. else
  53. return pts[idx].z;
  54. }
  55. // Optional bounding-box computation: return false to default to a standard
  56. // bbox computation loop.
  57. // Return true if the BBOX was already computed by the class and returned
  58. // in "bb" so it can be avoided to redo it again. Look at bb.size() to
  59. // find out the expected dimensionality (e.g. 2 or 3 for point clouds)
  60. template <class BBOX>
  61. bool kdtree_get_bbox(BBOX& /* bb */) const
  62. {
  63. return false;
  64. }
  65. };
  66. template <typename T>
  67. void generateRandomPointCloudRanges(
  68. PointCloud<T>& pc, const size_t N, const T max_range_x, const T max_range_y,
  69. const T max_range_z)
  70. {
  71. // Generating Random Point Cloud
  72. pc.pts.resize(N);
  73. for (size_t i = 0; i < N; i++)
  74. {
  75. pc.pts[i].x = max_range_x * (rand() % 1000) / T(1000);
  76. pc.pts[i].y = max_range_y * (rand() % 1000) / T(1000);
  77. pc.pts[i].z = max_range_z * (rand() % 1000) / T(1000);
  78. }
  79. }
  80. template <typename T>
  81. void generateRandomPointCloud(
  82. PointCloud<T>& pc, const size_t N, const T max_range = 10)
  83. {
  84. generateRandomPointCloudRanges(pc, N, max_range, max_range, max_range);
  85. }
  86. // This is an exampleof a custom data set class
  87. template <typename T>
  88. struct PointCloud_Quat
  89. {
  90. struct Point
  91. {
  92. T w, x, y, z;
  93. };
  94. std::vector<Point> pts;
  95. // Must return the number of data points
  96. inline size_t kdtree_get_point_count() const { return pts.size(); }
  97. // Returns the dim'th component of the idx'th point in the class:
  98. // Since this is inlined and the "dim" argument is typically an immediate
  99. // value, the
  100. // "if/else's" are actually solved at compile time.
  101. inline T kdtree_get_pt(const size_t idx, const size_t dim) const
  102. {
  103. if (dim == 0)
  104. return pts[idx].w;
  105. else if (dim == 1)
  106. return pts[idx].x;
  107. else if (dim == 2)
  108. return pts[idx].y;
  109. else
  110. return pts[idx].z;
  111. }
  112. // Optional bounding-box computation: return false to default to a standard
  113. // bbox computation loop.
  114. // Return true if the BBOX was already computed by the class and returned
  115. // in "bb" so it can be avoided to redo it again. Look at bb.size() to
  116. // find out the expected dimensionality (e.g. 2 or 3 for point clouds)
  117. template <class BBOX>
  118. bool kdtree_get_bbox(BBOX& /* bb */) const
  119. {
  120. return false;
  121. }
  122. };
  123. template <typename T>
  124. void generateRandomPointCloud_Quat(PointCloud_Quat<T>& point, const size_t N)
  125. {
  126. // Generating Random Quaternions
  127. point.pts.resize(N);
  128. T theta, X, Y, Z, sinAng, cosAng, mag;
  129. for (size_t i = 0; i < N; i++)
  130. {
  131. theta = static_cast<T>(
  132. nanoflann::pi_const<double>() * (((double)rand()) / RAND_MAX));
  133. // Generate random value in [-1, 1]
  134. X = static_cast<T>(2 * (((double)rand()) / RAND_MAX) - 1);
  135. Y = static_cast<T>(2 * (((double)rand()) / RAND_MAX) - 1);
  136. Z = static_cast<T>(2 * (((double)rand()) / RAND_MAX) - 1);
  137. mag = sqrt(X * X + Y * Y + Z * Z);
  138. X /= mag;
  139. Y /= mag;
  140. Z /= mag;
  141. cosAng = cos(theta / 2);
  142. sinAng = sin(theta / 2);
  143. point.pts[i].w = cosAng;
  144. point.pts[i].x = X * sinAng;
  145. point.pts[i].y = Y * sinAng;
  146. point.pts[i].z = Z * sinAng;
  147. }
  148. }
  149. // This is an exampleof a custom data set class
  150. template <typename T>
  151. struct PointCloud_Orient
  152. {
  153. struct Point
  154. {
  155. T theta;
  156. };
  157. std::vector<Point> pts;
  158. // Must return the number of data points
  159. inline size_t kdtree_get_point_count() const { return pts.size(); }
  160. // Returns the dim'th component of the idx'th point in the class:
  161. // Since this is inlined and the "dim" argument is typically an immediate
  162. // value, the
  163. // "if/else's" are actually solved at compile time.
  164. inline T kdtree_get_pt(const size_t idx, const size_t dim = 0) const
  165. {
  166. return pts[idx].theta;
  167. }
  168. // Optional bounding-box computation: return false to default to a standard
  169. // bbox computation loop.
  170. // Return true if the BBOX was already computed by the class and returned
  171. // in "bb" so it can be avoided to redo it again. Look at bb.size() to
  172. // find out the expected dimensionality (e.g. 2 or 3 for point clouds)
  173. template <class BBOX>
  174. bool kdtree_get_bbox(BBOX& /* bb */) const
  175. {
  176. return false;
  177. }
  178. };
  179. template <typename T>
  180. void generateRandomPointCloud_Orient(
  181. PointCloud_Orient<T>& point, const size_t N)
  182. {
  183. // Generating Random Orientations
  184. point.pts.resize(N);
  185. for (size_t i = 0; i < N; i++)
  186. {
  187. point.pts[i].theta = static_cast<T>(
  188. (2 * nanoflann::pi_const<double>() *
  189. (((double)rand()) / RAND_MAX)) -
  190. nanoflann::pi_const<double>());
  191. }
  192. }
  193. inline void dump_mem_usage()
  194. {
  195. FILE* f = fopen("/proc/self/statm", "rt");
  196. if (!f) return;
  197. char str[300];
  198. size_t n = fread(str, 1, 200, f);
  199. str[n] = 0;
  200. printf("MEM: %s\n", str);
  201. fclose(f);
  202. }