forked from sammy-tri/drake
-
Notifications
You must be signed in to change notification settings - Fork 0
/
binding.h
98 lines (81 loc) · 2.95 KB
/
binding.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
#pragma once
#include <memory>
#include <utility>
#include "drake/common/drake_copyable.h"
#include "drake/common/drake_deprecated.h"
#include "drake/solvers/decision_variable.h"
namespace drake {
namespace solvers {
/**
* A binding on constraint type C is a mapping of the decision
* variables onto the inputs of C. This allows the constraint to operate
* on a vector made up of different elements of the decision variables.
*/
template <typename C>
class Binding {
public:
DRAKE_DEFAULT_COPY_AND_MOVE_AND_ASSIGN(Binding)
Binding(const std::shared_ptr<C>& c,
const Eigen::Ref<const VectorXDecisionVariable>& v)
: evaluator_(c), vars_(v) {
DRAKE_DEMAND(c->num_vars() == v.rows() || c->num_vars() == Eigen::Dynamic);
}
/**
* Concatenates each VectorDecisionVariable object in @p v into a single
* column vector, binds this column vector of decision variables with
* the constraint @p c.
*/
Binding(const std::shared_ptr<C>& c, const VariableRefList& v)
: evaluator_(c) {
vars_ = ConcatenateVariableRefList(v);
DRAKE_DEMAND(c->num_vars() == vars_.rows() ||
c->num_vars() == Eigen::Dynamic);
}
template <typename U>
Binding(const Binding<U>& b,
typename std::enable_if<std::is_convertible<
std::shared_ptr<U>, std::shared_ptr<C>>::value>::type* = nullptr)
: Binding(b.evaluator(), b.variables()) {}
DRAKE_DEPRECATED("Please use evaluator() instead of constraint()")
const std::shared_ptr<C>& constraint() const { return evaluator_; }
const std::shared_ptr<C>& evaluator() const { return evaluator_; }
const VectorXDecisionVariable& variables() const { return vars_; }
/**
* Returns true iff the given @p var is included in this Binding. */
bool ContainsVariable(const symbolic::Variable& var) const {
for (int i = 0; i < vars_.rows(); ++i) {
if (vars_(i).equal_to(var)) {
return true;
}
}
return false;
}
size_t GetNumElements() const {
// TODO(ggould-tri) assumes that no index appears more than once in the
// view, which is nowhere asserted (but seems assumed elsewhere).
return vars_.size();
}
private:
std::shared_ptr<C> evaluator_;
VectorXDecisionVariable vars_;
};
namespace internal {
/*
* Create binding, inferring the type from the provided pointer.
* @tparam C Cost or Constraint type to be bound.
* @note Since this forwards arguments, this will not be usable with
* `std::intializer_list`.
*/
template <typename C, typename... Args>
Binding<C> CreateBinding(const std::shared_ptr<C>& c, Args&&... args) {
return Binding<C>(c, std::forward<Args>(args)...);
}
template <typename To, typename From>
Binding<To> BindingDynamicCast(const Binding<From>& binding) {
auto constraint = std::dynamic_pointer_cast<To>(binding.evaluator());
DRAKE_DEMAND(constraint != nullptr);
return Binding<To>(constraint, binding.variables());
}
} // namespace internal
} // namespace solvers
} // namespace drake