37 #define BOOST_TEST_MODULE FCL_HEIGHT_FIELDS 38 #include <boost/test/included/unit_test.hpp> 39 #include <boost/filesystem.hpp> 41 #include "fcl_resources/config.h" 57 template <
typename BV>
59 const Eigen::DenseIndex ny,
62 const FCL_REAL x_dim = 1., y_dim = 2.;
63 const MatrixXf heights = MatrixXf::Constant(ny, nx, max_altitude);
67 BOOST_CHECK(hfield.
getXDim() == x_dim);
68 BOOST_CHECK(hfield.
getYDim() == y_dim);
71 BOOST_CHECK(x_grid[0] == -x_dim / 2.);
72 BOOST_CHECK(x_grid[nx - 1] == x_dim / 2.);
75 BOOST_CHECK(y_grid[0] == y_dim / 2.);
76 BOOST_CHECK(y_grid[ny - 1] == -y_dim / 2.);
81 for (Eigen::DenseIndex i = 0; i < nx; ++i) {
82 for (Eigen::DenseIndex j = 0; j < ny; ++j) {
83 Vec3f point(x_grid[i], y_grid[j], heights(j, i));
92 BOOST_CHECK(*hfield_clone == hfield);
98 const Box equivalent_box(x_dim, y_dim, max_altitude - min_altitude);
100 Matrix3f::Identity(),
Vec3f(0., 0., (max_altitude + min_altitude) / 2.));
106 const Box box(Vec3f::Ones());
112 const FCL_REAL eps_no_collision = +0.1 * (max_altitude - min_altitude);
114 Vec3f(0., 0., max_altitude + sphere.
radius + eps_no_collision));
116 Vec3f(0., 0., max_altitude + box.
halfSide[2] + eps_no_collision));
120 collide(&hfield, IdTransform, &sphere, M_sphere, request, result);
125 collide(&equivalent_box, IdTransform * box_placement, &sphere, M_sphere,
126 request, result_check_sphere);
128 BOOST_CHECK(!result_check_sphere.isCollision());
131 collide(&equivalent_box, IdTransform * box_placement, &box, M_box, request,
134 BOOST_CHECK(!result_check_box.isCollision());
139 const FCL_REAL eps_collision = -0.1 * (max_altitude - min_altitude);
141 Vec3f(0., 0., max_altitude + sphere.
radius + eps_collision));
143 Vec3f(0., 0., max_altitude + box.
halfSide[2] + eps_collision));
148 collide(&hfield, IdTransform, &sphere, M_sphere, request, result);
153 collide(&equivalent_box, IdTransform * box_placement, &sphere, M_sphere,
154 request, result_check);
156 BOOST_CHECK(result_check.isCollision());
159 collide(&equivalent_box, IdTransform * box_placement, &box, M_box, request,
162 BOOST_CHECK(result_check_box.isCollision());
167 MatrixXf::Constant(ny, nx, max_altitude / 2.));
171 const FCL_REAL eps_no_collision = +0.1 * (max_altitude - min_altitude);
173 Vec3f(0., 0., max_altitude + sphere.
radius + eps_no_collision));
175 Vec3f(0., 0., max_altitude + box.
halfSide[2] + eps_no_collision));
179 collide(&hfield, IdTransform, &sphere, M_sphere, request, result);
184 collide(&equivalent_box, IdTransform * box_placement, &sphere, M_sphere,
185 request, result_check_sphere);
187 BOOST_CHECK(!result_check_sphere.isCollision());
190 collide(&equivalent_box, IdTransform * box_placement, &box, M_box, request,
193 BOOST_CHECK(!result_check_box.isCollision());
198 const FCL_REAL eps_collision = -0.1 * (max_altitude - min_altitude);
200 Vec3f(0., 0., max_altitude + sphere.
radius + eps_collision));
202 Vec3f(0., 0., max_altitude + box.
halfSide[2] + eps_collision));
207 collide(&hfield, IdTransform, &sphere, M_sphere, request, result);
212 collide(&equivalent_box, IdTransform * box_placement, &sphere, M_sphere,
213 request, result_check);
215 BOOST_CHECK(result_check.isCollision());
218 collide(&equivalent_box, IdTransform * box_placement, &box, M_box, request,
221 BOOST_CHECK(result_check_box.isCollision());
226 MatrixXf::Constant(ny, nx, max_altitude));
230 const FCL_REAL eps_collision = -0.1 * (max_altitude - min_altitude);
232 Vec3f(0., 0., max_altitude + sphere.
radius + eps_collision));
234 Vec3f(0., 0., max_altitude + box.
halfSide[2] + eps_collision));
239 collide(&hfield, IdTransform, &sphere, M_sphere, request, result);
244 collide(&equivalent_box, IdTransform * box_placement, &sphere, M_sphere,
245 request, result_check);
247 BOOST_CHECK(result_check.isCollision());
250 collide(&equivalent_box, IdTransform * box_placement, &box, M_box, request,
253 BOOST_CHECK(result_check_box.isCollision());
258 const FCL_REAL max_altitude = 1., min_altitude = 0.;
260 test_constant_hfields<OBBRSS>(2, 2, min_altitude,
262 test_constant_hfields<OBBRSS>(20, 2, min_altitude, max_altitude);
263 test_constant_hfields<OBBRSS>(100, 100, min_altitude, max_altitude);
266 test_constant_hfields<AABB>(2, 2, min_altitude, max_altitude);
267 test_constant_hfields<AABB>(20, 2, min_altitude, max_altitude);
268 test_constant_hfields<AABB>(100, 100, min_altitude, max_altitude);
271 template <
typename BV>
273 const Eigen::DenseIndex ny,
276 const FCL_REAL x_dim = 1., y_dim = 2.;
277 const MatrixXf heights = MatrixXf::Constant(ny, nx, max_altitude);
282 const Box equivalent_box(x_dim, y_dim, max_altitude - min_altitude);
284 Matrix3f::Identity(),
Vec3f(0., 0., (max_altitude + min_altitude) / 2.));
290 const Box box(Vec3f::Ones());
296 const FCL_REAL eps_no_collision = +0.1 * (max_altitude - min_altitude);
298 Vec3f(0., 0., max_altitude + sphere.
radius + eps_no_collision));
300 Vec3f(0., 0., max_altitude + box.
halfSide[2] + eps_no_collision));
304 collide(&hfield, IdTransform, &sphere, M_sphere, request, result);
309 collide(&equivalent_box, IdTransform * box_placement, &sphere, M_sphere,
310 request, result_check_sphere);
312 BOOST_CHECK(!result_check_sphere.isCollision());
315 collide(&equivalent_box, IdTransform * box_placement, &box, M_box, request,
318 BOOST_CHECK(!result_check_box.isCollision());
323 const FCL_REAL eps_no_collision = +0.1 * (max_altitude - min_altitude);
325 Vec3f(0., 0., max_altitude + sphere.
radius + eps_no_collision));
327 Vec3f(0., 0., max_altitude + box.
halfSide[2] + eps_no_collision));
332 collide(&hfield, IdTransform, &sphere, M_sphere, request, result);
337 collide(&equivalent_box, IdTransform * box_placement, &sphere, M_sphere,
338 request, result_check_sphere);
340 BOOST_CHECK(result_check_sphere.isCollision());
343 collide(&equivalent_box, IdTransform * box_placement, &box, M_box, request,
346 BOOST_CHECK(result_check_box.isCollision());
351 const FCL_REAL eps_no_collision = -0.1 * (max_altitude - min_altitude);
353 Vec3f(0., 0., max_altitude + sphere.
radius + eps_no_collision));
355 Vec3f(0., 0., max_altitude + box.
halfSide[2] + eps_no_collision));
359 collide(&hfield, IdTransform, &sphere, M_sphere, request, result);
364 collide(&equivalent_box, IdTransform * box_placement, &sphere, M_sphere,
365 request, result_check_sphere);
367 BOOST_CHECK(result_check_sphere.isCollision());
370 collide(&equivalent_box, IdTransform * box_placement, &box, M_box, request,
373 BOOST_CHECK(result_check_box.isCollision());
378 const FCL_REAL eps_no_collision = -0.1 * (max_altitude - min_altitude);
380 Vec3f(0., 0., max_altitude + sphere.
radius + eps_no_collision));
382 Vec3f(0., 0., max_altitude + box.
halfSide[2] + eps_no_collision));
387 collide(&hfield, IdTransform, &sphere, M_sphere, request, result);
392 collide(&equivalent_box, IdTransform * box_placement, &sphere, M_sphere,
393 request, result_check_sphere);
395 BOOST_CHECK(!result_check_sphere.isCollision());
398 collide(&equivalent_box, IdTransform * box_placement, &box, M_box, request,
401 BOOST_CHECK(!result_check_box.isCollision());
406 const FCL_REAL max_altitude = 1., min_altitude = 0.;
410 test_negative_security_margin<AABB>(100, 100, min_altitude, max_altitude);
414 const Eigen::DenseIndex nx = 100, ny = 100;
418 Eigen::RowVectorXd::LinSpaced(nx, -1., 1.).replicate(ny, 1);
419 const MatrixXf Y = Eigen::VectorXd::LinSpaced(ny, 1., -1.).replicate(1, nx);
423 const Eigen::Array<bool, Eigen::Dynamic, Eigen::Dynamic> hole =
424 (X.array().abs() < dim_square) && (Y.array().abs() < dim_square);
427 MatrixXf::Ones(ny, nx) - hole.cast<
double>().matrix();
439 collide(&hfield, hfield_pos, &sphere, sphere_pos, request, result);
448 const Sphere sphere2(0.51);
449 collide(&hfield, hfield_pos, &sphere2, sphere_pos, request, result);
456 const Eigen::DenseIndex nx = 100, ny = 100;
462 Eigen::RowVectorXd::LinSpaced(nx, -1., 1.).replicate(ny, 1);
463 const MatrixXf Y = Eigen::VectorXd::LinSpaced(ny, 1., -1.).replicate(1, nx);
467 const Eigen::Array<bool, Eigen::Dynamic, Eigen::Dynamic> hole =
468 (X.array().square() + Y.array().square() <= dim_hole);
471 MatrixXf::Ones(ny, nx) - hole.cast<
double>().matrix();
475 BOOST_CHECK(hfield.
getXGrid()[0] == -1.);
476 BOOST_CHECK(hfield.
getXGrid()[nx - 1] == +1.);
478 BOOST_CHECK(hfield.
getYGrid()[0] == +1.);
479 BOOST_CHECK(hfield.
getYGrid()[ny - 1] == -1.);
489 collide(&hfield, hfield_pos, &sphere, sphere_pos, request, result);
498 collide(&hfield, hfield_pos, &sphere, sphere_pos, request, result);
507 collide(&hfield, hfield_pos, &sphere, sphere_pos, request, result);
516 collide(&hfield, hfield_pos, &sphere, sphere_pos, request, result);
Vec3f halfSide
box side half-length
FCL_REAL getYDim() const
Returns the dimension of the Height Field along the Y direction.
Eigen::Matrix< FCL_REAL, Eigen::Dynamic, Eigen::Dynamic > MatrixXf
virtual HeightField< BV > * clone() const
Clone *this into a new CollisionGeometry.
Eigen::Matrix< FCL_REAL, Eigen::Dynamic, 1 > VecXf
BOOST_AUTO_TEST_CASE(building_constant_hfields)
FCL_REAL getXDim() const
Returns the dimension of the Height Field along the X direction.
void test_negative_security_margin(const Eigen::DenseIndex nx, const Eigen::DenseIndex ny, const FCL_REAL min_altitude, const FCL_REAL max_altitude)
void computeLocalAABB()
Compute the AABB for the HeightField, used for broad-phase collision.
const VecXf & getXGrid() const
Returns a const reference of the grid along the X direction.
Data structure depicting a height field given by the base grid dimensions and the elevation along the...
request to the collision algorithm
const VecXf & getYGrid() const
Returns a const reference of the grid along the Y direction.
AABB aabb_local
AABB in local coordinate, used for tight AABB when only translation transform.
Center at zero point, axis aligned box.
A class describing the AABB collision structure, which is a box in 3D space determined by two diagona...
FCL_REAL radius
Radius of the sphere.
Center at zero point sphere.
void updateHeights(const MatrixXf &new_heights)
Update Height Field height.
HPP_FCL_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, including num of max contacts, whether perform exhaustive collision (i.e., returning returning all the contact points), whether return detailed contact information (i.e., normal, contact point, depth; otherwise only contact primitive id is returned), this function performs the collision between them. Return value is the number of contacts generated between the two objects.
bool contain(const Vec3f &p) const
Check whether the AABB contains a point.
bool isCollision() const
return binary collision result
Eigen::Matrix< FCL_REAL, 3, 1 > Vec3f
void test_constant_hfields(const Eigen::DenseIndex nx, const Eigen::DenseIndex ny, const FCL_REAL min_altitude, const FCL_REAL max_altitude)
FCL_REAL security_margin
Distance below which objects are considered in collision. See Collision.