Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ROS2] Porting bodies::Body::computeBoundingBox changes from noetic to ROS2 #239

Open
wants to merge 35 commits into
base: ros2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
92744ad
merging obb into ros2
peci1 Nov 22, 2021
2e7de79
test bounding box updated
spelletier1996 Apr 19, 2024
f74c0d1
Added obb.h
tmayoff Apr 19, 2024
994b258
Merge branch 'ros2-obb' of github.com:spelletier1996/geometric_shapes…
tmayoff Apr 19, 2024
517648f
updated tests and cpp to 232
spelletier1996 Apr 19, 2024
5d04936
Merge branch 'ros2-obb' of github.com:spelletier1996/geometric_shapes…
spelletier1996 Apr 19, 2024
d6a80af
Fixed build
tmayoff Apr 19, 2024
483b844
Fixed license
tmayoff Apr 19, 2024
c014758
added obb to bodies header
spelletier1996 Apr 19, 2024
9caa2eb
Merge branch 'ros2-obb' of github.com:spelletier1996/geometric_shapes…
spelletier1996 Apr 19, 2024
169d33b
Fixed FCL dependency
tmayoff Apr 19, 2024
e055eed
.
tmayoff Apr 19, 2024
a108625
merged changes from 232
spelletier1996 Apr 19, 2024
0814306
Merge branch 'ros2-obb' of github.com:spelletier1996/geometric_shapes…
spelletier1996 Apr 19, 2024
8aa8ca3
Builds tests pass (copyright fails though)
tmayoff Apr 19, 2024
f49fdf6
Reverted copyright notice changes
tmayoff Apr 19, 2024
fdad9d3
Fixed copyright notices
tmayoff Apr 19, 2024
43939d4
^
tmayoff Apr 19, 2024
48bc778
Ran pre-commit
tmayoff Apr 19, 2024
5f351f4
added pcl to package.xml
tmayoff Apr 19, 2024
e15c6af
format
tmayoff Apr 19, 2024
520d5a5
Copyright year
spelletier1996 Apr 22, 2024
126955b
reversed white space change
spelletier1996 May 3, 2024
94ea0df
removed commented depends
spelletier1996 May 3, 2024
48bba6f
toFCL fromFCL removed, FCL 0.5 checks removed
spelletier1996 May 3, 2024
26212d1
Merge pull request #2 from spelletier1996/pr-review-fixes
spelletier1996 May 3, 2024
b36a5d7
addressing header and xml comments
spelletier1996 Jun 7, 2024
6c321ec
re-added accidental removal of translation line
spelletier1996 Jun 7, 2024
1818146
correct ifdef
spelletier1996 Jun 7, 2024
5bd19db
fix redundant depends
tmayoff Jul 15, 2024
998a998
added copyright notice
tmayoff Jul 15, 2024
0d04ba5
copied the copyright from the obb.h file
tmayoff Jul 15, 2024
daa7464
Merge branch 'ros2' into ros2-obb
tmayoff Jul 15, 2024
7f76e3b
remove fcl export
tmayoff Jul 18, 2024
0117184
Added libfcl to back to exec-depend
tmayoff Nov 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ find_package(rclcpp REQUIRED)
find_package(resource_retriever REQUIRED)
find_package(shape_msgs REQUIRED)
find_package(visualization_msgs REQUIRED)
find_package(fcl REQUIRED)
include(ConfigExtras)

