Visual Servoing Platform  version 3.6.1 under development (2024-12-17)
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 
43 #include <assert.h>
44 #include <sstream>
45 
46 #include <visp3/core/vpException.h>
47 #include <visp3/core/vpForceTwistMatrix.h>
48 
49 BEGIN_VISP_NAMESPACE
50 
51 const 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 
91 vpForceTwistMatrix::vpForceTwistMatrix() : vpArray2D<double>(constr_value_6, constr_value_6) { eye(); }
92 
100 vpForceTwistMatrix::vpForceTwistMatrix(const vpForceTwistMatrix &F) : vpArray2D<double>(constr_value_6, constr_value_6) { *this = F; }
101 
131 vpForceTwistMatrix::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 
183 vpForceTwistMatrix::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 
227 vpForceTwistMatrix::vpForceTwistMatrix(const vpRotationMatrix &R) : vpArray2D<double>(constr_value_6, constr_value_6) { buildFrom(R); }
228 
249 vpForceTwistMatrix::vpForceTwistMatrix(double tx, double ty, double tz, double tux, double tuy, double tuz)
250  : vpArray2D<double>(constr_value_6, constr_value_6)
251 {
252  vpTranslationVector T(tx, ty, tz);
253  vpThetaUVector tu(tux, tuy, tuz);
254  buildFrom(T, tu);
255 }
256 
280 {
281  vpForceTwistMatrix Fout;
282  const unsigned int nparam = 6;
283  for (unsigned int i = 0; i < nparam; ++i) {
284  for (unsigned int j = 0; j < nparam; ++j) {
285  double s = 0;
286  for (unsigned int k = 0; k < nparam; ++k) {
287  s += rowPtrs[i][k] * F.rowPtrs[k][j];
288  }
289  Fout[i][j] = s;
290  }
291  }
292  return Fout;
293 }
294 
303 {
304  const unsigned int nparam = 6;
305  if (nparam != M.getRows()) {
307  "Cannot multiply (6x6) force/torque twist matrix by a (%dx%d) matrix", M.getRows(), M.getCols()));
308  }
309 
310  unsigned int m_col = M.getCols();
311  vpMatrix p(nparam, M.getCols());
312  for (unsigned int i = 0; i < nparam; ++i) {
313  for (unsigned int j = 0; j < m_col; ++j) {
314  double s = 0;
315  for (unsigned int k = 0; k < nparam; ++k) {
316  s += rowPtrs[i][k] * M[k][j];
317  }
318  p[i][j] = s;
319  }
320  }
321  return p;
322 }
323 
372 {
373  const unsigned int val_6 = 6;
374  const unsigned int nparam = 6;
375  vpColVector Hout(nparam);
376 
377  if (val_6 != H.getRows()) {
379  "Cannot multiply a (6x6) force/torque twist matrix by "
380  "a %d dimension column vector",
381  H.getRows()));
382  }
383 
384  Hout = 0.0;
385 
386  for (unsigned int i = 0; i < nparam; ++i) {
387  for (unsigned int j = 0; j < nparam; ++j) {
388  Hout[i] += rowPtrs[i][j] * H[j];
389  }
390  }
391 
392  return Hout;
393 }
394 
414 {
415  vpMatrix skewaR = t.skew(t) * R;
416 
417  const unsigned int val_3 = 3;
418  const unsigned int index_3 = 3;
419  for (unsigned int i = 0; i < val_3; ++i) {
420  for (unsigned int j = 0; j < val_3; ++j) {
421  (*this)[i][j] = R[i][j];
422  (*this)[i + index_3][j + index_3] = R[i][j];
423  (*this)[i + index_3][j] = skewaR[i][j];
424  }
425  }
426  return *this;
427 }
428 
446 {
447  const unsigned int index_3 = 3;
448  const unsigned int val_3 = 3;
449  for (unsigned int i = 0; i < val_3; ++i) {
450  for (unsigned int j = 0; j < val_3; ++j) {
451  (*this)[i][j] = R[i][j];
452  (*this)[i + index_3][j + index_3] = R[i][j];
453  (*this)[i + index_3][j] = 0;
454  }
455  }
456  return *this;
457 }
458 
479 {
480  buildFrom(tv, vpRotationMatrix(thetau));
481  return *this;
482 }
483 
502 {
503  buildFrom(vpRotationMatrix(thetau));
504  return *this;
505 }
506 
535 {
536  if (full) {
538  }
539  else {
541  }
542 
543  return *this;
544 }
545 
565 int vpForceTwistMatrix::print(std::ostream &s, unsigned int length, char const *intro) const
566 {
567  typedef std::string::size_type size_type;
568 
569  unsigned int m = getRows();
570  unsigned int n = getCols();
571 
572  std::vector<std::string> values(m * n);
573  std::ostringstream oss;
574  std::ostringstream ossFixed;
575  std::ios_base::fmtflags original_flags = oss.flags();
576 
577  // --comment: ossFixed less less std fixed
578  ossFixed.setf(std::ios::fixed, std::ios::floatfield);
579 
580  size_type maxBefore = 0; // the length of the integral part
581  size_type maxAfter = 0; // number of decimals plus
582  // one place for the decimal point
583  for (unsigned int i = 0; i < m; ++i) {
584  for (unsigned int j = 0; j < n; ++j) {
585  oss.str("");
586  oss << (*this)[i][j];
587  if (oss.str().find("e") != std::string::npos) {
588  ossFixed.str("");
589  ossFixed << (*this)[i][j];
590  oss.str(ossFixed.str());
591  }
592 
593  values[(i * n) + j] = oss.str();
594  size_type thislen = values[(i * n) + j].size();
595  size_type p = values[(i * n) + j].find('.');
596 
597  if (p == std::string::npos) {
598  maxBefore = vpMath::maximum(maxBefore, thislen);
599  // maxAfter remains the same
600  }
601  else {
602  maxBefore = vpMath::maximum(maxBefore, p);
603  maxAfter = vpMath::maximum(maxAfter, thislen - p - 1);
604  }
605  }
606  }
607 
608  size_type totalLength = length;
609  // increase totalLength according to maxBefore
610  totalLength = vpMath::maximum(totalLength, maxBefore);
611  // decrease maxAfter according to totalLength
612  maxAfter = std::min<size_type>(maxAfter, totalLength - maxBefore);
613  if (maxAfter == 1) {
614  maxAfter = 0;
615  }
616 
617  // the following line is useful for debugging
618  // std::cerr <<totalLength <<" " <<maxBefore <<" " <<maxAfter <<"\n";
619 
620  if (intro) {
621  s << intro;
622  }
623  s << "[" << m << "," << n << "]=\n";
624 
625  for (unsigned int i = 0; i < m; ++i) {
626  s << " ";
627  for (unsigned int j = 0; j < n; ++j) {
628  size_type p = values[(i * n) + j].find('.');
629  s.setf(std::ios::right, std::ios::adjustfield);
630  s.width(static_cast<std::streamsize>(maxBefore));
631  s << values[(i * n) + j].substr(0, p).c_str();
632 
633  if (maxAfter > 0) {
634  s.setf(std::ios::left, std::ios::adjustfield);
635  if (p != std::string::npos) {
636  s.width(static_cast<std::streamsize>(maxAfter));
637  s << values[(i * n) + j].substr(p, maxAfter).c_str();
638  }
639  else {
640  assert(maxAfter > 1);
641  s.width(static_cast<std::streamsize>(maxAfter));
642  s << ".0";
643  }
644  }
645 
646  s << ' ';
647  }
648  s << std::endl;
649  }
650 
651  s.flags(original_flags); // restore s to standard state
652 
653  return static_cast<int>(maxBefore + maxAfter);
654 }
655 
656 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
657 
664 void vpForceTwistMatrix::setIdentity() { eye(); }
665 
666 #endif //#if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
667 #ifdef ENABLE_VISP_NAMESPACE
668  }
669 #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:1105
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:1166
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 & 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: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.