1 |
|
|
/** |
2 |
|
|
* @file |
3 |
|
|
* @authors Nahuel Villa, Maximilien Naveau |
4 |
|
|
* @copyright Copyright (c) 2022 LAAS-CNRS, TOWARD, PAL_ROBOTICS |
5 |
|
|
* License BSD-2 |
6 |
|
|
* |
7 |
|
|
* @brief Class to perform inverse geometry on a biped robot. |
8 |
|
|
*/ |
9 |
|
|
|
10 |
|
|
#ifndef DYNACOM_DYNACOM |
11 |
|
|
#define DYNACOM_DYNACOM |
12 |
|
|
|
13 |
|
|
// clang-format off |
14 |
|
|
#include <Eigen/Dense> |
15 |
|
|
#include "pinocchio/fwd.hpp" |
16 |
|
|
#include "pinocchio/multibody/data.hpp" |
17 |
|
|
#include "pinocchio/multibody/model.hpp" |
18 |
|
|
#include "pinocchio/spatial/se3.hpp" |
19 |
|
|
#include <map> |
20 |
|
|
#include <memory> |
21 |
|
|
#include "dynacom/contact6d.hpp" |
22 |
|
|
// clang-format on |
23 |
|
|
|
24 |
|
|
// @TODO: add abstract class contact and new implementation of it contactPoint. |
25 |
|
|
// @TODO: implement method copy of contacts to be able to duplicate them easily. |
26 |
|
|
// @TODO: In the getters uni_A, fria_A, uni_b, fri_b return only the active |
27 |
|
|
// block. |
28 |
|
|
// @TODO: change internaly the system of names by ids. |
29 |
|
|
|
30 |
|
|
namespace dynacom { |
31 |
|
|
|
32 |
|
|
struct DynaCoMSettings { |
33 |
|
|
public: |
34 |
|
|
/** |
35 |
|
|
* @brief This must contain either a valid path to the urdf file or the |
36 |
|
|
* content of this file in a string. |
37 |
|
|
*/ |
38 |
|
|
std::string urdf = ""; |
39 |
|
|
|
40 |
|
|
friend std::ostream &operator<<(std::ostream &out, |
41 |
|
|
const DynaCoMSettings &obj) { |
42 |
|
|
out << "DynaCoMSettings:\n"; |
43 |
|
|
out << " urdf: " << obj.urdf << std::endl; |
44 |
|
|
return out; |
45 |
|
|
} |
46 |
|
|
|
47 |
|
|
friend bool operator==(const DynaCoMSettings &lhs, |
48 |
|
|
const DynaCoMSettings &rhs) { |
49 |
|
|
bool test = true; |
50 |
|
|
test &= lhs.urdf == rhs.urdf; |
51 |
|
|
return test; |
52 |
|
|
} |
53 |
|
|
}; |
54 |
|
|
|
55 |
|
|
class DynaCoM { |
56 |
|
|
public: |
57 |
|
|
EIGEN_MAKE_ALIGNED_OPERATOR_NEW |
58 |
|
|
private: |
59 |
|
|
DynaCoMSettings settings_; |
60 |
|
|
Eigen::Matrix2d S_; |
61 |
|
|
pinocchio::Model model_; |
62 |
|
|
pinocchio::Data data_; |
63 |
|
|
double mass_; |
64 |
|
|
double inf_ = std::numeric_limits<double>::infinity(); |
65 |
|
|
|
66 |
|
|
// Lists of contacts |
67 |
|
|
// std::vector< std::shared_ptr<Contact6D> > known_contact6ds_; |
68 |
|
|
std::map<std::string, std::shared_ptr<Contact6D>> known_contact6ds_; |
69 |
|
|
std::vector<std::string> active_contact6ds_; |
70 |
|
|
|
71 |
|
|
// QP Matrices |
72 |
|
|
Eigen::MatrixXd unilaterality_A_; |
73 |
|
|
Eigen::VectorXd unilaterality_b_; |
74 |
|
|
Eigen::MatrixXd friction_A_; |
75 |
|
|
Eigen::VectorXd friction_b_; |
76 |
|
|
Eigen::VectorXd regularization_A_; |
77 |
|
|
Eigen::VectorXd regularization_b_; |
78 |
|
|
Eigen::Matrix<double, 6, -1> newton_euler_A_; |
79 |
|
|
Eigen::Matrix<double, 6, 1> newton_euler_b_; |
80 |
|
|
|
81 |
|
|
// variables for QP problem with proxsuite formulation |
82 |
|
|
// Eigen::MatrixXd H_, , A_; |
83 |
|
|
// Eigen::VectorXd g_, u_, l_; |
84 |
|
|
// Eigen::Matrix<double, 6, 1> b_; |
85 |
|
|
|
86 |
|
|
// variables for QP problem with eiquadprog formulation |
87 |
|
|
Eigen::MatrixXd G_; // matrix for quadratic cost |
88 |
|
|
Eigen::VectorXd g0_; // linear part of the cost function |
89 |
|
|
Eigen::MatrixXd CE_, CI_, C_; // constraints matrix |
90 |
|
|
Eigen::VectorXd ce0_, ci0_; // constraints vector |
91 |
|
|
|
92 |
|
|
// variables for QP problem |
93 |
|
|
Eigen::VectorXd F_; |
94 |
|
|
Eigen::VectorXi activeSet_; |
95 |
|
|
size_t activeSetSize_; |
96 |
|
|
|
97 |
|
|
size_t cols_, uni_rows_, fri_rows_; |
98 |
|
|
// active sizes: |
99 |
|
|
size_t uni_i_, fri_i_, j_; |
100 |
|
|
|
101 |
|
|
// Internal variables: |
102 |
|
|
Eigen::Vector3d groundCoMForce_, groundCoMTorque_, CoPTorque_, weight_; |
103 |
|
|
Eigen::Vector3d acom_; |
104 |
|
|
Eigen::Vector2d cop_; |
105 |
|
|
Eigen::Vector3d dL_; |
106 |
|
|
Eigen::Vector3d L_; |
107 |
|
|
Eigen::Vector2d n_; |
108 |
|
|
std::vector<std::string>::iterator activeID_; |
109 |
|
|
std::map<std::string, std::shared_ptr<Contact6D>>::iterator knownID_; |
110 |
|
|
|
111 |
|
|
// for the CoP wrench |
112 |
|
|
pinocchio::SE3 oMso_, soMs_; |
113 |
|
|
Eigen::Matrix<double, 6, 6> Sz_, oXso_, soXs_; |
114 |
|
|
|
115 |
|
|
void addSizes(const std::shared_ptr<Contact6D> &contact); |
116 |
|
|
void removeSizes(const std::shared_ptr<Contact6D> &contact); |
117 |
|
|
void resizeMatrices(); |
118 |
|
|
void buildMatrices(const Eigen::Vector3d &groundCoMForce, |
119 |
|
|
const Eigen::Vector3d &groundCoMTorque, |
120 |
|
|
const Eigen::Vector3d &CoM); |
121 |
|
|
void solveQP(); |
122 |
|
|
void distribute(); |
123 |
|
|
|
124 |
|
|
const Eigen::Matrix<double, 6, 6> toWorldCoPWrench(pinocchio::SE3 pose); |
125 |
|
|
|
126 |
|
|
public: |
127 |
|
|
DynaCoM(); |
128 |
|
|
DynaCoM(const DynaCoMSettings settings); |
129 |
|
|
void initialize(const DynaCoMSettings settings); |
130 |
|
|
|
131 |
|
|
void computeDynamics(const Eigen::VectorXd &posture, |
132 |
|
|
const Eigen::VectorXd &velocity, |
133 |
|
|
const Eigen::VectorXd &acceleration, |
134 |
|
|
const Eigen::Matrix<double, 6, 1> &externalWrench = |
135 |
|
|
Eigen::Matrix<double, 6, 1>::Zero(), |
136 |
|
|
bool flatHorizontalGround = true); |
137 |
|
|
|
138 |
|
|
void computeNL(const double &w, const Eigen::VectorXd &posture, |
139 |
|
|
const Eigen::VectorXd &velocity, |
140 |
|
|
const Eigen::VectorXd &acceleration, |
141 |
|
|
const Eigen::Matrix<double, 6, 1> &externalWrench = |
142 |
|
|
Eigen::Matrix<double, 6, 1>::Zero(), |
143 |
|
|
bool flatHorizontalGround = true); |
144 |
|
|
|
145 |
|
|
void computeNL(const double &w); |
146 |
|
|
|
147 |
|
|
void addContact6d(const std::shared_ptr<Contact6D> &contact, |
148 |
|
|
const std::string &name, const bool active = true); |
149 |
|
|
void removeContact6d(const std::string &name); |
150 |
|
|
|
151 |
|
|
void activateContact6d(const std::string &name); |
152 |
|
|
void deactivateContact6d(const std::string &name); |
153 |
|
|
|
154 |
|
|
void distributeForce(const Eigen::Vector3d &groundCoMForce, |
155 |
|
|
const Eigen::Vector3d &groundCoMTorque, |
156 |
|
|
const Eigen::Vector3d &CoM); |
157 |
|
|
|
158 |
|
|
// GETTERS |
159 |
|
|
/// @brief Please call computeDynamics first. |
160 |
|
|
const Eigen::Vector3d &getAMVariation() { return dL_; } |
161 |
|
2 |
const Eigen::Vector3d &getCoM() { return data_.com[0]; } |
162 |
|
|
const Eigen::Vector3d &getVCoM() { return data_.vcom[0]; } |
163 |
|
|
const Eigen::Vector3d &getACoM() { return acom_; } |
164 |
|
|
const Eigen::Vector3d &getAM() { return L_; } |
165 |
|
502 |
const Eigen::Vector2d &getCoP() { return cop_; } |
166 |
|
|
const Eigen::Vector2d &getNL() { return n_; } |
167 |
|
1500 |
const Eigen::Vector3d &getGroundCoMForce() { return groundCoMForce_; } |
168 |
|
1000 |
const Eigen::Vector3d &getGroundCoMTorque() { return groundCoMTorque_; } |
169 |
|
6 |
const std::vector<std::string> &getActiveContacts() { |
170 |
|
6 |
return active_contact6ds_; |
171 |
|
|
} |
172 |
|
1011 |
const std::shared_ptr<Contact6D> &getContact(std::string name) { |
173 |
|
1011 |
return known_contact6ds_[name]; |
174 |
|
|
} |
175 |
|
|
const DynaCoMSettings &getSettings() { return settings_; } |
176 |
|
533 |
const pinocchio::Model &getModel() { return model_; } |
177 |
|
514 |
const pinocchio::Data &getData() { return data_; } |
178 |
|
|
|
179 |
|
|
const Eigen::MatrixXd uni_A() { |
180 |
|
|
return unilaterality_A_.block(0, 0, uni_i_, j_); |
181 |
|
|
} |
182 |
|
|
const Eigen::VectorXd uni_b() { return unilaterality_b_.segment(0, j_); } |
183 |
|
|
const Eigen::MatrixXd fri_A() { return friction_A_.block(0, 0, fri_i_, j_); } |
184 |
|
|
const Eigen::VectorXd fri_b() { return friction_b_.segment(0, j_); } |
185 |
|
|
const Eigen::VectorXd reg_A() { return regularization_A_.segment(0, j_); } |
186 |
|
|
const Eigen::VectorXd reg_b() { return regularization_b_.segment(0, j_); } |
187 |
|
|
const Eigen::Matrix<double, 6, -1> NE_A() { |
188 |
|
|
return newton_euler_A_.block(0, 0, 6, j_); |
189 |
|
|
} |
190 |
|
|
const Eigen::Matrix<double, 6, 1> &NE_b() { return newton_euler_b_; } |
191 |
|
|
const Eigen::VectorXd &allForces() { return F_; } |
192 |
|
|
}; |
193 |
|
|
|
194 |
|
|
} // namespace dynacom |
195 |
|
|
|
196 |
|
|
#endif // DYNACOM_DYNACOM |