set(THIS_PACKAGE_EXPORT_DEPENDS
Expand Down Expand Up @@ -80,13 +81,15 @@ add_library(${PROJECT_NAME} SHARED
src/bodies.cpp
src/body_operations.cpp
src/mesh_operations.cpp
src/obb.cpp
src/shape_extents.cpp
src/shape_operations.cpp
src/shape_to_marker.cpp
src/shapes.cpp
)
set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${${PROJECT_NAME}_VERSION} WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
target_compile_options(${PROJECT_NAME} PRIVATE ${PROJECT_COMPILE_OPTIONS})
target_link_libraries(${PROJECT_NAME} fcl)
ament_target_dependencies(${PROJECT_NAME}
${THIS_PACKAGE_EXPORT_DEPENDS}
)
Expand Down
9 changes: 9 additions & 0 deletions include/geometric_shapes/bodies.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

#define _USE_MATH_DEFINES
#include "geometric_shapes/aabb.h"
#include "geometric_shapes/obb.h"
#include "geometric_shapes/shapes.h"
#include <eigen_stl_containers/eigen_stl_containers.h>
#include <random_numbers/random_numbers.h>
Expand Down Expand Up @@ -240,6 +241,10 @@ class Body
pose. Scaling and padding are accounted for. */
virtual void computeBoundingBox(AABB& bbox) const = 0;

/** \brief Compute the oriented bounding box for the body, in its current
pose. Scaling and padding are accounted for. */
virtual void computeBoundingBox(OBB& bbox) const = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will break ABI (the virtual keyword). Not sure what is the current policy regarding ABI breakages.


/** \brief Get a clone of this body, but one that is located at the pose \e pose */
inline BodyPtr cloneAt(const Eigen::Isometry3d& pose) const
{
Expand Down Expand Up @@ -307,6 +312,7 @@ class Sphere : public Body
void computeBoundingSphere(BoundingSphere& sphere) const override;
void computeBoundingCylinder(BoundingCylinder& cylinder) const override;
void computeBoundingBox(AABB& bbox) const override;
void computeBoundingBox(OBB& bbox) const override;
bool intersectsRay(const Eigen::Vector3d& origin, const Eigen::Vector3d& dir,
EigenSTL::vector_Vector3d* intersections = nullptr, unsigned int count = 0) const override;

Expand Down Expand Up @@ -359,6 +365,7 @@ class Cylinder : public Body
void computeBoundingSphere(BoundingSphere& sphere) const override;
void computeBoundingCylinder(BoundingCylinder& cylinder) const override;
void computeBoundingBox(AABB& bbox) const override;
void computeBoundingBox(OBB& bbox) const override;
bool intersectsRay(const Eigen::Vector3d& origin, const Eigen::Vector3d& dir,
EigenSTL::vector_Vector3d* intersections = nullptr, unsigned int count = 0) const override;

Expand Down Expand Up @@ -421,6 +428,7 @@ class Box : public Body
void computeBoundingSphere(BoundingSphere& sphere) const override;
void computeBoundingCylinder(BoundingCylinder& cylinder) const override;
void computeBoundingBox(AABB& bbox) const override;
void computeBoundingBox(OBB& bbox) const override;
bool intersectsRay(const Eigen::Vector3d& origin, const Eigen::Vector3d& dir,
EigenSTL::vector_Vector3d* intersections = nullptr, unsigned int count = 0) const override;

Expand Down Expand Up @@ -483,6 +491,7 @@ class ConvexMesh : public Body
void computeBoundingSphere(BoundingSphere& sphere) const override;
void computeBoundingCylinder(BoundingCylinder& cylinder) const override;
void computeBoundingBox(AABB& bbox) const override;
void computeBoundingBox(OBB& bbox) const override;
bool intersectsRay(const Eigen::Vector3d& origin, const Eigen::Vector3d& dir,
EigenSTL::vector_Vector3d* intersections = nullptr, unsigned int count = 0) const override;

Expand Down
3 changes: 3 additions & 0 deletions include/geometric_shapes/body_operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ void mergeBoundingSpheres(const std::vector<BoundingSphere>& spheres, BoundingSp
/** \brief Compute an axis-aligned bounding box to enclose a set of bounding boxes. */
void mergeBoundingBoxes(const std::vector<AABB>& boxes, AABB& mergedBox);

/** \brief Compute an approximate oriented bounding box to enclose a set of bounding boxes. */
void mergeBoundingBoxesApprox(const std::vector<OBB>& boxes, OBB& mergedBox);

/** \brief Compute the bounding sphere for a set of \e bodies and store the resulting sphere in \e mergedSphere */
void computeBoundingSphere(const std::vector<const Body*>& bodies, BoundingSphere& mergedSphere);
} // namespace bodies
Expand Down
142 changes: 142 additions & 0 deletions include/geometric_shapes/obb.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// Copyright 2024 Open Robotics
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the Open Robotics nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

/* Author: Martin Pecka */

#ifndef GEOMETRIC_SHAPES_OBB_H
#define GEOMETRIC_SHAPES_OBB_H

#include <memory>

#include <Eigen/Core>
#include <Eigen/Geometry>

#include <eigen_stl_containers/eigen_stl_containers.h>
#include <geometric_shapes/aabb.h>

namespace bodies
{
class OBBPrivate;

/** \brief Represents an oriented bounding box. */
class OBB
{
public:
/** \brief Initialize an oriented bounding box at position 0, with 0 extents and
* identity orientation. */
OBB();
OBB(const OBB& other);
OBB(const Eigen::Isometry3d& pose, const Eigen::Vector3d& extents);
virtual ~OBB();

OBB& operator=(const OBB& other);

/**
* \brief Set both the pose and extents of the OBB.
* \param [in] pose New pose of the OBB.
* \param [in] extents New extents of the OBB.
*/
void setPoseAndExtents(const Eigen::Isometry3d& pose, const Eigen::Vector3d& extents);

/**
* \brief Get the extents of the OBB.
* \return The extents.
*/
Eigen::Vector3d getExtents() const;

/**
* \brief Get the extents of the OBB.
* \param extents [out] The extents.
*/
void getExtents(Eigen::Vector3d& extents) const;

/**
* \brief Get the pose of the OBB.
* \return The pose.
*/
Eigen::Isometry3d getPose() const;

/**
* \brief Get The pose of the OBB.
* \param pose The pose.
*/
void getPose(Eigen::Isometry3d& pose) const;

/**
* \brief Convert this OBB to an axis-aligned BB.
* \return The AABB.
*/
AABB toAABB() const;

/**
* \brief Convert this OBB to an axis-aligned BB.
* \param aabb The AABB.
*/
void toAABB(AABB& aabb) const;

/**
* \brief Add the other OBB to this one and compute an approximate enclosing OBB.
* \param box The other box to add.
* \return Pointer to this OBB after the update.
*/
OBB* extendApprox(const OBB& box);

/**
* \brief Check if this OBB contains the given point.
* \param point The point to check.
* \return Whether the point is inside or not.
*/
bool contains(const Eigen::Vector3d& point) const;

/**
* \brief Check whether this and the given OBBs have nonempty intersection.
* \param other The other OBB to check.
* \return Whether the OBBs overlap.
*/
bool overlaps(const OBB& other) const;

/**
* \brief Check if this OBB contains whole other OBB.
* \param point The point to check.
* \return Whether the point is inside or not.
*/
bool contains(const OBB& obb) const;

/**
* \brief Compute coordinates of the 8 vertices of this OBB.
* \return The vertices.
*/
EigenSTL::vector_Vector3d computeVertices() const;

protected:
/** \brief PIMPL pointer */
std::unique_ptr<OBBPrivate> obb_;
};
} // namespace bodies

#endif // GEOMETRIC_SHAPES_OBB_H
5 changes: 4 additions & 1 deletion package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
<depend>visualization_msgs</depend>

<build_depend>assimp-dev</build_depend>
<build_depend>eigen</build_depend>
<build_depend>libfcl-dev</build_depend>
spelletier1996 marked this conversation as resolved.
Show resolved Hide resolved
<build_depend>pkg-config</build_depend>
<build_depend>libboost-dev</build_depend>
<build_depend>libboost-filesystem-dev</build_depend>
Expand All @@ -45,7 +47,8 @@
<exec_depend>assimp</exec_depend>
<exec_depend>libboost-filesystem</exec_depend>
<exec_depend>rosidl_default_runtime</exec_depend>

<exec_depend>libfcl-dev</exec_depend>

<test_depend>ament_cmake_gtest</test_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_cmake</test_depend>
Expand Down
12 changes: 7 additions & 5 deletions src/aabb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,24 @@

#include <geometric_shapes/aabb.h>

#include <fcl/geometry/shape/utility.h>

spelletier1996 marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These includes now seem irrelevant.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With switching to the correct ifdef as you mentioned below I believe that #include <fcl/geometry/shape/utility.h>
is still required?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, some fcl include is still required. This seems good.

void bodies::AABB::extendWithTransformedBox(const Eigen::Isometry3d& transform, const Eigen::Vector3d& box)
{
// Method adapted from FCL src/shape/geometric_shapes_utility.cpp#computeBV<AABB, Box>(...) (BSD-licensed code):
// https://github.com/flexible-collision-library/fcl/blob/fcl-0.4/src/shape/geometric_shapes_utility.cpp#L292
// We don't call their code because it would need creating temporary objects, and their method is in floats.
// We don't call their code because it would need creating temporary objects, and their method is in floats in FCL 0.5
//
// Here's a nice explanation why it works: https://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/

const Eigen::Matrix3d& r = transform.rotation();
const Eigen::Vector3d& t = transform.translation();

double x_range = 0.5 * (fabs(r(0, 0) * box[0]) + fabs(r(0, 1) * box[1]) + fabs(r(0, 2) * box[2]));
double y_range = 0.5 * (fabs(r(1, 0) * box[0]) + fabs(r(1, 1) * box[1]) + fabs(r(1, 2) * box[2]));
double z_range = 0.5 * (fabs(r(2, 0) * box[0]) + fabs(r(2, 1) * box[1]) + fabs(r(2, 2) * box[2]));

const Eigen::Vector3d v_delta(x_range, y_range, z_range);
extend(t + v_delta);
extend(t - v_delta);
fcl::AABBd aabb;
fcl::computeBV(fcl::Boxd(box), transform, aabb);
extend(aabb.min_);
extend(aabb.max_);
}
24 changes: 24 additions & 0 deletions src/bodies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,15 @@ void bodies::Sphere::computeBoundingBox(bodies::AABB& bbox) const
bbox.extendWithTransformedBox(transform, Eigen::Vector3d(2 * radiusU_, 2 * radiusU_, 2 * radiusU_));
}

void bodies::Sphere::computeBoundingBox(bodies::OBB& bbox) const
{
// it's a sphere, so we do not rotate the bounding box
Eigen::Isometry3d transform = Eigen::Isometry3d::Identity();
transform.translation() = getPose().translation();

bbox.setPoseAndExtents(transform, 2 * Eigen::Vector3d(radiusU_, radiusU_, radiusU_));
}

bool bodies::Sphere::samplePointInside(random_numbers::RandomNumberGenerator& rng, unsigned int max_attempts,
Eigen::Vector3d& result) const
{
Expand Down Expand Up @@ -427,6 +436,11 @@ void bodies::Cylinder::computeBoundingBox(bodies::AABB& bbox) const
bbox.extend(pb + e);
}

void bodies::Cylinder::computeBoundingBox(bodies::OBB& bbox) const
{
bbox.setPoseAndExtents(getPose(), 2 * Eigen::Vector3d(radiusU_, radiusU_, length2_));
}

bool bodies::Cylinder::intersectsRay(const Eigen::Vector3d& origin, const Eigen::Vector3d& dir,
EigenSTL::vector_Vector3d* intersections, unsigned int count) const
{
Expand Down Expand Up @@ -663,6 +677,11 @@ void bodies::Box::computeBoundingBox(bodies::AABB& bbox) const
bbox.extendWithTransformedBox(getPose(), 2 * Eigen::Vector3d(length2_, width2_, height2_));
}

void bodies::Box::computeBoundingBox(bodies::OBB& bbox) const
{
bbox.setPoseAndExtents(getPose(), 2 * Eigen::Vector3d(length2_, width2_, height2_));
}

bool bodies::Box::intersectsRay(const Eigen::Vector3d& origin, const Eigen::Vector3d& dir,
EigenSTL::vector_Vector3d* intersections, unsigned int count) const
{
Expand Down Expand Up @@ -1155,6 +1174,11 @@ void bodies::ConvexMesh::computeBoundingBox(bodies::AABB& bbox) const
bounding_box_.computeBoundingBox(bbox);
}

void bodies::ConvexMesh::computeBoundingBox(bodies::OBB& bbox) const
{
bounding_box_.computeBoundingBox(bbox);
}

bool bodies::ConvexMesh::isPointInsidePlanes(const Eigen::Vector3d& point) const
{
unsigned int numplanes = mesh_data_->planes_.size();
Expand Down
6 changes: 6 additions & 0 deletions src/body_operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,9 @@ void bodies::mergeBoundingBoxes(const std::vector<bodies::AABB>& boxes, bodies::
for (const auto& box : boxes)
mergedBox.extend(box);
}

void bodies::mergeBoundingBoxesApprox(const std::vector<bodies::OBB>& boxes, bodies::OBB& mergedBox)
{
for (const auto& box : boxes)
mergedBox.extendApprox(box);
}
Loading