Gazebo Math

API Reference

8.1.0
Matrix6.hh
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022 Open Source Robotics Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16*/
17#ifndef GZ_MATH_MATRIX6_HH_
18#define GZ_MATH_MATRIX6_HH_
19
20#include <utility>
21#include <gz/math/config.hh>
22#include <gz/math/Helpers.hh>
23#include <gz/math/Matrix3.hh>
24
25namespace gz::math
26{
27 // Inline bracket to help doxygen filtering.
28 inline namespace GZ_MATH_VERSION_NAMESPACE {
29 //
32 template<typename T>
33 class Matrix6
34 {
36 public: enum Matrix6Corner
37 {
40 TOP_LEFT = 0,
41
44 TOP_RIGHT = 1,
45
48 BOTTOM_LEFT = 2,
49
52 BOTTOM_RIGHT = 3
53 };
54
56 public: static constexpr std::size_t MatrixSize{6};
57
59 public: static const Matrix6<T> &Identity;
60
62 public: static const Matrix6<T> &Zero;
63
65 public: Matrix6()
66 {
67 memset(this->data, 0, sizeof(this->data[0][0])*MatrixSize*MatrixSize);
68 }
69
107 public: constexpr Matrix6(T _v00, T _v01, T _v02, T _v03, T _v04, T _v05,
108 T _v10, T _v11, T _v12, T _v13, T _v14, T _v15,
109 T _v20, T _v21, T _v22, T _v23, T _v24, T _v25,
110 T _v30, T _v31, T _v32, T _v33, T _v34, T _v35,
111 T _v40, T _v41, T _v42, T _v43, T _v44, T _v45,
112 T _v50, T _v51, T _v52, T _v53, T _v54, T _v55)
113 : data{{_v00, _v01, _v02, _v03, _v04, _v05},
114 {_v10, _v11, _v12, _v13, _v14, _v15},
115 {_v20, _v21, _v22, _v23, _v24, _v25},
116 {_v30, _v31, _v32, _v33, _v34, _v35},
117 {_v40, _v41, _v42, _v43, _v44, _v45},
118 {_v50, _v51, _v52, _v53, _v54, _v55}}
119 {
120 }
121
127 public: bool SetValue(size_t _row, size_t _col, T _v)
128 {
129 if (_row < MatrixSize && _col < MatrixSize)
130 {
131 this->data[_row][_col] = _v;
132 return true;
133 }
134 return false;
135 }
136
174 public: void Set(
175 T _v00, T _v01, T _v02, T _v03, T _v04, T _v05,
176 T _v10, T _v11, T _v12, T _v13, T _v14, T _v15,
177 T _v20, T _v21, T _v22, T _v23, T _v24, T _v25,
178 T _v30, T _v31, T _v32, T _v33, T _v34, T _v35,
179 T _v40, T _v41, T _v42, T _v43, T _v44, T _v45,
180 T _v50, T _v51, T _v52, T _v53, T _v54, T _v55)
181 {
182 this->data[0][0] = _v00;
183 this->data[0][1] = _v01;
184 this->data[0][2] = _v02;
185 this->data[0][3] = _v03;
186 this->data[0][4] = _v04;
187 this->data[0][5] = _v05;
188
189 this->data[1][0] = _v10;
190 this->data[1][1] = _v11;
191 this->data[1][2] = _v12;
192 this->data[1][3] = _v13;
193 this->data[1][4] = _v14;
194 this->data[1][5] = _v15;
195
196 this->data[2][0] = _v20;
197 this->data[2][1] = _v21;
198 this->data[2][2] = _v22;
199 this->data[2][3] = _v23;
200 this->data[2][4] = _v24;
201 this->data[2][5] = _v25;
202
203 this->data[3][0] = _v30;
204 this->data[3][1] = _v31;
205 this->data[3][2] = _v32;
206 this->data[3][3] = _v33;
207 this->data[3][4] = _v34;
208 this->data[3][5] = _v35;
209
210 this->data[4][0] = _v40;
211 this->data[4][1] = _v41;
212 this->data[4][2] = _v42;
213 this->data[4][3] = _v43;
214 this->data[4][4] = _v44;
215 this->data[4][5] = _v45;
216
217 this->data[5][0] = _v50;
218 this->data[5][1] = _v51;
219 this->data[5][2] = _v52;
220 this->data[5][3] = _v53;
221 this->data[5][4] = _v54;
222 this->data[5][5] = _v55;
223 }
224
226 public: void Transpose()
227 {
228 std::swap(this->data[0][1], this->data[1][0]);
229 std::swap(this->data[0][2], this->data[2][0]);
230 std::swap(this->data[0][3], this->data[3][0]);
231 std::swap(this->data[0][4], this->data[4][0]);
232 std::swap(this->data[0][5], this->data[5][0]);
233 std::swap(this->data[1][2], this->data[2][1]);
234 std::swap(this->data[1][3], this->data[3][1]);
235 std::swap(this->data[1][4], this->data[4][1]);
236 std::swap(this->data[1][5], this->data[5][1]);
237 std::swap(this->data[2][3], this->data[3][2]);
238 std::swap(this->data[2][4], this->data[4][2]);
239 std::swap(this->data[2][5], this->data[5][2]);
240 std::swap(this->data[3][4], this->data[4][3]);
241 std::swap(this->data[3][5], this->data[5][3]);
242 std::swap(this->data[4][5], this->data[5][4]);
243 }
244
247 public: Matrix6<T> Transposed() const
248 {
249 return Matrix6<T>(
250 this->data[0][0],
251 this->data[1][0],
252 this->data[2][0],
253 this->data[3][0],
254 this->data[4][0],
255 this->data[5][0],
256
257 this->data[0][1],
258 this->data[1][1],
259 this->data[2][1],
260 this->data[3][1],
261 this->data[4][1],
262 this->data[5][1],
263
264 this->data[0][2],
265 this->data[1][2],
266 this->data[2][2],
267 this->data[3][2],
268 this->data[4][2],
269 this->data[5][2],
270
271 this->data[0][3],
272 this->data[1][3],
273 this->data[2][3],
274 this->data[3][3],
275 this->data[4][3],
276 this->data[5][3],
277
278 this->data[0][4],
279 this->data[1][4],
280 this->data[2][4],
281 this->data[3][4],
282 this->data[4][4],
283 this->data[5][4],
284
285 this->data[0][5],
286 this->data[1][5],
287 this->data[2][5],
288 this->data[3][5],
289 this->data[4][5],
290 this->data[5][5]);
291 }
292
298 {
299 (*this) = (*this) * _m2;
300 return *this;
301 }
302
306 public: Matrix6<T> operator*(const Matrix6<T> &_m2) const
307 {
308 auto el = [&](size_t _row, size_t _col) -> T
309 {
310 T result = static_cast<T>(0);
311 for (size_t i = 0; i < MatrixSize; ++i)
312 result += this->data[_row][i] * _m2(i, _col);
313 return result;
314 };
315 return Matrix6<T>(
316 el(0, 0), el(0, 1), el(0, 2), el(0, 3), el(0, 4), el(0, 5),
317 el(1, 0), el(1, 1), el(1, 2), el(1, 3), el(1, 4), el(1, 5),
318 el(2, 0), el(2, 1), el(2, 2), el(2, 3), el(2, 4), el(2, 5),
319 el(3, 0), el(3, 1), el(3, 2), el(3, 3), el(3, 4), el(3, 5),
320 el(4, 0), el(4, 1), el(4, 2), el(4, 3), el(4, 4), el(4, 5),
321 el(5, 0), el(5, 1), el(5, 2), el(5, 3), el(5, 4), el(5, 5));
322 }
323
329 {
330 (*this) = (*this) + _m2;
331 return *this;
332 }
333
337 public: Matrix6<T> operator+(const Matrix6<T> &_m2) const
338 {
339 auto el = [&](size_t _row, size_t _col) -> T
340 {
341 return this->data[_row][_col] + _m2(_row, _col);
342 };
343 return Matrix6<T>(
344 el(0, 0), el(0, 1), el(0, 2), el(0, 3), el(0, 4), el(0, 5),
345 el(1, 0), el(1, 1), el(1, 2), el(1, 3), el(1, 4), el(1, 5),
346 el(2, 0), el(2, 1), el(2, 2), el(2, 3), el(2, 4), el(2, 5),
347 el(3, 0), el(3, 1), el(3, 2), el(3, 3), el(3, 4), el(3, 5),
348 el(4, 0), el(4, 1), el(4, 2), el(4, 3), el(4, 4), el(4, 5),
349 el(5, 0), el(5, 1), el(5, 2), el(5, 3), el(5, 4), el(5, 5));
350 }
351
358 public: inline const T &operator()(const size_t _row,
359 const size_t _col) const
360 {
361 return this->data[clamp(_row, GZ_ZERO_SIZE_T, GZ_FIVE_SIZE_T)][
363 }
364
372 public: inline T &operator()(const size_t _row, const size_t _col)
373 {
374 return this->data[clamp(_row, GZ_ZERO_SIZE_T, GZ_FIVE_SIZE_T)]
376 }
377
384 {
385 size_t row = 0;
386 size_t col = 0;
388 {
389 row = 3;
390 }
392 {
393 col = 3;
394 }
395 return {this->data[row + 0][col + 0],
396 this->data[row + 0][col + 1],
397 this->data[row + 0][col + 2],
398 this->data[row + 1][col + 0],
399 this->data[row + 1][col + 1],
400 this->data[row + 1][col + 2],
401 this->data[row + 2][col + 0],
402 this->data[row + 2][col + 1],
403 this->data[row + 2][col + 2]};
404 }
405
412 {
413 size_t row = 0;
414 size_t col = 0;
416 {
417 row = 3;
418 }
420 {
421 col = 3;
422 }
423 for (size_t r = 0; r < 3; ++r)
424 {
425 for (size_t c = 0; c < 3; ++c)
426 {
427 this->data[row + r][col + c] = _mat(r, c);
428 }
429 }
430 }
431
437 public: bool Equal(const Matrix6 &_m, const T &_tol) const
438 {
439 return equal<T>(this->data[0][0], _m(0, 0), _tol)
440 && equal<T>(this->data[0][1], _m(0, 1), _tol)
441 && equal<T>(this->data[0][2], _m(0, 2), _tol)
442 && equal<T>(this->data[0][3], _m(0, 3), _tol)
443 && equal<T>(this->data[0][4], _m(0, 4), _tol)
444 && equal<T>(this->data[0][5], _m(0, 5), _tol)
445 && equal<T>(this->data[1][0], _m(1, 0), _tol)
446 && equal<T>(this->data[1][1], _m(1, 1), _tol)
447 && equal<T>(this->data[1][2], _m(1, 2), _tol)
448 && equal<T>(this->data[1][3], _m(1, 3), _tol)
449 && equal<T>(this->data[1][4], _m(1, 4), _tol)
450 && equal<T>(this->data[1][5], _m(1, 5), _tol)
451 && equal<T>(this->data[2][0], _m(2, 0), _tol)
452 && equal<T>(this->data[2][1], _m(2, 1), _tol)
453 && equal<T>(this->data[2][2], _m(2, 2), _tol)
454 && equal<T>(this->data[2][3], _m(2, 3), _tol)
455 && equal<T>(this->data[2][4], _m(2, 4), _tol)
456 && equal<T>(this->data[2][5], _m(2, 5), _tol)
457 && equal<T>(this->data[3][0], _m(3, 0), _tol)
458 && equal<T>(this->data[3][1], _m(3, 1), _tol)
459 && equal<T>(this->data[3][2], _m(3, 2), _tol)
460 && equal<T>(this->data[3][3], _m(3, 3), _tol)
461 && equal<T>(this->data[3][4], _m(3, 4), _tol)
462 && equal<T>(this->data[3][5], _m(3, 5), _tol)
463 && equal<T>(this->data[4][0], _m(4, 0), _tol)
464 && equal<T>(this->data[4][1], _m(4, 1), _tol)
465 && equal<T>(this->data[4][2], _m(4, 2), _tol)
466 && equal<T>(this->data[4][3], _m(4, 3), _tol)
467 && equal<T>(this->data[4][4], _m(4, 4), _tol)
468 && equal<T>(this->data[4][5], _m(4, 5), _tol)
469 && equal<T>(this->data[5][0], _m(5, 0), _tol)
470 && equal<T>(this->data[5][1], _m(5, 1), _tol)
471 && equal<T>(this->data[5][2], _m(5, 2), _tol)
472 && equal<T>(this->data[5][3], _m(5, 3), _tol)
473 && equal<T>(this->data[5][4], _m(5, 4), _tol)
474 && equal<T>(this->data[5][5], _m(5, 5), _tol);
475 }
476
481 public: bool operator==(const Matrix6<T> &_m) const
482 {
483 return this->Equal(_m, static_cast<T>(1e-6));
484 }
485
489 public: bool operator!=(const Matrix6<T> &_m) const
490 {
491 return !(*this == _m);
492 }
493
498 public: friend std::ostream &operator<<(
500 {
501 for (auto i : {0, 1, 2, 3, 4, 5})
502 {
503 for (auto j : {0, 1, 2, 3, 4, 5})
504 {
505 if (!(i == 0 && j == 0))
506 _out << " ";
507
509 }
510 }
511
512 return _out;
513 }
514
519 public: friend std::istream &operator>>(
521 {
522 // Skip white spaces
523 _in.setf(std::ios_base::skipws);
524 T d[36];
525 _in >> d[0] >> d[1] >> d[2] >> d[3] >> d[4] >> d[5]
526 >> d[6] >> d[7] >> d[8] >> d[9] >> d[10] >> d[11]
527 >> d[12] >> d[13] >> d[14] >> d[15] >> d[16] >> d[17]
528 >> d[18] >> d[19] >> d[20] >> d[21] >> d[22] >> d[23]
529 >> d[24] >> d[25] >> d[26] >> d[27] >> d[28] >> d[29]
530 >> d[30] >> d[31] >> d[32] >> d[33] >> d[34] >> d[35];
531
532 if (!_in.fail())
533 {
534 _m.Set(d[0], d[1], d[2], d[3], d[4], d[5],
535 d[6], d[7], d[8], d[9], d[10], d[11],
536 d[12], d[13], d[14], d[15], d[16], d[17],
537 d[18], d[19], d[20], d[21], d[22], d[23],
538 d[24], d[25], d[26], d[27], d[28], d[29],
539 d[30], d[31], d[32], d[33], d[34], d[35]);
540 }
541 return _in;
542 }
543
545 private: T data[MatrixSize][MatrixSize];
546 };
547
548 namespace detail {
549
550 template<typename T>
551 constexpr Matrix6<T> gMatrix6Identity(
552 1, 0, 0, 0, 0, 0,
553 0, 1, 0, 0, 0, 0,
554 0, 0, 1, 0, 0, 0,
555 0, 0, 0, 1, 0, 0,
556 0, 0, 0, 0, 1, 0,
557 0, 0, 0, 0, 0, 1);
558
559 template<typename T>
560 constexpr Matrix6<T> gMatrix6Zero(
561 0, 0, 0, 0, 0, 0,
562 0, 0, 0, 0, 0, 0,
563 0, 0, 0, 0, 0, 0,
564 0, 0, 0, 0, 0, 0,
565 0, 0, 0, 0, 0, 0,
566 0, 0, 0, 0, 0, 0);
567
568 } // namespace detail
569
570 template<typename T>
571 const Matrix6<T> &Matrix6<T>::Identity = detail::gMatrix6Identity<T>;
572
573 template<typename T>
574 const Matrix6<T> &Matrix6<T>::Zero = detail::gMatrix6Zero<T>;
575
579 } // namespace GZ_MATH_VERSION_NAMESPACE
580} // namespace gz::math
581#endif // GZ_MATH_MATRIX6_HH_