-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
static_friction_cone_complementarity_constraint.h
126 lines (109 loc) · 5.05 KB
/
static_friction_cone_complementarity_constraint.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
#pragma once
#include <memory>
#include <vector>
#include "drake/multibody/optimization/contact_wrench_evaluator.h"
#include "drake/solvers/binding.h"
#include "drake/solvers/constraint.h"
#include "drake/solvers/mathematical_program.h"
namespace drake {
namespace multibody {
namespace internal {
/**
* The nonlinear constraints to be imposed for static friction force. See
* AddStaticFrictionConeComplementarityConstraint() for more details. The
* nonlinear constraints are (1) - (4) in
* AddStaticFrictionConeComplementarityConstraint()
* The bound variable vector for this constraint is x = [q; λ; α; β]
*/
class StaticFrictionConeComplementarityNonlinearConstraint
: public solvers::Constraint {
public:
DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN(
StaticFrictionConeComplementarityNonlinearConstraint)
/**
* See AddStaticFrictionConeComplementarityConstraint() for details.
*/
StaticFrictionConeComplementarityNonlinearConstraint(
const ContactWrenchEvaluator* contact_wrench_evaluator,
double complementarity_tolerance);
~StaticFrictionConeComplementarityNonlinearConstraint() override {}
/** The slack variable for n_Wᵀ * f_W. See
* AddStaticFrictionConeComplementarityConstraint().*/
const symbolic::Variable& alpha_var() const { return alpha_var_; }
/** The slack variable for sdf. See
* AddStaticFrictionConeComplementarityConstraint(). */
const symbolic::Variable& beta_var() const { return beta_var_; }
void UpdateComplementarityTolerance(double complementarity_tolerance);
const ContactWrenchEvaluator& contact_wrench_evaluator() const {
return *contact_wrench_evaluator_;
}
template <typename T>
void DecomposeX(const Eigen::Ref<const VectorX<T>>& x, VectorX<T>* q,
VectorX<T>* lambda, T* alpha, T* beta) const {
*q = x.head(contact_wrench_evaluator_->plant().num_positions());
*lambda = x.segment(q->rows(), contact_wrench_evaluator_->num_lambda());
*alpha = x(x.rows() - 2);
*beta = x(x.rows() - 1);
}
/**
* Create a binding of the constraint, together with the bound variables
* q, λ, α and β. See AddStaticFrictionConeComplementarityConstraint()
* for more details.
*/
static solvers::Binding<
internal::StaticFrictionConeComplementarityNonlinearConstraint>
MakeBinding(const ContactWrenchEvaluator* contact_wrench_evaluator,
double complementarity_tolerance,
const Eigen::Ref<const VectorX<symbolic::Variable>>& q_vars,
const Eigen::Ref<const VectorX<symbolic::Variable>>& lambda_vars);
private:
void DoEval(const Eigen::Ref<const Eigen::VectorXd>& x,
Eigen::VectorXd* y) const final;
void DoEval(const Eigen::Ref<const AutoDiffVecXd>& x,
AutoDiffVecXd* y) const final;
void DoEval(const Eigen::Ref<const VectorX<symbolic::Variable>>& x,
VectorX<symbolic::Expression>* y) const final;
const ContactWrenchEvaluator* const contact_wrench_evaluator_;
symbolic::Variable alpha_var_;
symbolic::Variable beta_var_;
};
}; // namespace internal
/**
* Adds the complementarity constraint on the static friction force
* between a pair of contacts
* |ft_W| <= μ * n_Wᵀ * f_W (static friction force in the friction cone).
* fn_W * sdf = 0 (complementarity condition)
* sdf >= 0 (no penetration)
* where sdf stands for signed distance function, ft_W stands for the tangential
* friction force expressed in the world frame.
*
* Mathematically, we add the following constraints to the optimization program
*
* f_Wᵀ * ((μ² + 1)* n_W * n_Wᵀ - I) * f_W ≥ 0 (1)
* n_Wᵀ * f_W = α (2)
* sdf(q) = β (3)
* 0 ≤ α * β ≤ ε (4)
* α ≥ 0 (5)
* β ≥ 0 (6)
* the slack variables α and β are added to the optimization program as well.
*
* @param contact_wrench_evaluator The evaluator to compute the
* contact wrench expressed in the world frame.
* @param complementarity_tolerance ε in the documentation above.
* @param q_vars The decision variable for the generalized configuration q.
* @param lambda_vars The decision variable to parameterize the contact wrench.
* @param[in,out] prog The optimization program to which the constraint is
* added.
* @return binding The binding containing the nonlinear constraints (1)-(4).
* @pre Both `q_vars` and `lambda_vars` have been added to `prog` before calling
* this function.
*/
solvers::Binding<internal::StaticFrictionConeComplementarityNonlinearConstraint>
AddStaticFrictionConeComplementarityConstraint(
const ContactWrenchEvaluator* contact_wrench_evaluator,
double complementarity_tolerance,
const Eigen::Ref<const VectorX<symbolic::Variable>>& q_vars,
const Eigen::Ref<const VectorX<symbolic::Variable>>& lambda_vars,
solvers::MathematicalProgram* prog);
} // namespace multibody
} // namespace drake