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_CONTACT_6D |
11 |
|
|
#define DYNACOM_CONTACT_6D |
12 |
|
|
|
13 |
|
|
// clang-format off |
14 |
|
|
#include <Eigen/Dense> |
15 |
|
|
#include "pinocchio/spatial/se3.hpp" |
16 |
|
|
#include <memory> |
17 |
|
|
// clang-format on |
18 |
|
|
|
19 |
|
|
namespace dynacom { |
20 |
|
|
|
21 |
|
|
struct Contact6DSettings { |
22 |
|
|
public: |
23 |
|
|
double mu, gu; |
24 |
|
|
double half_length, half_width; |
25 |
|
|
Eigen::Matrix<double, 6, 1> weights; |
26 |
|
|
std::string frame_name; |
27 |
|
|
|
28 |
|
|
std::string to_string() { |
29 |
|
|
std::ostringstream out; |
30 |
|
|
out << "Contact6D " |
31 |
|
|
<< ":\n"; |
32 |
|
|
out << " mu: " << this->mu << "\n"; |
33 |
|
|
out << " gu: " << this->gu << "\n"; |
34 |
|
|
out << " weights: " << this->weights.transpose() << "\n"; |
35 |
|
|
out << " Surface half_length: " << this->half_length << "\n"; |
36 |
|
|
out << " Surface half_width: " << this->half_width << std::endl; |
37 |
|
|
|
38 |
|
|
return out.str(); |
39 |
|
|
} |
40 |
|
|
|
41 |
|
|
std::ostream &operator<<(std::ostream &out) { |
42 |
|
|
out << this->to_string(); |
43 |
|
|
return out; |
44 |
|
|
} |
45 |
|
|
|
46 |
|
|
bool operator!=(const Contact6DSettings &rhs) { return !(*this == rhs); } |
47 |
|
|
|
48 |
|
|
bool operator==(const Contact6DSettings &rhs) { |
49 |
|
|
bool test = true; |
50 |
|
|
test &= this->frame_name == rhs.frame_name; |
51 |
|
|
test &= this->mu == rhs.mu; |
52 |
|
|
test &= this->gu == rhs.gu; |
53 |
|
|
test &= this->half_length == rhs.half_length; |
54 |
|
|
test &= this->half_width == rhs.half_width; |
55 |
|
|
test &= this->weights == rhs.weights; |
56 |
|
|
return test; |
57 |
|
|
} |
58 |
|
|
}; |
59 |
|
|
|
60 |
|
|
class Contact6D { |
61 |
|
|
private: |
62 |
|
|
Contact6DSettings settings_; |
63 |
|
|
pinocchio::SE3 oMs_, cMo_; |
64 |
|
|
|
65 |
|
|
// matrices |
66 |
|
|
Eigen::Matrix<double, 5, 6> unilaterality_A_; |
67 |
|
|
Eigen::Matrix<double, 5, 1> unilaterality_b_; |
68 |
|
|
Eigen::Matrix<double, 6, 6> friction_A_; |
69 |
|
|
Eigen::Matrix<double, 6, 1> friction_b_; |
70 |
|
|
Eigen::Matrix<double, 6, 1> regularization_A_; |
71 |
|
|
Eigen::Matrix<double, 6, 1> regularization_b_; |
72 |
|
|
Eigen::Matrix<double, 6, 6> newton_euler_A_; |
73 |
|
|
Eigen::Matrix<double, 6, 1> contactForce_; |
74 |
|
|
size_t frameID_; |
75 |
|
|
|
76 |
|
|
public: |
77 |
|
|
Contact6D(); |
78 |
|
|
Contact6D(const Contact6DSettings &settings); |
79 |
|
|
void initialize(const Contact6DSettings &settings); |
80 |
|
|
|
81 |
|
|
// ~Contact6D(); |
82 |
|
|
|
83 |
|
|
// setters |
84 |
|
|
void setMu(const double &mu); |
85 |
|
|
void setGu(const double &gu); |
86 |
|
|
void setForceWeights(const Eigen::Vector3d &force_weights); |
87 |
|
|
void setTorqueWeights(const Eigen::Vector3d &torque_weights); |
88 |
|
|
void setSurfaceHalfWidth(const double &half_width); |
89 |
|
|
void setSurfaceHalfLength(const double &half_length); |
90 |
|
|
void updateNewtonEuler(const Eigen::Vector3d &CoM, const pinocchio::SE3 &oMf); |
91 |
|
12 |
void setFrameID(const size_t frameID) { frameID_ = frameID; } |
92 |
|
1006 |
void applyForce(const Eigen::Matrix<double, 6, 1> &force) { |
93 |
|
1006 |
contactForce_ << force; |
94 |
|
1006 |
} |
95 |
|
|
void setPose(pinocchio::SE3 &pose) { oMs_ = pose; } |
96 |
|
|
void deactivate() { contactForce_.setZero(); } |
97 |
|
|
|
98 |
|
|
// getters |
99 |
|
17 |
const Contact6DSettings &getSettings() { return settings_; } |
100 |
|
|
const Eigen::Matrix<double, 6, 6> toWorldForces() { |
101 |
|
|
return oMs_.toActionMatrixInverse().transpose(); |
102 |
|
|
} |
103 |
|
|
const Eigen::Matrix<double, 6, 6> toCoMForces() { |
104 |
|
|
return cMo_.act(oMs_).toActionMatrixInverse().transpose(); |
105 |
|
|
} |
106 |
|
1018 |
size_t uni_rows() const { return unilaterality_A_.rows(); } |
107 |
|
1018 |
size_t fri_rows() const { return friction_A_.rows(); } |
108 |
|
2023 |
size_t cols() const { return newton_euler_A_.cols(); } |
109 |
|
1018 |
size_t getFrameID() const { return frameID_; } |
110 |
|
4 |
const pinocchio::SE3 &getPose() const { return oMs_; } |
111 |
|
|
|
112 |
|
1005 |
const Eigen::Matrix<double, 5, 6> &uni_A() { return unilaterality_A_; } |
113 |
|
1005 |
const Eigen::Matrix<double, 5, 1> &uni_b() { return unilaterality_b_; } |
114 |
|
1005 |
const Eigen::Matrix<double, 6, 6> &fri_A() { return friction_A_; } |
115 |
|
1005 |
const Eigen::Matrix<double, 6, 1> &fri_b() { return friction_b_; } |
116 |
|
1005 |
const Eigen::Matrix<double, 6, 1> ®_A() { return regularization_A_; } |
117 |
|
1005 |
const Eigen::Matrix<double, 6, 1> ®_b() { return regularization_b_; } |
118 |
|
1005 |
const Eigen::Matrix<double, 6, 6> &NE_A() { return newton_euler_A_; } |
119 |
|
|
|
120 |
|
1007 |
const Eigen::Matrix<double, 6, 1> &appliedForce() { return contactForce_; } |
121 |
|
|
}; |
122 |
|
|
|
123 |
|
|
///// Start of future contact point. //////////// |
124 |
|
|
/** |
125 |
|
|
* Still missing the definition of the abstract class Contact which will be |
126 |
|
|
* the ansester of ContactPoint and Contact6D. Similar for the settings. |
127 |
|
|
*/ |
128 |
|
|
struct ContactPointSettings { |
129 |
|
|
public: |
130 |
|
|
double mu; |
131 |
|
|
Eigen::Matrix<double, 3, 1> weights; |
132 |
|
|
std::string frame_name; |
133 |
|
|
|
134 |
|
|
std::string to_string() { |
135 |
|
|
std::ostringstream out; |
136 |
|
|
out << "Contact6D " |
137 |
|
|
<< ":\n"; |
138 |
|
|
out << " mu: " << this->mu << "\n"; |
139 |
|
|
out << " weights: " << this->weights.transpose() << std::endl; |
140 |
|
|
|
141 |
|
|
return out.str(); |
142 |
|
|
} |
143 |
|
|
|
144 |
|
|
std::ostream &operator<<(std::ostream &out) { |
145 |
|
|
out << this->to_string(); |
146 |
|
|
return out; |
147 |
|
|
} |
148 |
|
|
|
149 |
|
|
bool operator==(const ContactPointSettings &rhs) { |
150 |
|
|
bool test = true; |
151 |
|
|
test &= this->frame_name == rhs.frame_name; |
152 |
|
|
test &= this->mu == rhs.mu; |
153 |
|
|
test &= this->weights == rhs.weights; |
154 |
|
|
return test; |
155 |
|
|
} |
156 |
|
|
|
157 |
|
|
bool operator!=(const ContactPointSettings &rhs) { return !(*this == rhs); } |
158 |
|
|
}; |
159 |
|
|
|
160 |
|
|
class ContactPoint { |
161 |
|
|
private: |
162 |
|
|
ContactPointSettings settings_; |
163 |
|
|
pinocchio::SE3 oMs_, cMo_; |
164 |
|
|
|
165 |
|
|
// matrices |
166 |
|
|
Eigen::Matrix<double, 1, 3> unilaterality_A_; |
167 |
|
|
Eigen::Matrix<double, 1, 1> unilaterality_b_; |
168 |
|
|
Eigen::Matrix<double, 4, 3> friction_A_; |
169 |
|
|
Eigen::Matrix<double, 4, 1> friction_b_; |
170 |
|
|
Eigen::Matrix<double, 3, 1> regularization_A_; |
171 |
|
|
Eigen::Matrix<double, 3, 1> regularization_b_; |
172 |
|
|
Eigen::Matrix<double, 6, 3> newton_euler_A_; |
173 |
|
|
size_t frameID_; |
174 |
|
|
Eigen::Matrix<double, 3, 1> contactForce_; |
175 |
|
|
|
176 |
|
|
public: |
177 |
|
|
ContactPoint(); |
178 |
|
|
ContactPoint(const ContactPointSettings &settings); |
179 |
|
|
void initialize(const ContactPointSettings &settings); |
180 |
|
|
|
181 |
|
|
// ~ContactPoint(); |
182 |
|
|
|
183 |
|
|
// setters |
184 |
|
|
void setMu(const double &mu); |
185 |
|
|
void setForceWeights(const Eigen::Vector3d &force_weights); |
186 |
|
|
void updateNewtonEuler(const Eigen::Vector3d &CoM, const pinocchio::SE3 &oMf); |
187 |
|
|
void setFrameID(const size_t frameID) { frameID_ = frameID; } |
188 |
|
|
void applyForce(const Eigen::Matrix<double, 3, 1> &force) { |
189 |
|
|
contactForce_ << force; |
190 |
|
|
} |
191 |
|
|
|
192 |
|
|
// getters |
193 |
|
|
const ContactPointSettings &getSettings() { return settings_; } |
194 |
|
|
const Eigen::Matrix<double, 6, 3> toWorldForces() { |
195 |
|
|
return oMs_.toActionMatrixInverse().transpose().block<6, 3>(0, 0); |
196 |
|
|
} |
197 |
|
|
const Eigen::Matrix<double, 6, 3> toCoMForces() { |
198 |
|
|
return oMs_.act(cMo_).toActionMatrixInverse().transpose().block<6, 3>(0, 0); |
199 |
|
|
} |
200 |
|
|
size_t uni_rows() const { return unilaterality_A_.rows(); } |
201 |
|
|
size_t fri_rows() const { return friction_A_.rows(); } |
202 |
|
|
size_t cols() const { return newton_euler_A_.cols(); } |
203 |
|
|
size_t getFrameID() const { return frameID_; } |
204 |
|
|
|
205 |
|
|
const Eigen::Matrix<double, 1, 3> &uni_A() { return unilaterality_A_; } |
206 |
|
|
const Eigen::Matrix<double, 1, 1> &uni_b() { return unilaterality_b_; } |
207 |
|
|
const Eigen::Matrix<double, 4, 3> &fri_A() { return friction_A_; } |
208 |
|
|
const Eigen::Matrix<double, 4, 1> &fri_b() { return friction_b_; } |
209 |
|
|
const Eigen::Matrix<double, 3, 1> ®_A() { return regularization_A_; } |
210 |
|
|
const Eigen::Matrix<double, 3, 1> ®_b() { return regularization_b_; } |
211 |
|
|
const Eigen::Matrix<double, 6, 3> &NE_A() { return newton_euler_A_; } |
212 |
|
|
|
213 |
|
|
const Eigen::Matrix<double, 3, 1> &appliedForce() { return contactForce_; } |
214 |
|
|
}; |
215 |
|
|
|
216 |
|
|
} // namespace dynacom |
217 |
|
|
|
218 |
|
|
#endif // DYNACOM_CONTACT_6D |