Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
vpForceTwistMatrix.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 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 *****************************************************************************/
35 
44 #include <assert.h>
45 #include <sstream>
46 
47 #include <visp3/core/vpException.h>
48 #include <visp3/core/vpForceTwistMatrix.h>
49 
51 
58 {
59  for (int i = 0; i < 6; ++i) {
60  for (int j = 0; j < 6; ++j) {
61  rowPtrs[i][j] = M.rowPtrs[i][j];
62  }
63  }
64 
65  return *this;
66 }
67 
72 {
73  const unsigned int nparam = 6;
74  for (unsigned int i = 0; i < nparam; ++i) {
75  for (unsigned int j = 0; j < nparam; ++j) {
76  if (i == j) {
77  (*this)[i][j] = 1.0;
78  }
79  else {
80  (*this)[i][j] = 0.0;
81  }
82  }
83  }
84 }
85 
90 
99 
130 {
131  if (full) {
132  build(M);
133  }
134  else {
136  }
137 }
138 
159  : vpArray2D<double>(6, 6)
160 {
161  build(t, thetau);
162 }
163 
181 vpForceTwistMatrix::vpForceTwistMatrix(const vpThetaUVector &thetau) : vpArray2D<double>(6, 6) { build(thetau); }
182 
203  : vpArray2D<double>(6, 6)
204 {
205  build(t, R);
206 }
207 
226 
247 vpForceTwistMatrix::vpForceTwistMatrix(double tx, double ty, double tz, double tux, double tuy, double tuz)
248  : vpArray2D<double>(6, 6)
249 {
250  vpTranslationVector T(tx, ty, tz);
251  vpThetaUVector tu(tux, tuy, tuz);
252  build(T, tu);
253 }
254 
278 {
279  vpForceTwistMatrix Fout;
280  const unsigned int nparam = 6;
281  for (unsigned int i = 0; i < nparam; ++i) {
282  for (unsigned int j = 0; j < nparam; ++j) {
283  double s = 0;
284  for (unsigned int k = 0; k < nparam; ++k) {
285  s += rowPtrs[i][k] * F.rowPtrs[k][j];
286  }
287  Fout[i][j] = s;
288  }
289  }
290  return Fout;
291 }
292 
301 {
302  const unsigned int nparam = 6;
303  if (nparam != M.getRows()) {
305  "Cannot multiply (6x6) force/torque twist matrix by a (%dx%d) matrix", M.getRows(), M.getCols()));
306  }
307 
308  unsigned int m_col = M.getCols();
309  vpMatrix p(nparam, M.getCols());
310  for (unsigned int i = 0; i < nparam; ++i) {
311  for (unsigned int j = 0; j < m_col; ++j) {
312  double s = 0;
313  for (unsigned int k = 0; k < nparam; ++k) {
314  s += rowPtrs[i][k] * M[k][j];
315  }
316  p[i][j] = s;
317  }
318  }
319  return p;
320 }
321 
370 {
371  const unsigned int nparam = 6;
372  vpColVector Hout(nparam);
373 
374  if (6 != H.getRows()) {
376  "Cannot multiply a (6x6) force/torque twist matrix by "
377  "a %d dimension column vector",
378  H.getRows()));
379  }
380 
381  Hout = 0.0;
382 
383  for (unsigned int i = 0; i < nparam; ++i) {
384  for (unsigned int j = 0; j < nparam; ++j) {
385  Hout[i] += rowPtrs[i][j] * H[j];
386  }
387  }
388 
389  return Hout;
390 }
391 
392 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
413 {
414  build(t, R);
415  return *this;
416 }
417 
436 {
437  build(R);
438  return *this;
439 }
440 
462 {
463  build(tv, vpRotationMatrix(thetau));
464  return *this;
465 }
466 
486 {
487  build(vpRotationMatrix(thetau));
488  return *this;
489 }
490 
520 {
521  if (full) {
523  }
524  else {
526  }
527 
528  return *this;
529 }
530 #endif
531 
551 {
552  vpMatrix skewaR = t.skew(t) * R;
553 
554  const unsigned int val_3 = 3;
555  for (unsigned int i = 0; i < val_3; ++i) {
556  for (unsigned int j = 0; j < val_3; ++j) {
557  (*this)[i][j] = R[i][j];
558  (*this)[i + 3][j + 3] = R[i][j];
559  (*this)[i + 3][j] = skewaR[i][j];
560  }
561  }
562  return *this;
563 }
564 
582 {
583  const unsigned int val_3 = 3;
584  for (unsigned int i = 0; i < val_3; ++i) {
585  for (unsigned int j = 0; j < val_3; ++j) {
586  (*this)[i][j] = R[i][j];
587  (*this)[i + 3][j + 3] = R[i][j];
588  (*this)[i + 3][j] = 0;
589  }
590  }
591  return *this;
592 }
593 
614 {
615  build(tv, vpRotationMatrix(thetau));
616  return *this;
617 }
618 
637 {
638  build(vpRotationMatrix(thetau));
639  return *this;
640 }
641 
670 {
671  if (full) {
673  }
674  else {
676  }
677 
678  return *this;
679 }
680 
700 int vpForceTwistMatrix::print(std::ostream &s, unsigned int length, char const *intro) const
701 {
702  typedef std::string::size_type size_type;
703 
704  unsigned int m = getRows();
705  unsigned int n = getCols();
706 
707  std::vector<std::string> values(m * n);
708  std::ostringstream oss;
709  std::ostringstream ossFixed;
710  std::ios_base::fmtflags original_flags = oss.flags();
711 
712  // --comment: ossFixed less less std fixed
713  ossFixed.setf(std::ios::fixed, std::ios::floatfield);
714 
715  size_type maxBefore = 0; // the length of the integral part
716  size_type maxAfter = 0; // number of decimals plus
717  // one place for the decimal point
718  for (unsigned int i = 0; i < m; ++i) {
719  for (unsigned int j = 0; j < n; ++j) {
720  oss.str("");
721  oss << (*this)[i][j];
722  if (oss.str().find("e") != std::string::npos) {
723  ossFixed.str("");
724  ossFixed << (*this)[i][j];
725  oss.str(ossFixed.str());
726  }
727 
728  values[(i * n) + j] = oss.str();
729  size_type thislen = values[(i * n) + j].size();
730  size_type p = values[(i * n) + j].find('.');
731 
732  if (p == std::string::npos) {
733  maxBefore = vpMath::maximum(maxBefore, thislen);
734  // maxAfter remains the same
735  }
736  else {
737  maxBefore = vpMath::maximum(maxBefore, p);
738  maxAfter = vpMath::maximum(maxAfter, thislen - p - 1);
739  }
740  }
741  }
742 
743  size_type totalLength = length;
744  // increase totalLength according to maxBefore
745  totalLength = vpMath::maximum(totalLength, maxBefore);
746  // decrease maxAfter according to totalLength
747  maxAfter = std::min<size_type>(maxAfter, totalLength - maxBefore);
748  if (maxAfter == 1) {
749  maxAfter = 0;
750  }
751 
752  // the following line is useful for debugging
753  // std::cerr <<totalLength <<" " <<maxBefore <<" " <<maxAfter <<"\n";
754 
755  if (intro) {
756  s << intro;
757  }
758  s << "[" << m << "," << n << "]=\n";
759 
760  for (unsigned int i = 0; i < m; ++i) {
761  s << " ";
762  for (unsigned int j = 0; j < n; ++j) {
763  size_type p = values[(i * n) + j].find('.');
764  s.setf(std::ios::right, std::ios::adjustfield);
765  s.width(static_cast<std::streamsize>(maxBefore));
766  s << values[(i * n) + j].substr(0, p).c_str();
767 
768  if (maxAfter > 0) {
769  s.setf(std::ios::left, std::ios::adjustfield);
770  if (p != std::string::npos) {
771  s.width(static_cast<std::streamsize>(maxAfter));
772  s << values[(i * n) + j].substr(p, maxAfter).c_str();
773  }
774  else {
775  assert(maxAfter > 1);
776  s.width(static_cast<std::streamsize>(maxAfter));
777  s << ".0";
778  }
779  }
780 
781  s << ' ';
782  }
783  s << std::endl;
784  }
785 
786  s.flags(original_flags); // restore s to standard state
787 
788  return static_cast<int>(maxBefore + maxAfter);
789 }
790 
791 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
792 
800 
801 #endif //#if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
802 #ifdef ENABLE_VISP_NAMESPACE
803  }
804 #endif
Implementation of a generic 2D array used as base class for matrices and vectors.
Definition: vpArray2D.h:145
unsigned int getCols() const
Definition: vpArray2D.h:337
double ** rowPtrs
Address of the first element of each rows.
Definition: vpArray2D.h:1102
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:349
vpArray2D< double > t() const
Compute the transpose of the array.
Definition: vpArray2D.h:1163
unsigned int getRows() const
Definition: vpArray2D.h:347
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ dimensionError
Bad dimension.
Definition: vpException.h:71
vpForceTwistMatrix & build(const vpTranslationVector &t, const vpRotationMatrix &R)
VP_DEPRECATED vpForceTwistMatrix buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
vpForceTwistMatrix operator*(const vpForceTwistMatrix &F) const
vpForceTwistMatrix & operator=(const vpForceTwistMatrix &H)
int print(std::ostream &s, unsigned int length, char const *intro=nullptr) const
VP_DEPRECATED void setIdentity()
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:254
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169
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.