test/octree.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2019, CNRS-LAAS.
5  * Copyright (c) 2023, INRIA.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of Willow Garage, Inc. nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
38 #define BOOST_TEST_MODULE COAL_OCTREE
39 #include <fstream>
40 #include <boost/test/included/unit_test.hpp>
41 #include <boost/filesystem.hpp>
42 
43 #include "coal/BVH/BVH_model.h"
44 #include "coal/collision.h"
45 #include "coal/distance.h"
46 #include "coal/hfield.h"
50 
51 #include "utility.h"
52 #include "fcl_resources/config.h"
53 
54 namespace utf = boost::unit_test::framework;
55 
56 using namespace coal;
57 
58 void makeMesh(const std::vector<Vec3s>& vertices,
59  const std::vector<Triangle>& triangles, BVHModel<OBBRSS>& model) {
61  model.bv_splitter.reset(new BVSplitter<OBBRSS>(split_method));
62  model.bv_splitter.reset(new BVSplitter<OBBRSS>(split_method));
63 
64  model.beginModel();
65  model.addSubModel(vertices, triangles);
66  model.endModel();
67 }
68 
70  const CoalScalar& resolution) {
71  Vec3s m(mesh.aabb_local.min_);
72  Vec3s M(mesh.aabb_local.max_);
73  coal::Box box(resolution, resolution, resolution);
75  CollisionResult result;
76  Transform3s tfBox;
77  octomap::OcTreePtr_t octree(new octomap::OcTree(resolution));
78 
79  for (CoalScalar x = resolution * floor(m[0] / resolution); x <= M[0];
80  x += resolution) {
81  for (CoalScalar y = resolution * floor(m[1] / resolution); y <= M[1];
82  y += resolution) {
83  for (CoalScalar z = resolution * floor(m[2] / resolution); z <= M[2];
84  z += resolution) {
85  Vec3s center(x + .5 * resolution, y + .5 * resolution,
86  z + .5 * resolution);
87  tfBox.setTranslation(center);
88  coal::collide(&box, tfBox, &mesh, Transform3s(), request, result);
89  if (result.isCollision()) {
90  octomap::point3d p((float)center[0], (float)center[1],
91  (float)center[2]);
92  octree->updateNode(p, true);
93  result.clear();
94  }
95  }
96  }
97  }
98 
99  octree->updateInnerOccupancy();
100  octree->writeBinary("./env.octree");
101  return OcTree(octree);
102 }
103 
104 BOOST_AUTO_TEST_CASE(octree_mesh) {
105  Eigen::IOFormat tuple(Eigen::FullPrecision, Eigen::DontAlignCols, "", ", ",
106  "", "", "(", ")");
107  CoalScalar resolution(10.);
108  std::vector<Vec3s> pRob, pEnv;
109  std::vector<Triangle> tRob, tEnv;
110  boost::filesystem::path path(TEST_RESOURCES_DIR);
111  loadOBJFile((path / "rob.obj").string().c_str(), pRob, tRob);
112  loadOBJFile((path / "env.obj").string().c_str(), pEnv, tEnv);
113 
114  BVHModel<OBBRSS> robMesh, envMesh;
115  // Build meshes with robot and environment
116  makeMesh(pRob, tRob, robMesh);
117  makeMesh(pEnv, tEnv, envMesh);
118  // Build octomap with environment
119  envMesh.computeLocalAABB();
120  // Load octree built from envMesh by makeOctree(envMesh, resolution)
121  OcTree envOctree(
122  coal::loadOctreeFile((path / "env.octree").string(), resolution));
123 
124  std::cout << "Finished loading octree." << std::endl;
125 
126  // Test operator==
127  {
128  BOOST_CHECK(envOctree == envOctree);
129  BOOST_CHECK(envOctree == OcTree(envOctree));
130 
131  const OcTree envOctree_from_tree(envOctree.getTree());
132  BOOST_CHECK(envOctree == envOctree_from_tree);
133  }
134 
135  // Test tobytes()
136  {
137  const std::vector<uint8_t> bytes = envOctree.tobytes();
138  BOOST_CHECK(bytes.size() > 0 && bytes.size() <= envOctree.toBoxes().size() *
139  3 * sizeof(CoalScalar));
140  }
141 
142  std::vector<Transform3s> transforms;
143  CoalScalar extents[] = {-2000, -2000, 0, 2000, 2000, 2000};
144 #ifndef NDEBUG // if debug mode
145  std::size_t N = 100;
146 #else
147  std::size_t N = 10000;
148 #endif
149  N = coal::getNbRun(utf::master_test_suite().argc,
150  utf::master_test_suite().argv, N);
151 
152  generateRandomTransforms(extents, transforms, 2 * N);
153 
155  for (std::size_t i = 0; i < N; ++i) {
156  CollisionResult resultMesh;
157  CollisionResult resultOctree;
158  Transform3s tf1(transforms[2 * i]);
159  Transform3s tf2(transforms[2 * i + 1]);
160  ;
161  // Test collision between meshes with random transform for robot.
162  coal::collide(&robMesh, tf1, &envMesh, tf2, request, resultMesh);
163  // Test collision between mesh and octree for the same transform.
164  coal::collide(&robMesh, tf1, &envOctree, tf2, request, resultOctree);
165  bool resMesh(resultMesh.isCollision());
166  bool resOctree(resultOctree.isCollision());
167  BOOST_CHECK(!resMesh || resOctree);
168  if (!resMesh && resOctree) {
171  coal::distance(&robMesh, tf1, &envMesh, tf2, dreq, dres);
172  std::cout << "distance mesh mesh: " << dres.min_distance << std::endl;
173  BOOST_CHECK(dres.min_distance < sqrt(2.) * resolution);
174  }
175  }
176 }
177 
178 BOOST_AUTO_TEST_CASE(octree_height_field) {
179  Eigen::IOFormat tuple(Eigen::FullPrecision, Eigen::DontAlignCols, "", ", ",
180  "", "", "(", ")");
181  CoalScalar resolution(10.);
182  std::vector<Vec3s> pEnv;
183  std::vector<Triangle> tEnv;
184  boost::filesystem::path path(TEST_RESOURCES_DIR);
185  loadOBJFile((path / "env.obj").string().c_str(), pEnv, tEnv);
186 
187  BVHModel<OBBRSS> envMesh;
188  // Build meshes with robot and environment
189  makeMesh(pEnv, tEnv, envMesh);
190  // Build octomap with environment
191  envMesh.computeLocalAABB();
192  // Load octree built from envMesh by makeOctree(envMesh, resolution)
193  OcTree envOctree(
194  coal::loadOctreeFile((path / "env.octree").string(), resolution));
195 
196  std::cout << "Finished loading octree." << std::endl;
197 
198  // Building hfield
199  const CoalScalar x_dim = 10, y_dim = 20;
200  const int nx = 100, ny = 100;
201  const CoalScalar max_altitude = 1., min_altitude = 0.;
202  const MatrixXs heights = MatrixXs::Constant(ny, nx, max_altitude);
203 
204  HeightField<AABB> hfield(x_dim, y_dim, heights, min_altitude);
205  hfield.computeLocalAABB();
206 
207  std::vector<Transform3s> transforms;
208  CoalScalar extents[] = {-2000, -2000, 0, 2000, 2000, 2000};
209 #ifndef NDEBUG // if debug mode
210  std::size_t N = 1000;
211 #else
212  std::size_t N = 100000;
213 #endif
214  N = coal::getNbRun(utf::master_test_suite().argc,
215  utf::master_test_suite().argv, N);
216 
217  generateRandomTransforms(extents, transforms, 2 * N);
218 
220  for (std::size_t i = 0; i < N; ++i) {
221  CollisionResult resultBox;
222  CollisionResult resultHfield1, resultHfield2;
223  Transform3s tf1(transforms[2 * i]);
224  Transform3s tf2(transforms[2 * i + 1]);
225 
226  Box box;
227  Transform3s box_tf;
228  constructBox(hfield.aabb_local, tf2, box, box_tf);
229 
230  // Test collision between octree and equivalent box.
231  coal::collide(&envOctree, tf1, &box, box_tf, request, resultBox);
232  // Test collision between octree and hfield.
233  coal::collide(&envOctree, tf1, &hfield, tf2, request, resultHfield1);
234  coal::collide(&hfield, tf2, &envOctree, tf1, request, resultHfield2);
235 
236  bool resBox(resultBox.isCollision());
237  bool resHfield(resultHfield1.isCollision());
238  BOOST_CHECK(resBox == resHfield);
239  BOOST_CHECK(resultHfield1.isCollision() == resultHfield2.isCollision());
240  if (!resBox && resHfield) {
243  coal::distance(&envMesh, tf1, &box, box_tf, dreq, dres);
244  std::cout << "distance mesh box: " << dres.min_distance << std::endl;
245  BOOST_CHECK(dres.min_distance < sqrt(2.) * resolution);
246  }
247  }
248 }
generate_distance_plot.m
float m
Definition: generate_distance_plot.py:6
collision.h
coal::BVHModelBase::beginModel
int beginModel(unsigned int num_tris=0, unsigned int num_vertices=0)
Begin a new BVH model.
Definition: BVH_model.cpp:179
coal::CONTACT
@ CONTACT
Definition: coal/collision_data.h:305
coal::OcTree::toBoxes
std::vector< Vec6s > toBoxes() const
transform the octree into a bunch of boxes; uncertainty information is kept in the boxes....
Definition: coal/octree.h:178
coal::Vec3s
Eigen::Matrix< CoalScalar, 3, 1 > Vec3s
Definition: coal/data_types.h:77
collision_manager.box
box
Definition: collision_manager.py:11
coal::SplitMethodType
SplitMethodType
Three types of split algorithms are provided in FCL as default.
Definition: coal/internal/BV_splitter.h:50
coal::BVHModelBase::endModel
int endModel()
End BVH model construction, will build the bounding volume hierarchy.
Definition: BVH_model.cpp:507
makeMesh
void makeMesh(const std::vector< Vec3s > &vertices, const std::vector< Triangle > &triangles, BVHModel< OBBRSS > &model)
Definition: test/octree.cpp:58
coal::CollisionResult::isCollision
bool isCollision() const
return binary collision result
Definition: coal/collision_data.h:443
y
y
gjk.tf1
tuple tf1
Definition: test/scripts/gjk.py:27
coal
Main namespace.
Definition: coal/broadphase/broadphase_bruteforce.h:44
utility.h
coal::OcTree::tobytes
std::vector< uint8_t > tobytes() const
Returns a byte description of *this.
Definition: coal/octree.h:203
octree
Definition: octree.py:1
coal::makeOctree
COAL_DLLAPI OcTreePtr_t makeOctree(const Eigen::Matrix< CoalScalar, Eigen::Dynamic, 3 > &point_cloud, const CoalScalar resolution)
Build an OcTree from a point cloud and a given resolution.
Definition: src/octree.cpp:188
coal::distance
COAL_DLLAPI CoalScalar distance(const Matrix3s &R0, const Vec3s &T0, const kIOS &b1, const kIOS &b2, Vec3s *P=NULL, Vec3s *Q=NULL)
Approximate distance between two kIOS bounding volumes.
Definition: kIOS.cpp:180
coal::BVSplitter
A class describing the split rule that splits each BV node.
Definition: coal/BVH/BVH_model.h:61
coal::BVHModelBase::addSubModel
int addSubModel(const std::vector< Vec3s > &ps, const std::vector< Triangle > &ts)
Add a set of triangles in the new BVH model.
Definition: BVH_model.cpp:439
coal::HeightField::computeLocalAABB
void computeLocalAABB()
Compute the AABB for the HeightField, used for broad-phase collision.
Definition: coal/hfield.h:278
coal::SPLIT_METHOD_MEAN
@ SPLIT_METHOD_MEAN
Definition: coal/internal/BV_splitter.h:51
coal::Box
Center at zero point, axis aligned box.
Definition: coal/shape/geometric_shapes.h:166
coal::DISTANCE_LOWER_BOUND
@ DISTANCE_LOWER_BOUND
Definition: coal/collision_data.h:306
coal::Transform3s
Simple transform class used locally by InterpMotion.
Definition: coal/math/transform.h:55
coal::AABB::max_
Vec3s max_
The max point in the AABB.
Definition: coal/BV/AABB.h:60
coal::Transform3s::setTranslation
void setTranslation(const Eigen::MatrixBase< Derived > &T_)
set transform from translation
Definition: coal/math/transform.h:143
coal::constructBox
COAL_DLLAPI void constructBox(const AABB &bv, Box &box, Transform3s &tf)
construct a box shape (with a configuration) from a given bounding volume
Definition: geometric_shapes_utility.cpp:1011
coal::DistanceResult::min_distance
CoalScalar min_distance
minimum distance between two objects. If two objects are in collision and DistanceRequest::enable_sig...
Definition: coal/collision_data.h:1058
BVH_model.h
coal::DistanceRequest
request to the distance computation
Definition: coal/collision_data.h:985
coal::CollisionResult::clear
void clear()
clear the results obtained
Definition: coal/collision_data.h:483
coal::CollisionGeometry::aabb_local
AABB aabb_local
AABB in local coordinate, used for tight AABB when only translation transform.
Definition: coal/collision_object.h:158
coal::CollisionResult
collision result
Definition: coal/collision_data.h:390
coal::CollisionRequest
request to the collision algorithm
Definition: coal/collision_data.h:311
x
x
distance.h
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(octree_mesh)
Definition: test/octree.cpp:104
coal::DistanceResult
distance result
Definition: coal/collision_data.h:1051
gjk.tf2
tuple tf2
Definition: test/scripts/gjk.py:36
M
M
coal::BVHModelBase::computeLocalAABB
void computeLocalAABB()
Compute the AABB for the BVH, used for broad-phase collision.
Definition: BVH_model.cpp:781
coal::BVHModel::bv_splitter
shared_ptr< BVSplitter< BV > > bv_splitter
Split rule to split one BV node into two children.
Definition: coal/BVH/BVH_model.h:322
collision.path
path
Definition: scripts/collision.py:6
coal::generateRandomTransforms
void generateRandomTransforms(CoalScalar extents[6], std::vector< Transform3s > &transforms, std::size_t n)
Generate n random transforms whose translations are constrained by extents.
Definition: utility.cpp:226
BV_splitter.h
extents
CoalScalar extents[6]
Definition: test/geometric_shapes.cpp:53
coal::HeightField
Data structure depicting a height field given by the base grid dimensions and the elevation along the...
Definition: coal/hfield.h:202
coal::MatrixXs
Eigen::Matrix< CoalScalar, Eigen::Dynamic, Eigen::Dynamic > MatrixXs
Definition: coal/data_types.h:86
coal::AABB::min_
Vec3s min_
The min point in the AABB.
Definition: coal/BV/AABB.h:58
coal::OcTreePtr_t
shared_ptr< OcTree > OcTreePtr_t
Definition: include/coal/fwd.hh:144
coal::BVHModel
A class describing the bounding hierarchy of a mesh model or a point cloud model (which is viewed as ...
Definition: coal/BVH/BVH_model.h:314
coal::OcTree
Octree is one type of collision geometry which can encode uncertainty information in the sensor data.
Definition: coal/octree.h:53
hfield.h
geometric_shapes_utility.h
coal::OcTree::getTree
shared_ptr< const octomap::OcTree > getTree() const
Returns the tree associated to the underlying octomap OcTree.
Definition: coal/octree.h:100
geometric_shapes.h
coal::collide
COAL_DLLAPI std::size_t collide(const CollisionObject *o1, const CollisionObject *o2, const CollisionRequest &request, CollisionResult &result)
Main collision interface: given two collision objects, and the requirements for contacts,...
Definition: src/collision.cpp:61
coal::getNbRun
std::size_t getNbRun(const int &argc, char const *const *argv, std::size_t defaultValue)
Get the argument –nb-run from argv.
Definition: utility.cpp:384
coal::CoalScalar
double CoalScalar
Definition: coal/data_types.h:76
coal::loadOBJFile
void loadOBJFile(const char *filename, std::vector< Vec3s > &points, std::vector< Triangle > &triangles)
Load an obj mesh file.
Definition: utility.cpp:97


hpp-fcl
Author(s):
autogenerated on Sat Nov 23 2024 03:44:58