forked from RobotLocomotion/drake
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cspace_separating_plane.h
122 lines (104 loc) · 4.86 KB
/
cspace_separating_plane.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
/** @file
This file is used in our C-IRIS algorithm and will be used in our C-Space path
certifier, which certifies collision-free region in the configuration space, by
finding separating planes for each pair of geometry over all configurations in
a C-space region. For the detailed algorithm please refer to the paper <pre>
Certified Polyhedral Decompositions of Collision-Free Configuration Space
by Hongkai Dai*, Alexandre Amice*, Peter Werner, Annan Zhang and Russ Tedrake.
</pre>
*/
#pragma once
#include <utility>
#include "drake/common/symbolic/polynomial.h"
#include "drake/geometry/optimization/c_iris_collision_geometry.h"
namespace drake {
namespace geometry {
namespace optimization {
/** The separating plane aᵀx + b ≥ δ, aᵀx + b ≤ −δ has parameters a and b.
These parameterize a polynomial function of `s_for_plane` with the
specified order. `s_for_plane` is a sub set of the configuration-space
variable `s`, please refer to the RationalForwardKinematics class or
the paper above on the meaning of s.
*/
enum class SeparatingPlaneOrder {
kAffine = 1, ///< a and b are affine functions of s.
};
/** Convert an integer degree to the SeparatingPlaneOrder */
[[nodiscard]] SeparatingPlaneOrder ToPlaneOrder(int plane_degree);
/** Convert SeparatingPlaneOrder to an integer degree. */
[[nodiscard]] int ToPlaneDegree(SeparatingPlaneOrder plane_order);
/**
Wraps the information that a pair of collision geometries are separated by a
plane.
One collision geometry is on the "positive" side of the separating
plane, namely {x| aᵀx + b ≥ δ} (with δ ≥ 0}, and the other collision geometry
is on the "negative" side of the separating plane, namely {x|aᵀx+b ≤ −δ}.
@tparam T The type of decision_variables. T= symbolic::Variable or double.
*/
template <typename T>
struct CSpaceSeparatingPlane {
public:
DRAKE_DEFAULT_COPY_AND_MOVE_AND_ASSIGN(CSpaceSeparatingPlane);
CSpaceSeparatingPlane(
Vector3<symbolic::Polynomial> m_a, symbolic::Polynomial m_b,
const CIrisCollisionGeometry* m_positive_side_geometry,
const CIrisCollisionGeometry* m_negative_side_geometry,
multibody::BodyIndex m_expressed_body, int m_plane_degree,
const Eigen::Ref<const VectorX<T>>& m_decision_variables)
: a{std::move(m_a)},
b{std::move(m_b)},
positive_side_geometry{m_positive_side_geometry},
negative_side_geometry{m_negative_side_geometry},
expressed_body{m_expressed_body},
plane_degree{m_plane_degree},
decision_variables{m_decision_variables} {}
/// Return the geometry on the specified side.
[[nodiscard]] const CIrisCollisionGeometry* geometry(
PlaneSide plane_side) const {
return plane_side == PlaneSide::kPositive ? positive_side_geometry
: negative_side_geometry;
}
[[nodiscard]] SortedPair<geometry::GeometryId> geometry_pair() const {
return SortedPair<geometry::GeometryId>(positive_side_geometry->id(),
negative_side_geometry->id());
}
Vector3<symbolic::Polynomial> a;
symbolic::Polynomial b;
const CIrisCollisionGeometry* positive_side_geometry;
const CIrisCollisionGeometry* negative_side_geometry;
multibody::BodyIndex expressed_body;
int plane_degree{1};
VectorX<T> decision_variables;
};
namespace internal {
void CalcPlane(const VectorX<symbolic::Variable>& decision_variables,
const VectorX<symbolic::Variable>& vars_for_plane,
int plane_degree, Vector3<symbolic::Polynomial>* a_val,
symbolic::Polynomial* b_val);
void CalcPlane(const VectorX<double>& decision_variables,
const VectorX<symbolic::Variable>& vars_for_plane,
int plane_degree, Vector3<symbolic::Polynomial>* a_val,
symbolic::Polynomial* b_val);
void CalcPlane(const VectorX<double>& decision_variables,
const VectorX<double>& vars_for_plane, int plane_degree,
Vector3<double>* a_val, double* b_val);
} // namespace internal
/**
Computes the parameters a, b in the plane { x | aᵀx+b=0 }.
a and b are both polynomials of `vars_for_plane`. The coefficients of these
polynomials are in `decision_variables` in graded reverse lexicographic order.
@tparam D, S, V The valid combination of D, S, V are
1. D=symbolic::Variable, S=symbolic::Variable, V=symbolic::Polynomial.
2. D=double, S=symbolic::Variable, V=symbolic::Polynomial
3. D=double, S=double, V=double
*/
template <typename D, typename S, typename V>
void CalcPlane(const VectorX<D>& decision_variables,
const VectorX<S>& s_for_plane, int plane_degree,
Vector3<V>* a_val, V* b_val) {
internal::CalcPlane(decision_variables, s_for_plane, plane_degree, a_val,
b_val);
}
} // namespace optimization
} // namespace geometry
} // namespace drake