Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpForceTwistMatrix.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * Twist transformation matrix that allows to transform forces from one
32 * frame to an other.
33 */
34
42
43#include <assert.h>
44#include <sstream>
45
46#include <visp3/core/vpException.h>
47#include <visp3/core/vpForceTwistMatrix.h>
48
50
51const unsigned int vpForceTwistMatrix::constr_value_6 = 6;
52
59{
60 const int val_6 = 6;
61 for (int i = 0; i < val_6; ++i) {
62 for (int j = 0; j < val_6; ++j) {
63 rowPtrs[i][j] = M.rowPtrs[i][j];
64 }
65 }
66
67 return *this;
68}
69
74{
75 const unsigned int nparam = 6;
76 for (unsigned int i = 0; i < nparam; ++i) {
77 for (unsigned int j = 0; j < nparam; ++j) {
78 if (i == j) {
79 (*this)[i][j] = 1.0;
80 }
81 else {
82 (*this)[i][j] = 0.0;
83 }
84 }
85 }
86}
87
91vpForceTwistMatrix::vpForceTwistMatrix() : vpArray2D<double>(constr_value_6, constr_value_6) { eye(); }
92
100vpForceTwistMatrix::vpForceTwistMatrix(const vpForceTwistMatrix &F) : vpArray2D<double>(constr_value_6, constr_value_6) { *this = F; }
101
131vpForceTwistMatrix::vpForceTwistMatrix(const vpHomogeneousMatrix &M, bool full) : vpArray2D<double>(constr_value_6, constr_value_6)
132{
133 if (full) {
134 buildFrom(M);
135 }
136 else {
138 }
139}
140
161 : vpArray2D<double>(constr_value_6, constr_value_6)
162{
163 buildFrom(t, thetau);
164}
165
183vpForceTwistMatrix::vpForceTwistMatrix(const vpThetaUVector &thetau) : vpArray2D<double>(constr_value_6, constr_value_6) { buildFrom(thetau); }
184
205 : vpArray2D<double>(constr_value_6, constr_value_6)
206{
207 buildFrom(t, R);
208}
209
227vpForceTwistMatrix::vpForceTwistMatrix(const vpRotationMatrix &R) : vpArray2D<double>(constr_value_6, constr_value_6) { buildFrom(R); }
228
255vpForceTwistMatrix::vpForceTwistMatrix(double tx, double ty, double tz, double tux, double tuy, double tuz)
256 : vpArray2D<double>(constr_value_6, constr_value_6)
257{
258 vpTranslationVector T(tx, ty, tz);
259 vpThetaUVector tu(tux, tuy, tuz);
260 buildFrom(T, tu);
261}
262
286{
288 const unsigned int nparam = 6;
289 for (unsigned int i = 0; i < nparam; ++i) {
290 for (unsigned int j = 0; j < nparam; ++j) {
291 double s = 0;
292 for (unsigned int k = 0; k < nparam; ++k) {
293 s += rowPtrs[i][k] * F.rowPtrs[k][j];
294 }
295 Fout[i][j] = s;
296 }
297 }
298 return Fout;
299}
300
309{
310 const unsigned int nparam = 6;
311 if (nparam != M.getRows()) {
313 "Cannot multiply (6x6) force/torque twist matrix by a (%dx%d) matrix", M.getRows(), M.getCols()));
314 }
315
316 unsigned int m_col = M.getCols();
317 vpMatrix p(nparam, M.getCols());
318 for (unsigned int i = 0; i < nparam; ++i) {
319 for (unsigned int j = 0; j < m_col; ++j) {
320 double s = 0;
321 for (unsigned int k = 0; k < nparam; ++k) {
322 s += rowPtrs[i][k] * M[k][j];
323 }
324 p[i][j] = s;
325 }
326 }
327 return p;
328}
329
378{
379 const unsigned int val_6 = 6;
380 const unsigned int nparam = 6;
381 vpColVector Hout(nparam);
382
383 if (val_6 != H.getRows()) {
385 "Cannot multiply a (6x6) force/torque twist matrix by "
386 "a %d dimension column vector",
387 H.getRows()));
388 }
389
390 Hout = 0.0;
391
392 for (unsigned int i = 0; i < nparam; ++i) {
393 for (unsigned int j = 0; j < nparam; ++j) {
394 Hout[i] += rowPtrs[i][j] * H[j];
395 }
396 }
397
398 return Hout;
399}
400
420{
421 vpMatrix skewaR = t.skew(t) * R;
422
423 const unsigned int val_3 = 3;
424 const unsigned int index_3 = 3;
425 for (unsigned int i = 0; i < val_3; ++i) {
426 for (unsigned int j = 0; j < val_3; ++j) {
427 (*this)[i][j] = R[i][j];
428 (*this)[i + index_3][j + index_3] = R[i][j];
429 (*this)[i + index_3][j] = skewaR[i][j];
430 }
431 }
432 return *this;
433}
434
452{
453 const unsigned int index_3 = 3;
454 const unsigned int val_3 = 3;
455 for (unsigned int i = 0; i < val_3; ++i) {
456 for (unsigned int j = 0; j < val_3; ++j) {
457 (*this)[i][j] = R[i][j];
458 (*this)[i + index_3][j + index_3] = R[i][j];
459 (*this)[i + index_3][j] = 0;
460 }
461 }
462 return *this;
463}
464
485{
486 buildFrom(tv, vpRotationMatrix(thetau));
487 return *this;
488}
489
508{
510 return *this;
511}
512
541{
542 if (full) {
544 }
545 else {
547 }
548
549 return *this;
550}
551
571int vpForceTwistMatrix::print(std::ostream &s, unsigned int length, char const *intro) const
572{
573 typedef std::string::size_type size_type;
574
575 unsigned int m = getRows();
576 unsigned int n = getCols();
577
578 std::vector<std::string> values(m * n);
579 std::ostringstream oss;
580 std::ostringstream ossFixed;
581 std::ios_base::fmtflags original_flags = oss.flags();
582
583 // --comment: ossFixed less less std fixed
584 ossFixed.setf(std::ios::fixed, std::ios::floatfield);
585
586 size_type maxBefore = 0; // the length of the integral part
587 size_type maxAfter = 0; // number of decimals plus
588 // one place for the decimal point
589 for (unsigned int i = 0; i < m; ++i) {
590 for (unsigned int j = 0; j < n; ++j) {
591 oss.str("");
592 oss << (*this)[i][j];
593 if (oss.str().find("e") != std::string::npos) {
594 ossFixed.str("");
595 ossFixed << (*this)[i][j];
596 oss.str(ossFixed.str());
597 }
598
599 values[(i * n) + j] = oss.str();
600 size_type thislen = values[(i * n) + j].size();
601 size_type p = values[(i * n) + j].find('.');
602
603 if (p == std::string::npos) {
604 maxBefore = vpMath::maximum(maxBefore, thislen);
605 // maxAfter remains the same
606 }
607 else {
608 maxBefore = vpMath::maximum(maxBefore, p);
609 maxAfter = vpMath::maximum(maxAfter, thislen - p - 1);
610 }
611 }
612 }
613
614 size_type totalLength = length;
615 // increase totalLength according to maxBefore
616 totalLength = vpMath::maximum(totalLength, maxBefore);
617 // decrease maxAfter according to totalLength
618 maxAfter = std::min<size_type>(maxAfter, totalLength - maxBefore);
619 if (maxAfter == 1) {
620 maxAfter = 0;
621 }
622
623 // the following line is useful for debugging
624 // std::cerr <<totalLength <<" " <<maxBefore <<" " <<maxAfter <<"\n";
625
626 if (intro) {
627 s << intro;
628 }
629 s << "[" << m << "," << n << "]=\n";
630
631 for (unsigned int i = 0; i < m; ++i) {
632 s << " ";
633 for (unsigned int j = 0; j < n; ++j) {
634 size_type p = values[(i * n) + j].find('.');
635 s.setf(std::ios::right, std::ios::adjustfield);
636 s.width(static_cast<std::streamsize>(maxBefore));
637 s << values[(i * n) + j].substr(0, p).c_str();
638
639 if (maxAfter > 0) {
640 s.setf(std::ios::left, std::ios::adjustfield);
641 if (p != std::string::npos) {
642 s.width(static_cast<std::streamsize>(maxAfter));
643 s << values[(i * n) + j].substr(p, maxAfter).c_str();
644 }
645 else {
646 assert(maxAfter > 1);
647 s.width(static_cast<std::streamsize>(maxAfter));
648 s << ".0";
649 }
650 }
651
652 s << ' ';
653 }
654 s << std::endl;
655 }
656
657 s.flags(original_flags); // restore s to standard state
658
659 return static_cast<int>(maxBefore + maxAfter);
660}
661
662#if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
663
670void vpForceTwistMatrix::setIdentity() { eye(); }
671
672#endif //#if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
673#ifdef ENABLE_VISP_NAMESPACE
674 }
675#endif
unsigned int getCols() const
Definition vpArray2D.h:423
unsigned int size() const
Definition vpArray2D.h:435
vpArray2D< double > t() const
Definition vpArray2D.h:1273
unsigned int getRows() const
Definition vpArray2D.h:433
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ dimensionError
Bad dimension.
Definition vpException.h:71
vpForceTwistMatrix & buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
vpForceTwistMatrix & operator=(const vpForceTwistMatrix &H)
vpForceTwistMatrix operator*(const vpForceTwistMatrix &F) const
int print(std::ostream &s, unsigned int length, char const *intro=nullptr) const
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpRotationMatrix getRotationMatrix() const
vpTranslationVector getTranslationVector() const
static Type maximum(const Type &a, const Type &b)
Definition vpMath.h:257
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
Implementation of a rotation matrix and operations on such kind of matrices.
Implementation of a rotation vector as axis-angle minimal representation.
Class that consider the case of a translation vector.