GCC Code Coverage Report


Directory: ./
File: include/crocoddyl/multibody/friction-cone.hxx
Date: 2025-01-30 11:01:55
Exec Total Coverage
Lines: 93 149 62.4%
Branches: 61 170 35.9%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2019-2021, University of Edinburgh, University of Oxford
5 // Copyright note valid unless otherwise stated in individual files.
6 // All rights reserved.
7 ///////////////////////////////////////////////////////////////////////////////
8
9 #include <math.h>
10
11 #include <iostream>
12
13 namespace crocoddyl {
14
15 template <typename Scalar>
16 3 FrictionConeTpl<Scalar>::FrictionConeTpl()
17 3 : nf_(4),
18
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 A_(nf_ + 1, 3),
19
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 ub_(nf_ + 1),
20
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 lb_(nf_ + 1),
21
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 R_(Matrix3s::Identity()),
22 3 mu_(Scalar(0.7)),
23 3 inner_appr_(true),
24 3 min_nforce_(Scalar(0.)),
25 3 max_nforce_(std::numeric_limits<Scalar>::infinity()) {
26
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 A_.setZero();
27
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 ub_.setZero();
28
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 lb_.setZero();
29
30 // Update the inequality matrix and bounds
31
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 update();
32 3 }
33
34 template <typename Scalar>
35 922 FrictionConeTpl<Scalar>::FrictionConeTpl(const Matrix3s& R, const Scalar mu,
36 std::size_t nf, const bool inner_appr,
37 const Scalar min_nforce,
38 const Scalar max_nforce)
39 922 : nf_(nf),
40
1/2
✓ Branch 1 taken 922 times.
✗ Branch 2 not taken.
922 R_(R),
41 922 mu_(mu),
42 922 inner_appr_(inner_appr),
43 922 min_nforce_(min_nforce),
44
2/4
✓ Branch 2 taken 922 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 922 times.
✗ Branch 6 not taken.
922 max_nforce_(max_nforce) {
45
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 922 times.
922 if (nf_ % 2 != 0) {
46 nf_ = 4;
47 std::cerr << "Warning: nf has to be an even number, set to 4" << std::endl;
48 }
49
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 922 times.
922 if (mu < Scalar(0.)) {
50 mu_ = Scalar(1.);
51 std::cerr << "Warning: mu has to be a positive value, set to 1."
52 << std::endl;
53 }
54
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 922 times.
922 if (min_nforce < Scalar(0.)) {
55 min_nforce_ = Scalar(0.);
56 std::cerr << "Warning: min_nforce has to be a positive value, set to 0"
57 << std::endl;
58 }
59
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 922 times.
922 if (max_nforce < Scalar(0.)) {
60 max_nforce_ = std::numeric_limits<Scalar>::infinity();
61 std::cerr << "Warning: max_nforce has to be a positive value, set to "
62 "infinity value"
63 << std::endl;
64 }
65
2/4
✓ Branch 1 taken 922 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 922 times.
✗ Branch 5 not taken.
922 A_ = MatrixX3s::Zero(nf_ + 1, 3);
66
2/4
✓ Branch 1 taken 922 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 922 times.
✗ Branch 5 not taken.
922 ub_ = VectorXs::Zero(nf_ + 1);
67
2/4
✓ Branch 1 taken 922 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 922 times.
✗ Branch 5 not taken.
922 lb_ = VectorXs::Zero(nf_ + 1);
68
69 // Update the inequality matrix and bounds
70
1/2
✓ Branch 1 taken 922 times.
✗ Branch 2 not taken.
922 update();
71 922 }
72
73 template <typename Scalar>
74 FrictionConeTpl<Scalar>::FrictionConeTpl(const Vector3s& nsurf, const Scalar mu,
75 std::size_t nf, const bool inner_appr,
76 const Scalar min_nforce,
77 const Scalar max_nforce)
78 : nf_(nf),
79 R_(Quaternions::FromTwoVectors(nsurf, Vector3s::UnitZ())
80 .toRotationMatrix()),
81 mu_(mu),
82 inner_appr_(inner_appr),
83 min_nforce_(min_nforce),
84 max_nforce_(max_nforce) {
85 if (nf_ % 2 != 0) {
86 nf_ = 4;
87 std::cerr << "Warning: nf has to be an even number, set to 4" << std::endl;
88 }
89 Eigen::Vector3d normal = nsurf;
90 if (!nsurf.isUnitary()) {
91 normal /= nsurf.norm();
92 std::cerr
93 << "Warning: normal is not an unitary vector, then we normalized it"
94 << std::endl;
95 }
96 if (mu < Scalar(0.)) {
97 mu_ = Scalar(1.);
98 std::cerr << "Warning: mu has to be a positive value, set to 1."
99 << std::endl;
100 }
101 if (min_nforce < Scalar(0.)) {
102 min_nforce_ = Scalar(0.);
103 std::cerr << "Warning: min_nforce has to be a positive value, set to 0"
104 << std::endl;
105 }
106 if (max_nforce < Scalar(0.)) {
107 max_nforce_ = std::numeric_limits<Scalar>::infinity();
108 std::cerr << "Warning: max_nforce has to be a positive value, set to "
109 "infinity value"
110 << std::endl;
111 }
112 A_ = MatrixX3s::Zero(nf_ + 1, 3);
113 ub_ = VectorXs::Zero(nf_ + 1);
114 lb_ = VectorXs::Zero(nf_ + 1);
115 R_ =
116 Quaternions::FromTwoVectors(normal, Vector3s::UnitZ()).toRotationMatrix();
117
118 // Update the inequality matrix and bounds
119 update();
120 }
121
122 template <typename Scalar>
123 888 FrictionConeTpl<Scalar>::FrictionConeTpl(const FrictionConeTpl<Scalar>& cone)
124 888 : nf_(cone.get_nf()),
125 888 A_(cone.get_A()),
126
1/2
✓ Branch 2 taken 888 times.
✗ Branch 3 not taken.
888 ub_(cone.get_ub()),
127
1/2
✓ Branch 2 taken 888 times.
✗ Branch 3 not taken.
888 lb_(cone.get_lb()),
128
1/2
✓ Branch 2 taken 888 times.
✗ Branch 3 not taken.
888 R_(cone.get_R()),
129 888 mu_(cone.get_mu()),
130 888 inner_appr_(cone.get_inner_appr()),
131 888 min_nforce_(cone.get_min_nforce()),
132 888 max_nforce_(cone.get_max_nforce()) {}
133
134 template <typename Scalar>
135 1813 FrictionConeTpl<Scalar>::~FrictionConeTpl() {}
136
137 template <typename Scalar>
138 925 void FrictionConeTpl<Scalar>::update() {
139 // Initialize the matrix and bounds
140
1/2
✓ Branch 1 taken 925 times.
✗ Branch 2 not taken.
925 A_.setZero();
141
1/2
✓ Branch 1 taken 925 times.
✗ Branch 2 not taken.
925 ub_.setZero();
142
1/2
✓ Branch 1 taken 925 times.
✗ Branch 2 not taken.
925 lb_.setOnes();
143
1/2
✓ Branch 2 taken 925 times.
✗ Branch 3 not taken.
925 lb_ *= -std::numeric_limits<Scalar>::infinity();
144
145 // Compute the mu given the type of friction cone approximation
146 925 Scalar mu = mu_;
147 925 const Scalar theta = Scalar(2) * M_PI / static_cast<Scalar>(nf_);
148
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 823 times.
925 if (inner_appr_) {
149 102 mu *= cos(theta / Scalar(2.));
150 }
151
152 // Update the inequality matrix and the bounds
153 // This matrix is defined as
154 // [ 1 0 -mu;
155 // -1 0 -mu;
156 // 0 1 -mu;
157 // 0 -1 -mu;
158 // 0 0 1]
159 Scalar theta_i;
160
1/2
✓ Branch 1 taken 925 times.
✗ Branch 2 not taken.
925 Vector3s tsurf_i;
161
2/2
✓ Branch 0 taken 1942 times.
✓ Branch 1 taken 925 times.
2867 for (std::size_t i = 0; i < nf_ / 2; ++i) {
162 1942 theta_i = theta * static_cast<Scalar>(i);
163
3/6
✓ Branch 1 taken 1942 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1942 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1942 times.
✗ Branch 8 not taken.
1942 tsurf_i << cos(theta_i), sin(theta_i), Scalar(0.);
164
7/14
✓ Branch 1 taken 1942 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1942 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1942 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1942 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1942 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1942 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1942 times.
✗ Branch 20 not taken.
1942 A_.row(2 * i) =
165
1/2
✓ Branch 1 taken 1942 times.
✗ Branch 2 not taken.
1942 (-mu * Vector3s::UnitZ() + tsurf_i).transpose() * R_.transpose();
166
7/14
✓ Branch 1 taken 1942 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1942 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1942 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1942 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1942 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1942 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1942 times.
✗ Branch 20 not taken.
1942 A_.row(2 * i + 1) =
167
1/2
✓ Branch 1 taken 1942 times.
✗ Branch 2 not taken.
3884 (-mu * Vector3s::UnitZ() - tsurf_i).transpose() * R_.transpose();
168 }
169
4/8
✓ Branch 1 taken 925 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 925 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 925 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 925 times.
✗ Branch 11 not taken.
925 A_.row(nf_) = R_.col(2).transpose();
170
1/2
✓ Branch 1 taken 925 times.
✗ Branch 2 not taken.
925 lb_(nf_) = min_nforce_;
171
1/2
✓ Branch 1 taken 925 times.
✗ Branch 2 not taken.
925 ub_(nf_) = max_nforce_;
172 925 }
173
174 template <typename Scalar>
175 void FrictionConeTpl<Scalar>::update(const Vector3s& normal, const Scalar mu,
176 const bool inner_appr,
177 const Scalar min_nforce,
178 const Scalar max_nforce) {
179 Eigen::Vector3d nsurf = normal;
180 // Sanity checks
181 if (!nsurf.isUnitary()) {
182 nsurf /= normal.norm();
183 std::cerr
184 << "Warning: normal is not an unitary vector, then we normalized it"
185 << std::endl;
186 }
187 R_ = Quaternions::FromTwoVectors(nsurf, Vector3s::UnitZ()).toRotationMatrix();
188 set_mu(mu);
189 set_inner_appr(inner_appr);
190 set_min_nforce(min_nforce);
191 set_max_nforce(max_nforce);
192
193 // Update the inequality matrix and bounds
194 update();
195 }
196
197 template <typename Scalar>
198 96813 const typename MathBaseTpl<Scalar>::MatrixX3s& FrictionConeTpl<Scalar>::get_A()
199 const {
200 96813 return A_;
201 }
202
203 template <typename Scalar>
204 1914 const typename MathBaseTpl<Scalar>::VectorXs& FrictionConeTpl<Scalar>::get_ub()
205 const {
206 1914 return ub_;
207 }
208
209 template <typename Scalar>
210 1850 const typename MathBaseTpl<Scalar>::VectorXs& FrictionConeTpl<Scalar>::get_lb()
211 const {
212 1850 return lb_;
213 }
214
215 template <typename Scalar>
216 897 const typename MathBaseTpl<Scalar>::Matrix3s& FrictionConeTpl<Scalar>::get_R()
217 const {
218 897 return R_;
219 }
220
221 template <typename Scalar>
222 typename MathBaseTpl<Scalar>::Vector3s FrictionConeTpl<Scalar>::get_nsurf() {
223 return R_.row(2).transpose();
224 }
225
226 template <typename Scalar>
227 897 const Scalar FrictionConeTpl<Scalar>::get_mu() const {
228 897 return mu_;
229 }
230
231 template <typename Scalar>
232 1779 std::size_t FrictionConeTpl<Scalar>::get_nf() const {
233 1779 return nf_;
234 }
235
236 template <typename Scalar>
237 896 bool FrictionConeTpl<Scalar>::get_inner_appr() const {
238 896 return inner_appr_;
239 }
240
241 template <typename Scalar>
242 894 const Scalar FrictionConeTpl<Scalar>::get_min_nforce() const {
243 894 return min_nforce_;
244 }
245
246 template <typename Scalar>
247 894 const Scalar FrictionConeTpl<Scalar>::get_max_nforce() const {
248 894 return max_nforce_;
249 }
250
251 template <typename Scalar>
252 void FrictionConeTpl<Scalar>::set_R(const Matrix3s& R) {
253 R_ = R;
254 }
255
256 template <typename Scalar>
257 void FrictionConeTpl<Scalar>::set_nsurf(const Vector3s& nsurf) {
258 Eigen::Vector3d normal = nsurf;
259 // Sanity checks
260 if (!nsurf.isUnitary()) {
261 normal /= nsurf.norm();
262 std::cerr
263 << "Warning: normal is not an unitary vector, then we normalized it"
264 << std::endl;
265 }
266 R_ =
267 Quaternions::FromTwoVectors(normal, Vector3s::UnitZ()).toRotationMatrix();
268 }
269
270 template <typename Scalar>
271 void FrictionConeTpl<Scalar>::set_mu(const Scalar mu) {
272 if (mu < Scalar(0.)) {
273 mu_ = Scalar(1.);
274 std::cerr << "Warning: mu has to be a positive value, set to 1."
275 << std::endl;
276 }
277 mu_ = mu;
278 }
279
280 template <typename Scalar>
281 void FrictionConeTpl<Scalar>::set_inner_appr(const bool inner_appr) {
282 inner_appr_ = inner_appr;
283 }
284
285 template <typename Scalar>
286 void FrictionConeTpl<Scalar>::set_min_nforce(const Scalar min_nforce) {
287 if (min_nforce < Scalar(0.)) {
288 min_nforce_ = Scalar(0.);
289 std::cerr << "Warning: min_nforce has to be a positive value, set to 0"
290 << std::endl;
291 }
292 min_nforce_ = min_nforce;
293 }
294
295 template <typename Scalar>
296 void FrictionConeTpl<Scalar>::set_max_nforce(const Scalar max_nforce) {
297 if (max_nforce < Scalar(0.)) {
298 max_nforce_ = std::numeric_limits<Scalar>::infinity();
299 std::cerr << "Warning: max_nforce has to be a positive value, set to "
300 "infinity value"
301 << std::endl;
302 }
303 max_nforce_ = max_nforce;
304 }
305
306 template <typename Scalar>
307 2 FrictionConeTpl<Scalar>& FrictionConeTpl<Scalar>::operator=(
308 const FrictionConeTpl<Scalar>& other) {
309
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (this != &other) {
310 2 nf_ = other.get_nf();
311 2 A_ = other.get_A();
312 2 ub_ = other.get_ub();
313 2 lb_ = other.get_lb();
314 2 R_ = other.get_R();
315 2 mu_ = other.get_mu();
316 2 inner_appr_ = other.get_inner_appr();
317 2 min_nforce_ = other.get_min_nforce();
318 2 max_nforce_ = other.get_max_nforce();
319 }
320 2 return *this;
321 }
322
323 template <typename Scalar>
324 std::ostream& operator<<(std::ostream& os, const FrictionConeTpl<Scalar>& X) {
325 os << " R: " << X.get_R() << std::endl;
326 os << " mu: " << X.get_mu() << std::endl;
327 os << " nf: " << X.get_nf() << std::endl;
328 os << "inner_appr: ";
329 if (X.get_inner_appr()) {
330 os << "true" << std::endl;
331 } else {
332 os << "false" << std::endl;
333 }
334 os << " min_force: " << X.get_min_nforce() << std::endl;
335 os << " max_force: " << X.get_max_nforce() << std::endl;
336 return os;
337 }
338
339 } // namespace crocoddyl
340