test/collision.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011-2014, Willow Garage, Inc.
5  * Copyright (c) 2014-2015, Open Source Robotics Foundation
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 Open Source Robotics Foundation 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 #include <boost/mpl/vector.hpp>
39 
40 #define BOOST_TEST_MODULE COAL_COLLISION
41 #include <boost/test/included/unit_test.hpp>
42 
43 #include <fstream>
44 #include <boost/assign/list_of.hpp>
45 
46 #include "coal/fwd.hh"
47 
50 
51 #include "coal/collision.h"
52 
54 
55 #include "coal/BV/BV.h"
59 
62 #include "../src/collision_node.h"
64 
65 #include "coal/timings.h"
66 
67 #include "utility.h"
68 #include "fcl_resources/config.h"
69 
70 using namespace coal;
71 namespace utf = boost::unit_test::framework;
72 
73 int num_max_contacts = (std::numeric_limits<int>::max)();
74 
75 BOOST_AUTO_TEST_CASE(OBB_Box_test) {
76  CoalScalar r_extents[] = {-1000, -1000, -1000, 1000, 1000, 1000};
77  std::vector<Transform3s> rotate_transform;
78  generateRandomTransforms(r_extents, rotate_transform, 1);
79 
80  AABB aabb1;
81  aabb1.min_ = Vec3s(-600, -600, -600);
82  aabb1.max_ = Vec3s(600, 600, 600);
83 
84  OBB obb1;
85  convertBV(aabb1, rotate_transform[0], obb1);
86  Box box1;
87  Transform3s box1_tf;
88  constructBox(aabb1, rotate_transform[0], box1, box1_tf);
89 
90  CoalScalar extents[] = {-1000, -1000, -1000, 1000, 1000, 1000};
91  std::size_t n = 1000;
92 
93  std::vector<Transform3s> transforms;
94  generateRandomTransforms(extents, transforms, n);
95 
96  for (std::size_t i = 0; i < transforms.size(); ++i) {
97  AABB aabb;
98  aabb.min_ = aabb1.min_ * 0.5;
99  aabb.max_ = aabb1.max_ * 0.5;
100 
101  OBB obb2;
102  convertBV(aabb, transforms[i], obb2);
103 
104  Box box2;
105  Transform3s box2_tf;
106  constructBox(aabb, transforms[i], box2, box2_tf);
107 
108  GJKSolver solver;
109 
110  bool overlap_obb = obb1.overlap(obb2);
111  CollisionRequest request;
112  CollisionResult result;
113  // Convention: when doing primitive-primitive collision, either use
114  // `collide` or `ShapeShapeCollide`.
115  // **DO NOT** use methods of the GJKSolver directly if you don't know what
116  // you are doing.
117  ShapeShapeCollide<Box, Box>(&box1, box1_tf, &box2, box2_tf, &solver,
118  request, result);
119  bool overlap_box = result.isCollision();
120 
121  BOOST_CHECK(overlap_obb == overlap_box);
122  }
123 }
124 
125 BOOST_AUTO_TEST_CASE(OBB_shape_test) {
126  CoalScalar r_extents[] = {-1000, -1000, -1000, 1000, 1000, 1000};
127  std::vector<Transform3s> rotate_transform;
128  generateRandomTransforms(r_extents, rotate_transform, 1);
129 
130  AABB aabb1;
131  aabb1.min_ = Vec3s(-600, -600, -600);
132  aabb1.max_ = Vec3s(600, 600, 600);
133 
134  OBB obb1;
135  convertBV(aabb1, rotate_transform[0], obb1);
136  Box box1;
137  Transform3s box1_tf;
138  constructBox(aabb1, rotate_transform[0], box1, box1_tf);
139 
140  CoalScalar extents[] = {-1000, -1000, -1000, 1000, 1000, 1000};
141  std::size_t n = 1000;
142 
143  std::vector<Transform3s> transforms;
144  generateRandomTransforms(extents, transforms, n);
145 
146  for (std::size_t i = 0; i < transforms.size(); ++i) {
147  CoalScalar len = (aabb1.max_[0] - aabb1.min_[0]) * 0.5;
148  OBB obb2;
149  GJKSolver solver;
150 
151  {
152  Sphere sphere(len);
153  computeBV(sphere, transforms[i], obb2);
154 
155  bool overlap_obb = obb1.overlap(obb2);
156  CollisionRequest request;
157  CollisionResult result;
158  ShapeShapeCollide<Box, Sphere>(&box1, box1_tf, &sphere, transforms[i],
159  &solver, request, result);
160  bool overlap_sphere = result.isCollision();
161  // The sphere is contained inside obb2. So if the sphere overlaps with
162  // obb1, then necessarily obb2 overlaps with obb1.
163  BOOST_CHECK(overlap_obb >= overlap_sphere);
164  }
165 
166  {
167  Capsule capsule(len, 2 * len);
168  computeBV(capsule, transforms[i], obb2);
169 
170  bool overlap_obb = obb1.overlap(obb2);
171 
172  CollisionRequest request;
173  CollisionResult result;
174  ShapeShapeCollide<Box, Capsule>(&box1, box1_tf, &capsule, transforms[i],
175  &solver, request, result);
176  bool overlap_capsule = result.isCollision();
177  BOOST_CHECK(overlap_obb >= overlap_capsule);
178  }
179 
180  {
181  Cone cone(len, 2 * len);
182  computeBV(cone, transforms[i], obb2);
183 
184  bool overlap_obb = obb1.overlap(obb2);
185  CollisionRequest request;
186  CollisionResult result;
187  ShapeShapeCollide<Box, Cone>(&box1, box1_tf, &cone, transforms[i],
188  &solver, request, result);
189  bool overlap_cone = result.isCollision();
190  BOOST_CHECK(overlap_obb >= overlap_cone);
191  }
192 
193  {
194  Cylinder cylinder(len, 2 * len);
195  computeBV(cylinder, transforms[i], obb2);
196 
197  bool overlap_obb = obb1.overlap(obb2);
198  CollisionRequest request;
199  CollisionResult result;
200  ShapeShapeCollide<Box, Cylinder>(&box1, box1_tf, &cylinder, transforms[i],
201  &solver, request, result);
202  bool overlap_cylinder = result.isCollision();
203  BOOST_CHECK(overlap_obb >= overlap_cylinder);
204  }
205  }
206 }
207 
208 BOOST_AUTO_TEST_CASE(OBB_AABB_test) {
209  CoalScalar extents[] = {-1000, -1000, -1000, 1000, 1000, 1000};
210  std::size_t n = 1000;
211 
212  std::vector<Transform3s> transforms;
213  generateRandomTransforms(extents, transforms, n);
214 
215  AABB aabb1;
216  aabb1.min_ = Vec3s(-600, -600, -600);
217  aabb1.max_ = Vec3s(600, 600, 600);
218 
219  OBB obb1;
220  convertBV(aabb1, Transform3s(), obb1);
221 
222  for (std::size_t i = 0; i < transforms.size(); ++i) {
223  AABB aabb;
224  aabb.min_ = aabb1.min_ * 0.5;
225  aabb.max_ = aabb1.max_ * 0.5;
226 
227  AABB aabb2 = translate(aabb, transforms[i].getTranslation());
228 
229  OBB obb2;
230  convertBV(aabb, Transform3s(transforms[i].getTranslation()), obb2);
231 
232  bool overlap_aabb = aabb1.overlap(aabb2);
233  bool overlap_obb = obb1.overlap(obb2);
234  if (overlap_aabb != overlap_obb) {
235  std::cout << aabb1.min_ << " " << aabb1.max_ << std::endl;
236  std::cout << aabb2.min_ << " " << aabb2.max_ << std::endl;
237  std::cout << obb1.To << " " << obb1.extent << " " << obb1.axes
238  << std::endl;
239  std::cout << obb2.To << " " << obb2.extent << " " << obb2.axes
240  << std::endl;
241  }
242 
243  BOOST_CHECK(overlap_aabb == overlap_obb);
244  }
245  std::cout << std::endl;
246 }
247 
248 std::ostream* bench_stream = NULL;
249 bool bs_nl = true;
250 bool bs_hp = false;
251 #define BENCHMARK(stream) \
252  if (bench_stream != NULL) { \
253  *bench_stream << (bs_nl ? "" : ", ") << stream; \
254  bs_nl = false; \
255  }
256 #define BENCHMARK_HEADER(stream) \
257  if (!bs_hp) { \
258  BENCHMARK(stream) \
259  }
260 #define BENCHMARK_NEXT() \
261  if (bench_stream != NULL && !bs_nl) { \
262  *bench_stream << '\n'; \
263  bs_nl = true; \
264  bs_hp = true; \
265  }
266 
267 typedef std::vector<Contact> Contacts_t;
268 typedef boost::mpl::vector<OBB, RSS, KDOP<24>, KDOP<18>, KDOP<16>, kIOS, OBBRSS>
270 std::vector<SplitMethodType> splitMethods = boost::assign::list_of(
272 
273 #define BV_STR_SPECIALIZATION(bv) \
274  template <> \
275  const char* str<bv>() { \
276  return #bv; \
277  }
278 template <typename BV>
279 const char* str();
288 
289 template <typename T>
290 struct wrap {};
291 
292 struct base_traits {
293  enum { IS_IMPLEMENTED = true };
294 };
295 
296 enum {
297  Oriented = true,
298  NonOriented = false,
299  Recursive = true,
300  NonRecursive = false
301 };
302 
303 template <typename BV, bool Oriented, bool recursive>
304 struct traits : base_traits {};
305 
306 template <short N, bool recursive>
307 struct traits<KDOP<N>, Oriented, recursive> : base_traits {
308  enum { IS_IMPLEMENTED = false };
309 };
310 
313 
315  mesh_mesh_run_test(const std::vector<Transform3s>& _transforms,
316  const CollisionRequest _request)
317  : transforms(_transforms),
318  request(_request),
319  enable_statistics(false),
320  benchmark(false),
321  isInit(false),
322  indent(0) {}
323 
324  const std::vector<Transform3s>& transforms;
326  bool enable_statistics, benchmark;
327  std::vector<Contacts_t> contacts;
328  std::vector<Contacts_t> contacts_ref;
329  bool isInit;
330 
331  int indent;
332 
334 
335  const char* getindent() {
336  assert(indent < 9);
337  static const char* t[] = {"",
338  "\t",
339  "\t\t",
340  "\t\t\t",
341  "\t\t\t\t",
342  "\t\t\t\t\t",
343  "\t\t\t\t\t\t",
344  "\t\t\t\t\t\t\t",
345  "\t\t\t\t\t\t\t\t"};
346  return t[indent];
347  }
348 
349  template <typename BV>
350  void query(const std::vector<Transform3s>& transforms,
351  SplitMethodType splitMethod, const CollisionRequest request,
352  std::vector<Contacts_t>& contacts) {
353  BENCHMARK_HEADER("BV");
354  BENCHMARK_HEADER("oriented");
355  BENCHMARK_HEADER("Split method");
356  if (enable_statistics) {
357  BENCHMARK_HEADER("num_bv_tests");
358  BENCHMARK_HEADER("num_leaf_tests");
359  }
360  BENCHMARK_HEADER("numContacts");
361  BENCHMARK_HEADER("distance_lower_bound");
362  BENCHMARK_HEADER("time");
363  BENCHMARK_NEXT();
364 
365  typedef BVHModel<BV> BVH_t;
366  typedef shared_ptr<BVH_t> BVHPtr_t;
367 
368  BVHPtr_t model1(new BVH_t), model2(new BVH_t);
369  model1->bv_splitter.reset(new BVSplitter<BV>(splitMethod));
370  model2->bv_splitter.reset(new BVSplitter<BV>(splitMethod));
371 
372  loadPolyhedronFromResource(TEST_RESOURCES_DIR "/env.obj", Vec3s::Ones(),
373  model1);
374  loadPolyhedronFromResource(TEST_RESOURCES_DIR "/rob.obj", Vec3s::Ones(),
375  model2);
376 
377  Timer timer(false);
378  const Transform3s tf2;
379  const std::size_t N = transforms.size();
380 
381  contacts.resize(3 * N);
382 
384  BOOST_TEST_MESSAGE(getindent() << "BV: " << str<BV>() << " oriented");
385  ++indent;
386 
387  for (std::size_t i = 0; i < transforms.size(); ++i) {
388  const Transform3s& tf1 = transforms[i];
389  timer.start();
390 
391  CollisionResult local_result;
392  MeshCollisionTraversalNode<BV, 0> node(request);
393  node.enable_statistics = enable_statistics;
394 
395  bool success =
396  initialize(node, *model1, tf1, *model2, tf2, local_result);
397  BOOST_REQUIRE(success);
398 
399  collide(&node, request, local_result);
400 
401  timer.stop();
402 
403  BENCHMARK(str<BV>());
404  BENCHMARK(1);
405  BENCHMARK(splitMethod);
406  if (enable_statistics) {
407  BOOST_TEST_MESSAGE(getindent() << "statistics: " << node.num_bv_tests
408  << " " << node.num_leaf_tests);
409  BOOST_TEST_MESSAGE(getindent()
410  << "nb contacts: " << local_result.numContacts());
411  BENCHMARK(node.num_bv_tests);
412  BENCHMARK(node.num_leaf_tests);
413  }
414  BENCHMARK(local_result.numContacts());
415  BENCHMARK(local_result.distance_lower_bound);
416  BENCHMARK(timer.duration().count());
417  BENCHMARK_NEXT();
418 
419  if (local_result.numContacts() > 0) {
420  local_result.getContacts(contacts[i]);
421  std::sort(contacts[i].begin(), contacts[i].end());
422  }
423  }
424  --indent;
425  }
426 
428  BOOST_TEST_MESSAGE(getindent() << "BV: " << str<BV>());
429  ++indent;
430 
431  for (std::size_t i = 0; i < transforms.size(); ++i) {
432  const Transform3s tf1 = transforms[i];
433 
434  timer.start();
435  CollisionResult local_result;
436  MeshCollisionTraversalNode<BV, RelativeTransformationIsIdentity> node(
437  request);
438  node.enable_statistics = enable_statistics;
439 
440  BVH_t* model1_tmp = new BVH_t(*model1);
441  Transform3s tf1_tmp = tf1;
442  BVH_t* model2_tmp = new BVH_t(*model2);
443  Transform3s tf2_tmp = tf2;
444 
445  bool success = initialize(node, *model1_tmp, tf1_tmp, *model2_tmp,
446  tf2_tmp, local_result, true, true);
447  BOOST_REQUIRE(success);
448 
449  collide(&node, request, local_result);
450  delete model1_tmp;
451  delete model2_tmp;
452 
453  timer.stop();
454  BENCHMARK(str<BV>());
455  BENCHMARK(2);
456  BENCHMARK(splitMethod);
457  if (enable_statistics) {
458  BOOST_TEST_MESSAGE(getindent() << "statistics: " << node.num_bv_tests
459  << " " << node.num_leaf_tests);
460  BOOST_TEST_MESSAGE(getindent()
461  << "nb contacts: " << local_result.numContacts());
462  BENCHMARK(node.num_bv_tests);
463  BENCHMARK(node.num_leaf_tests);
464  }
465  BENCHMARK(local_result.numContacts());
466  BENCHMARK(local_result.distance_lower_bound);
467  BENCHMARK(timer.duration().count());
468  BENCHMARK_NEXT();
469 
470  if (local_result.numContacts() > 0) {
471  local_result.getContacts(contacts[i + N]);
472  std::sort(contacts[i + N].begin(), contacts[i + N].end());
473  }
474  }
475  --indent;
476  }
477 
479  BOOST_TEST_MESSAGE(getindent()
480  << "BV: " << str<BV>() << " oriented non-recursive");
481  ++indent;
482 
483  for (std::size_t i = 0; i < transforms.size(); ++i) {
484  timer.start();
485  const Transform3s tf1 = transforms[i];
486 
487  CollisionResult local_result;
488  MeshCollisionTraversalNode<BV, 0> node(request);
489  node.enable_statistics = enable_statistics;
490 
491  bool success =
492  initialize(node, *model1, tf1, *model2, tf2, local_result);
493  BOOST_REQUIRE(success);
494 
495  collide(&node, request, local_result, NULL, false);
496 
497  timer.stop();
498  BENCHMARK(str<BV>());
499  BENCHMARK(0);
500  BENCHMARK(splitMethod);
501  if (enable_statistics) {
502  BOOST_TEST_MESSAGE(getindent() << "statistics: " << node.num_bv_tests
503  << " " << node.num_leaf_tests);
504  BOOST_TEST_MESSAGE(getindent()
505  << "nb contacts: " << local_result.numContacts());
506  BENCHMARK(node.num_bv_tests);
507  BENCHMARK(node.num_leaf_tests);
508  }
509  BENCHMARK(local_result.numContacts());
510  BENCHMARK(local_result.distance_lower_bound);
511  BENCHMARK(timer.duration().count());
512  BENCHMARK_NEXT();
513 
514  if (local_result.numContacts() > 0) {
515  local_result.getContacts(contacts[i + 2 * N]);
516  std::sort(contacts[i + 2 * N].begin(), contacts[i + 2 * N].end());
517  }
518  }
519  --indent;
520  }
521  }
522 
523  void check_contacts(std::size_t i0, std::size_t i1, bool warn) {
524  for (std::size_t i = i0; i < i1; ++i) {
525  Contacts_t in_ref_but_not_in_i;
526  std::set_difference(
527  contacts_ref[i].begin(), contacts_ref[i].end(), contacts[i].begin(),
528  contacts[i].end(),
529  std::inserter(in_ref_but_not_in_i, in_ref_but_not_in_i.begin()));
530  if (!in_ref_but_not_in_i.empty()) {
531  for (std::size_t j = 0; j < in_ref_but_not_in_i.size(); ++j) {
532  if (warn) {
533  BOOST_WARN_MESSAGE(
534  false, "Missed contacts: " << in_ref_but_not_in_i[j].b1 << ", "
535  << in_ref_but_not_in_i[j].b2);
536  } else {
537  BOOST_CHECK_MESSAGE(
538  false, "Missed contacts: " << in_ref_but_not_in_i[j].b1 << ", "
539  << in_ref_but_not_in_i[j].b2);
540  }
541  }
542  }
543 
544  Contacts_t in_i_but_not_in_ref;
545  std::set_difference(
546  contacts[i].begin(), contacts[i].end(), contacts_ref[i].begin(),
547  contacts_ref[i].end(),
548  std::inserter(in_i_but_not_in_ref, in_i_but_not_in_ref.begin()));
549 
550  if (!in_i_but_not_in_ref.empty()) {
551  for (std::size_t j = 0; j < in_i_but_not_in_ref.size(); ++j) {
552  if (warn) {
553  BOOST_WARN_MESSAGE(
554  false, "False contacts: " << in_i_but_not_in_ref[j].b1 << ", "
555  << in_i_but_not_in_ref[j].b2);
556  } else {
557  BOOST_CHECK_MESSAGE(
558  false, "False contacts: " << in_i_but_not_in_ref[j].b1 << ", "
559  << in_i_but_not_in_ref[j].b2);
560  }
561  }
562  }
563  }
564  }
565 
566  template <typename BV>
567  void check() {
568  if (benchmark) return;
569  const std::size_t N = transforms.size();
570 
571  BOOST_REQUIRE_EQUAL(contacts.size(), 3 * N);
572  BOOST_REQUIRE_EQUAL(contacts.size(), contacts_ref.size());
573 
575  BOOST_TEST_MESSAGE(getindent() << "BV: " << str<BV>() << " oriented");
576  ++indent;
577  check_contacts(0, N, false);
578  --indent;
579  }
581  BOOST_TEST_MESSAGE(getindent() << "BV: " << str<BV>());
582  ++indent;
583  check_contacts(N, 2 * N, true);
584  --indent;
585  }
587  BOOST_TEST_MESSAGE(getindent()
588  << "BV: " << str<BV>() << " oriented non-recursive");
589  ++indent;
590  check_contacts(2 * N, 3 * N, false);
591  --indent;
592  }
593  }
594 
595  template <typename BV>
597  for (std::size_t i = 0; i < splitMethods.size(); ++i) {
598  BOOST_TEST_MESSAGE(getindent() << "splitMethod: " << splitMethods[i]);
599  ++indent;
600  query<BV>(transforms, splitMethods[i], request,
601  (isInit ? contacts : contacts_ref));
602  if (isInit) check<BV>();
603  isInit = true;
604  --indent;
605  }
606  }
607 };
608 
609 // This test
610 // 1. load two objects "env.obj" and "rob.obj" from directory
611 // fcl_resources,
612 // 2. generates n random transformation and for each of them denote tf,
613 // 2.1 performs a collision test where object 1 is in pose tf. All
614 // the contacts are stored in vector global_pairs.
615 // 2.2 performs a series of collision tests with the same object and
616 // the same poses using various methods and various types of bounding
617 // volumes. Each time the contacts are stored in vector global_pairs_now.
618 //
619 // The methods used to test collision are
620 // - collide_Test that calls function collide with tf for object1 pose and
621 // identity for the second object pose,
622 // - collide_Test2 that moves all vertices of object1 in pose tf and that
623 // calls function collide with identity for both object poses,
624 //
626  std::vector<Transform3s> transforms;
627  CoalScalar extents[] = {-3000, -3000, 0, 3000, 3000, 3000};
628 #ifndef NDEBUG // if debug mode
629  std::size_t n = 1;
630 #else
631  std::size_t n = 10;
632 #endif
633  n = getNbRun(utf::master_test_suite().argc, utf::master_test_suite().argv, n);
634 
635  generateRandomTransforms(extents, transforms, n);
636 
637  Eigen::IOFormat f(Eigen::FullPrecision, 0, ", ", ",", "", "", "(", ")");
638  for (std::size_t i = 0; i < transforms.size(); ++i) {
639  BOOST_TEST_MESSAGE(
640  "q" << i << "=" << transforms[i].getTranslation().format(f) << "+"
641  << transforms[i].getQuatRotation().coeffs().format(f));
642  }
643 
646 
647  // Request all contacts and check that all methods give the same result.
648  mesh_mesh_run_test runner(
649  transforms, CollisionRequest(CONTACT, (size_t)num_max_contacts));
650  runner.enable_statistics = true;
651  boost::mpl::for_each<BVs_t, wrap<boost::mpl::placeholders::_1> >(runner);
652 
654 }
655 
656 BOOST_AUTO_TEST_CASE(mesh_mesh_benchmark) {
657  std::vector<Transform3s> transforms;
658  CoalScalar extents[] = {-3000, -3000, 0, 3000, 3000, 3000};
659 #ifndef NDEBUG
660  std::size_t n = 0;
661 #else
662  std::size_t n = 10;
663 #endif
664  n = getNbRun(utf::master_test_suite().argc, utf::master_test_suite().argv, n);
665 
666  generateRandomTransforms(extents, transforms, n);
667 
668  Eigen::IOFormat f(Eigen::FullPrecision, 0, ", ", ",", "", "", "(", ")");
669  for (std::size_t i = 0; i < transforms.size(); ++i) {
670  BOOST_TEST_MESSAGE(
671  "q" << i << "=" << transforms[i].getTranslation().format(f) << "+"
672  << transforms[i].getQuatRotation().coeffs().format(f));
673  }
674 
675  // Request all contacts and check that all methods give the same result.
676  typedef boost::mpl::vector<OBB, RSS, AABB, KDOP<24>, KDOP<18>, KDOP<16>, kIOS,
677  OBBRSS>
678  BVs_t;
679 
680  std::ofstream ofs("./collision.benchmark.csv", std::ofstream::out);
681  bench_stream = &ofs;
682 
683  // without lower bound.
684  mesh_mesh_run_test runner1(transforms, CollisionRequest());
685  runner1.enable_statistics = false;
686  runner1.benchmark = true;
687  boost::mpl::for_each<BVs_t, wrap<boost::mpl::placeholders::_1> >(runner1);
688 
689  // with lower bound.
690  mesh_mesh_run_test runner2(transforms,
692  runner2.enable_statistics = false;
693  runner2.benchmark = true;
694  boost::mpl::for_each<BVs_t, wrap<boost::mpl::placeholders::_1> >(runner2);
695 
696  bench_stream = NULL;
697  ofs.close();
698 }
mesh_mesh_run_test::check_contacts
void check_contacts(std::size_t i0, std::size_t i1, bool warn)
Definition: test/collision.cpp:523
collision.h
coal::CONTACT
@ CONTACT
Definition: coal/collision_data.h:305
coal::Vec3s
Eigen::Matrix< CoalScalar, 3, 1 > Vec3s
Definition: coal/data_types.h:77
splitMethods
std::vector< SplitMethodType > splitMethods
Definition: test/collision.cpp:270
coal::SplitMethodType
SplitMethodType
Three types of split algorithms are provided in FCL as default.
Definition: coal/internal/BV_splitter.h:50
coal::Timer::stop
void stop()
Definition: coal/timings.h:76
mesh_mesh_run_test::benchmark
bool benchmark
Definition: test/collision.cpp:326
COAL_COMPILER_DIAGNOSTIC_PUSH
#define COAL_COMPILER_DIAGNOSTIC_PUSH
Definition: include/coal/fwd.hh:120
coal::CollisionResult::isCollision
bool isCollision() const
return binary collision result
Definition: coal/collision_data.h:443
coal::loadPolyhedronFromResource
void loadPolyhedronFromResource(const std::string &resource_path, const coal::Vec3s &scale, const shared_ptr< BVHModel< BoundingVolume > > &polyhedron)
Read a mesh file and convert it to a polyhedral mesh.
Definition: coal/mesh_loader/assimp.h:116
coal::Timer
This class mimics the way "boost/timer/timer.hpp" operates while using the modern std::chrono library...
Definition: coal/timings.h:31
mesh_mesh_run_test::indent
int indent
Definition: test/collision.cpp:331
mesh_mesh_run_test::mesh_mesh_run_test
mesh_mesh_run_test(const std::vector< Transform3s > &_transforms, const CollisionRequest _request)
Definition: test/collision.cpp:315
collision_manager.sphere
sphere
Definition: collision_manager.py:4
mesh_mesh_run_test::operator()
void operator()(wrap< BV >)
Definition: test/collision.cpp:596
traversal_node_bvhs.h
coal::OBB::extent
Vec3s extent
Half dimensions of OBB.
Definition: include/coal/BV/OBB.h:65
mesh_mesh_run_test::enable_statistics
bool enable_statistics
Definition: test/collision.cpp:326
gjk.tf1
tuple tf1
Definition: test/scripts/gjk.py:27
coal::Capsule
Capsule It is where is the distance between the point x and the capsule segment AB,...
Definition: coal/shape/geometric_shapes.h:383
coal::OBB::axes
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Matrix3s axes
Orientation of OBB. axis[i] is the ith column of the orientation matrix for the box; it is also the i...
Definition: include/coal/BV/OBB.h:59
BV_STR_SPECIALIZATION
#define BV_STR_SPECIALIZATION(bv)
Definition: test/collision.cpp:273
bench_stream
std::ostream * bench_stream
Definition: test/collision.cpp:248
coal::OBB::To
Vec3s To
Center of OBB.
Definition: include/coal/BV/OBB.h:62
coal
Main namespace.
Definition: coal/broadphase/broadphase_bruteforce.h:44
narrowphase.h
utility.h
coal::kIOS
A class describing the kIOS collision structure, which is a set of spheres.
Definition: coal/BV/kIOS.h:52
coal::GJKSolver
collision and distance solver based on the GJK and EPA algorithms. Originally, GJK and EPA were imple...
Definition: coal/narrowphase/narrowphase.h:57
bs_hp
bool bs_hp
Definition: test/collision.cpp:250
coal::BVSplitter
A class describing the split rule that splits each BV node.
Definition: coal/BVH/BVH_model.h:61
coal::OBB::overlap
bool overlap(const OBB &other) const
Definition: OBB.cpp:394
BV.h
coal::AABB
A class describing the AABB collision structure, which is a box in 3D space determined by two diagona...
Definition: coal/BV/AABB.h:55
coal::SPLIT_METHOD_MEAN
@ SPLIT_METHOD_MEAN
Definition: coal/internal/BV_splitter.h:51
coal::CollisionResult::distance_lower_bound
CoalScalar distance_lower_bound
Definition: coal/collision_data.h:401
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::Sphere
Center at zero point sphere.
Definition: coal/shape/geometric_shapes.h:240
mesh_mesh_run_test::getindent
const COAL_COMPILER_DIAGNOSTIC_POP char * getindent()
Definition: test/collision.cpp:335
traversal_node_setup.h
BENCHMARK
#define BENCHMARK(stream)
Definition: test/collision.cpp:251
coal::Transform3s
Simple transform class used locally by InterpMotion.
Definition: coal/math/transform.h:55
BENCHMARK_HEADER
#define BENCHMARK_HEADER(stream)
Definition: test/collision.cpp:256
mesh_mesh_run_test
Definition: test/collision.cpp:314
coal::AABB::max_
Vec3s max_
The max point in the AABB.
Definition: coal/BV/AABB.h:60
Recursive
@ Recursive
Definition: test/collision.cpp:299
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::AABB::overlap
bool overlap(const AABB &other) const
Check whether two AABB are overlap.
Definition: coal/BV/AABB.h:111
bs_nl
bool bs_nl
Definition: test/collision.cpp:249
coal::OBBRSS
Class merging the OBB and RSS, can handle collision and distance simultaneously.
Definition: coal/BV/OBBRSS.h:53
NonOriented
@ NonOriented
Definition: test/collision.cpp:298
mesh_mesh_run_test::query
void query(const std::vector< Transform3s > &transforms, SplitMethodType splitMethod, const CollisionRequest request, std::vector< Contacts_t > &contacts)
Definition: test/collision.cpp:350
fwd.hh
mesh_mesh_run_test::contacts
std::vector< Contacts_t > contacts
Definition: test/collision.cpp:327
traits
Definition: benchmark.cpp:54
coal::SPLIT_METHOD_MEDIAN
@ SPLIT_METHOD_MEDIAN
Definition: coal/internal/BV_splitter.h:52
coal::CollisionResult
collision result
Definition: coal/collision_data.h:390
wrap
Definition: test/collision.cpp:290
coal::CollisionRequest
request to the collision algorithm
Definition: coal/collision_data.h:311
Contacts_t
std::vector< Contact > Contacts_t
Definition: test/collision.cpp:267
coal::Timer::start
void start()
Definition: coal/timings.h:65
gjk.tf2
tuple tf2
Definition: test/scripts/gjk.py:36
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(OBB_Box_test)
Definition: test/collision.cpp:75
coal::Cylinder
Cylinder along Z axis. The cylinder is defined at its centroid.
Definition: coal/shape/geometric_shapes.h:560
base_traits
Definition: test/collision.cpp:292
coal::translate
static AABB translate(const AABB &aabb, const Vec3s &t)
translate the center of AABB by t
Definition: coal/BV/AABB.h:233
mesh_mesh_run_test::transforms
const std::vector< Transform3s > & transforms
Definition: test/collision.cpp:324
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
assimp.h
coal::KDOP
KDOP class describes the KDOP collision structures. K is set as the template parameter,...
Definition: coal/BV/kDOP.h:91
coal::AABB::min_
Vec3s min_
The min point in the AABB.
Definition: coal/BV/AABB.h:58
Oriented
@ Oriented
Definition: test/collision.cpp:297
mesh_mesh_run_test::check
void check()
Definition: test/collision.cpp:567
coal::Cone
Cone The base of the cone is at and the top is at .
Definition: coal/shape/geometric_shapes.h:467
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
BENCHMARK_NEXT
#define BENCHMARK_NEXT()
Definition: test/collision.cpp:260
mesh_mesh_run_test::contacts_ref
std::vector< Contacts_t > contacts_ref
Definition: test/collision.cpp:328
COAL_COMPILER_DIAGNOSTIC_POP
#define COAL_COMPILER_DIAGNOSTIC_POP
Definition: include/coal/fwd.hh:121
COAL_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS
#define COAL_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS
Definition: include/coal/fwd.hh:122
geometric_shapes.h
coal::convertBV
static void convertBV(const BV1 &bv1, const Transform3s &tf1, BV2 &bv2)
Convert a bounding volume of type BV1 in configuration tf1 to bounding volume of type BV2 in identity...
Definition: coal/BV/BV.h:276
coal::computeBV
void computeBV(const S &s, const Transform3s &tf, BV &bv)
calculate a bounding volume for a shape in a specific configuration
Definition: coal/shape/geometric_shapes_utility.h:73
coal::CollisionResult::getContacts
void getContacts(std::vector< Contact > &contacts_) const
get all the contacts
Definition: coal/collision_data.h:475
num_max_contacts
int num_max_contacts
Definition: test/collision.cpp:73
BVs_t
boost::mpl::vector< OBB, RSS, KDOP< 24 >, KDOP< 18 >, KDOP< 16 >, kIOS, OBBRSS > BVs_t
Definition: test/collision.cpp:269
coal::OBB
Oriented bounding box class.
Definition: include/coal/BV/OBB.h:51
mesh_mesh_run_test::request
const CollisionRequest request
Definition: test/collision.cpp:325
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
timings.h
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
mesh_mesh_run_test::isInit
bool isInit
Definition: test/collision.cpp:329
t
dictionary t
coal::RSS
A class for rectangle sphere-swept bounding volume.
Definition: coal/BV/RSS.h:53
coal::CoalScalar
double CoalScalar
Definition: coal/data_types.h:76
NonRecursive
@ NonRecursive
Definition: test/collision.cpp:300
str
const char * str()
Definition: doxygen_xml_parser.py:885
coal::SPLIT_METHOD_BV_CENTER
@ SPLIT_METHOD_BV_CENTER
Definition: coal/internal/BV_splitter.h:53
initialize
bool initialize(MeshCollisionTraversalNode< BV, RelativeTransformationIsIdentity > &node, BVHModel< BV > &model1, Transform3s &tf1, BVHModel< BV > &model2, Transform3s &tf2, CollisionResult &result, bool use_refit=false, bool refit_bottomup=false)
Initialize traversal node for collision between two meshes, given the current transforms.
Definition: coal/internal/traversal_node_setup.h:467
coal::CollisionResult::numContacts
size_t numContacts() const
number of contacts found
Definition: coal/collision_data.h:446


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