Skip to content

Commit

Permalink
[geometry:optimization] Add VPolytope from HPolyhedron
Browse files Browse the repository at this point in the history
brings in qhull as an external.
  • Loading branch information
RussTedrake committed Oct 1, 2021
1 parent 55ce547 commit d52e84e
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 0 deletions.
1 change: 1 addition & 0 deletions geometry/optimization/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ drake_cc_library(
"//geometry:scene_graph",
"//solvers:mathematical_program",
"//solvers:solve",
"@qhull",
],
)

Expand Down
17 changes: 17 additions & 0 deletions geometry/optimization/test/vpolytope_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,23 @@ GTEST_TEST(VPolytopeTest, UnitBox6DTest) {
EXPECT_FALSE(V.PointInSet(out2_W, kTol));
}

GTEST_TEST(VPolytopeTest, FromHPolyhedronTest) {
HPolyhedron H = HPolyhedron::MakeUnitBox(6);
VPolytope V(H);
EXPECT_EQ(V.ambient_dimension(), 6);
EXPECT_EQ(V.vertices().rows(), 6);
EXPECT_EQ(V.vertices().cols(), 8);

Vector6d in1_W{Vector6d::Constant(-.99)}, in2_W{Vector6d::Constant(.99)},
out1_W{Vector6d::Constant(-1.01)}, out2_W{Vector6d::Constant(1.01)};

const double kTol = 1e-11;
EXPECT_TRUE(V.PointInSet(in1_W, kTol));
EXPECT_TRUE(V.PointInSet(in2_W, kTol));
EXPECT_FALSE(V.PointInSet(out1_W, kTol));
EXPECT_FALSE(V.PointInSet(out2_W, kTol));
}

GTEST_TEST(VPolytopeTest, CloneTest) {
VPolytope V = VPolytope::MakeBox(Vector3d{-3, -4, -5}, Vector3d{6, 7, 8});
std::unique_ptr<ConvexSet> clone = V.Clone();
Expand Down
8 changes: 8 additions & 0 deletions geometry/optimization/vpolytope.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <limits>
#include <memory>

#include "libqhullcpp/Qhull.h"

#include "drake/common/is_approx_equal_abstol.h"
#include "drake/solvers/solve.h"

Expand Down Expand Up @@ -40,6 +42,12 @@ VPolytope::VPolytope(const QueryObject<double>& query_object,
vertices_ = X_EG * vertices;
}

VPolytope::VPolytope(const HPolyhedron& hpoly)
: ConvexSet(&ConvexSetCloner<VPolytope>, hpoly.ambient_dimension()) {
orgQhull::Qhull qhull;
unused(qhull);
}

VPolytope::~VPolytope() = default;

VPolytope VPolytope::MakeBox(const Eigen::Ref<const VectorXd>& lb,
Expand Down
4 changes: 4 additions & 0 deletions geometry/optimization/vpolytope.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <vector>

#include "drake/geometry/optimization/convex_set.h"
#include "drake/geometry/optimization/hpolyhedron.h"

namespace drake {
namespace geometry {
Expand Down Expand Up @@ -35,6 +36,9 @@ class VPolytope final : public ConvexSet {
VPolytope(const QueryObject<double>& query_object, GeometryId geometry_id,
std::optional<FrameId> reference_frame = std::nullopt);

/** Constructs the polytope from a bounded polyhedron (using qhull). */
explicit VPolytope(const HPolyhedron& hpoly);

~VPolytope() final;

/** Returns true if the point is within @p tol of the set under the L∞-norm.
Expand Down
3 changes: 3 additions & 0 deletions tools/workspace/default.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ load("@drake//tools/workspace/pycodestyle:repository.bzl", "pycodestyle_reposito
load("@drake//tools/workspace/pygame_py:repository.bzl", "pygame_py_repository") # noqa
load("@drake//tools/workspace/python:repository.bzl", "python_repository")
load("@drake//tools/workspace/qdldl:repository.bzl", "qdldl_repository")
load("@drake//tools/workspace/qhull:repository.bzl", "qhull_repository")
load("@drake//tools/workspace/ros_xacro:repository.bzl", "ros_xacro_repository") # noqa
load("@drake//tools/workspace/rules_pkg:repository.bzl", "rules_pkg_repository") # noqa
load("@drake//tools/workspace/rules_python:repository.bzl", "rules_python_repository") # noqa
Expand Down Expand Up @@ -231,6 +232,8 @@ def add_default_repositories(excludes = [], mirrors = DEFAULT_MIRRORS):
python_repository(name = "python")
if "qdldl" not in excludes:
qdldl_repository(name = "qdldl", mirrors = mirrors)
if "qhull" not in excludes:
qhull_repository(name = "qhull", mirrors = mirrors)
if "ros_xacro" not in excludes:
ros_xacro_repository(name = "ros_xacro", mirrors = mirrors)
if "rules_pkg" not in excludes:
Expand Down
5 changes: 5 additions & 0 deletions tools/workspace/qhull/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# -*- python -*-

load("//tools/lint:lint.bzl", "add_lint_tests")

add_lint_tests()
33 changes: 33 additions & 0 deletions tools/workspace/qhull/package.BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# -*- python -*-

load(
"@drake//tools/install:install.bzl",
"install",
)

licenses(["notice"]) # Copyright

package(default_visibility = ["//visibility:public"])

cc_library(
name = "qhull",
hdrs = glob(["src/libqhullcpp/*.h", "src/libqhull_r/*.h"]),
includes = ["src"],
srcs = glob([
"src/libqhull_r/*.c",
"src/libqhullcpp/*.cpp",
"src/libqhullcpp/*.h",
],
exclude = [
"src/libqhullcpp/qt-qhull.cpp",
"src/libqhullcpp/usermem_r-cpp.cpp",
],
),
linkstatic = 1,
)

# Install the license file.
install(
name = "install",
docs = ["LICENSE"],
)
15 changes: 15 additions & 0 deletions tools/workspace/qhull/repository.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# -*- python -*-

load("@drake//tools/workspace:github.bzl", "github_archive")

def qhull_repository(
name,
mirrors = None):
github_archive(
name = name,
repository = "qhull/qhull",
commit = "2020.2",
sha256 = "59356b229b768e6e2b09a701448bfa222c37b797a84f87f864f97462d8dbc7c5", # noqa
build_file = "@drake//tools/workspace/qhull:package.BUILD.bazel",
mirrors = mirrors,
)

0 comments on commit d52e84e

Please sign in to comment.