-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
cartesian_product.h
150 lines (115 loc) · 5.88 KB
/
cartesian_product.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#pragma once
#include <memory>
#include <optional>
#include <utility>
#include <vector>
#include "drake/geometry/optimization/convex_set.h"
namespace drake {
namespace geometry {
namespace optimization {
/** The Cartesian product of convex sets is a convex set:
S = X₁ × X₂ × ⋯ × Xₙ =
{(x₁, x₂, ..., xₙ) | x₁ ∈ X₁, x₂ ∈ X₂, ..., xₙ ∈ Xₙ}.
This class also supports a generalization of this concept in which the
coordinates are transformed by the linear map,
{x | y = Ax + b, y ∈ Y₁ × Y₂ × ⋯ × Yₙ},
with the default values set to the identity map. This concept is required for
reasoning about cylinders in arbitrary poses as cartesian products, and more
generally for describing any affine transform of a CartesianProduct.
Special behavior for IsEmpty: If there are no sets in the product, returns
nonempty by convention. See:
https://en.wikipedia.org/wiki/Empty_product#Nullary_Cartesian_product
Otherwise, if any set in the cartesian product is empty, the whole product
is empty.
@ingroup geometry_optimization */
class CartesianProduct final : public ConvexSet {
public:
DRAKE_DEFAULT_COPY_AND_MOVE_AND_ASSIGN(CartesianProduct)
/** Constructs a default (zero-dimensional, nonempty) set. */
CartesianProduct();
/** Constructs the product from a vector of convex sets. */
explicit CartesianProduct(const ConvexSets& sets);
/** Constructs the product from a pair of convex sets. */
CartesianProduct(const ConvexSet& setA, const ConvexSet& setB);
/** Constructs the product of convex sets in the transformed coordinates:
{x | y = Ax + b, y ∈ Y₁ × Y₂ × ⋯ × Yₙ}.
@throws std::exception when `A` is not full column rank. */
CartesianProduct(const ConvexSets& sets,
const Eigen::Ref<const Eigen::MatrixXd>& A,
const Eigen::Ref<const Eigen::VectorXd>& b);
/** Constructs a CartesianProduct from a SceneGraph geometry and pose in the
`reference_frame` frame, obtained via the QueryObject. If `reference_frame`
frame is std::nullopt, then it will be expressed in the world frame.
Although any geometry that can be used as a ConvexSet could also be a
(trivial) CartesianProduct, we restrict this constructor to handling Cylinder
geometry, which constructs the (non-trivial) Cartesian product of a
HyperEllipsoid and an HPolyhedron. Most other SceneGraph geometry types are
supported by at least one of the ConvexSet class constructors.
@throws std::exception if geometry_id does not correspond to a Cylinder. */
CartesianProduct(const QueryObject<double>& query_object,
GeometryId geometry_id,
std::optional<FrameId> reference_frame = std::nullopt);
~CartesianProduct() final;
/** The number of factors (or sets) used in the product. */
int num_factors() const { return sets_.size(); }
/** Returns a reference to the ConvexSet defining the `index` factor in the
product. */
const ConvexSet& factor(int i) const;
/** Returns true if each subvector is in its corresponding set with tolerance
`tol`. Note: Tolerance support for this query varies in the different convex
set implementations. */
using ConvexSet::PointInSet;
/** @throws if `set.has_exact_volume() == false` for any of the sets in the
product. */
using ConvexSet::CalcVolume;
private:
std::unique_ptr<ConvexSet> DoClone() const final;
std::optional<bool> DoIsBoundedShortcut() const final;
bool DoIsEmpty() const final;
std::optional<Eigen::VectorXd> DoMaybeGetPoint() const final;
std::optional<Eigen::VectorXd> DoMaybeGetFeasiblePoint() const final;
/* Given a list of vectors, one from each constituent set of this
CartesianProduct, this stacks them into a single vector. Then, if this
CartesianProduct has an associated transformation (in the form of an A_
matrix and b_ vector), it applies that transformation. */
Eigen::VectorXd StackAndMaybeTransform(
const std::vector<Eigen::VectorXd>& points) const;
bool DoPointInSet(const Eigen::Ref<const Eigen::VectorXd>& x,
double tol) const final;
std::pair<VectorX<symbolic::Variable>,
std::vector<solvers::Binding<solvers::Constraint>>>
DoAddPointInSetConstraints(
solvers::MathematicalProgram*,
const Eigen::Ref<const solvers::VectorXDecisionVariable>&) const final;
std::vector<solvers::Binding<solvers::Constraint>>
DoAddPointInNonnegativeScalingConstraints(
solvers::MathematicalProgram* prog,
const Eigen::Ref<const solvers::VectorXDecisionVariable>& x,
const symbolic::Variable& t) const final;
std::vector<solvers::Binding<solvers::Constraint>>
DoAddPointInNonnegativeScalingConstraints(
solvers::MathematicalProgram* prog,
const Eigen::Ref<const Eigen::MatrixXd>& A_x,
const Eigen::Ref<const Eigen::VectorXd>& b_x,
const Eigen::Ref<const Eigen::VectorXd>& c, double d,
const Eigen::Ref<const solvers::VectorXDecisionVariable>& x,
const Eigen::Ref<const solvers::VectorXDecisionVariable>& t) const final;
std::pair<std::unique_ptr<Shape>, math::RigidTransformd> DoToShapeWithPose()
const final;
// The member variables are not const in order to support move semantics.
ConvexSets sets_{};
// Note: We make these optional, instead of Identity() and Zero(), so we can
// avoid adding additional variables and constraints to MathematicalPrograms
// in the implementation.
std::optional<Eigen::MatrixXd> A_{std::nullopt};
std::optional<Eigen::VectorXd> b_{std::nullopt};
// When an `A` is passed to the constructor, we'll compute its decomposition
// and store it here for later use. Note that even though the constructor for
// a scene graph cylinder sets A_, it does not set A_decomp_.
std::optional<Eigen::ColPivHouseholderQR<Eigen::MatrixXd>> A_decomp_{
std::nullopt};
double DoCalcVolume() const final;
};
} // namespace optimization
} // namespace geometry
} // namespace drake