Visual Servoing Platform  version 3.6.1 under development (2024-12-17)
vpVelocityTwistMatrix.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  * Velocity twist transformation matrix.
32  */
33 
42 #include <assert.h>
43 #include <sstream>
44 
45 #include <visp3/core/vpException.h>
46 #include <visp3/core/vpVelocityTwistMatrix.h>
47 
48 BEGIN_VISP_NAMESPACE
49 const unsigned int vpVelocityTwistMatrix::constr_val_6 = 6;
56 {
57  // why not unsigned int
58  const int val_6 = 6;
59  for (int i = 0; i < val_6; ++i) {
60  for (int j = 0; j < val_6; ++j) {
61  rowPtrs[i][j] = V.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 
89 vpVelocityTwistMatrix::vpVelocityTwistMatrix() : vpArray2D<double>(constr_val_6, constr_val_6) { eye(); }
90 
97 vpVelocityTwistMatrix::vpVelocityTwistMatrix(const vpVelocityTwistMatrix &V) : vpArray2D<double>(constr_val_6, constr_val_6) { *this = V; }
98 
117 vpVelocityTwistMatrix::vpVelocityTwistMatrix(const vpHomogeneousMatrix &M, bool full) : vpArray2D<double>(constr_val_6, constr_val_6)
118 {
119  if (full) {
120  buildFrom(M);
121  }
122  else {
124  }
125 }
126 
142  : vpArray2D<double>(constr_val_6, constr_val_6)
143 {
144  buildFrom(t, thetau);
145 }
146 
159 vpVelocityTwistMatrix::vpVelocityTwistMatrix(const vpThetaUVector &thetau) : vpArray2D<double>(constr_val_6, constr_val_6)
160 {
161  buildFrom(thetau);
162 }
163 
178  : vpArray2D<double>(constr_val_6, constr_val_6)
179 {
180  buildFrom(t, R);
181 }
182 
194 vpVelocityTwistMatrix::vpVelocityTwistMatrix(const vpRotationMatrix &R) : vpArray2D<double>(constr_val_6, constr_val_6) { buildFrom(R); }
195 
211 vpVelocityTwistMatrix::vpVelocityTwistMatrix(double tx, double ty, double tz, double tux, double tuy, double tuz)
212  : vpArray2D<double>(constr_val_6, constr_val_6)
213 {
214  vpTranslationVector t(tx, ty, tz);
215  vpThetaUVector tu(tux, tuy, tuz);
216  buildFrom(t, tu);
217 }
218 
226 {
228  const unsigned int nparam = 6;
229  for (unsigned int i = 0; i < nparam; ++i) {
230  for (unsigned int j = 0; j < nparam; ++j) {
231  double s = 0;
232  for (unsigned int k = 0; k < nparam; ++k) {
233  s += rowPtrs[i][k] * V.rowPtrs[k][j];
234  }
235  p[i][j] = s;
236  }
237  }
238  return p;
239 }
240 
285 {
286  const unsigned int nparam = 6;
287  if (nparam != M.getRows()) {
288  throw(vpException(vpException::dimensionError, "Cannot multiply a (6x6) velocity twist matrix by a (%dx%d) matrix",
289  M.getRows(), M.getCols()));
290  }
291 
292  vpMatrix p(nparam, M.getCols());
293  unsigned int m_col = M.getCols();
294  for (unsigned int i = 0; i < nparam; ++i) {
295  for (unsigned int j = 0; j < m_col; ++j) {
296  double s = 0;
297  for (unsigned int k = 0; k < nparam; ++k) {
298  s += rowPtrs[i][k] * M[k][j];
299  }
300  p[i][j] = s;
301  }
302  }
303  return p;
304 }
305 
318 {
319  const unsigned int nparam = 6;
320  vpColVector c(nparam);
321 
322  if (nparam != v.getRows()) {
324  "Cannot multiply a (6x6) velocity twist matrix by a "
325  "(%d) column vector",
326  v.getRows()));
327  }
328 
329  c = 0.0;
330 
331  for (unsigned int i = 0; i < nparam; ++i) {
332  for (unsigned int j = 0; j < nparam; ++j) {
333  c[i] += rowPtrs[i][j] * v[j];
334  }
335  }
336 
337  return c;
338 }
339 
352 {
353  const unsigned int index_3 = 3;
354  const unsigned int val_3 = 3;
355  for (unsigned int i = 0; i < val_3; ++i) {
356  for (unsigned int j = 0; j < val_3; ++j) {
357  (*this)[i][j] = R[i][j];
358  (*this)[i + index_3][j + index_3] = R[i][j];
359  (*this)[i][j + index_3] = 0;
360  }
361  }
362  return *this;
363 }
364 
380 {
381  vpMatrix skewaR = t.skew(t) * R;
382 
383  const unsigned int index_3 = 3;
384  const unsigned int val_3 = 3;
385  for (unsigned int i = 0; i < val_3; ++i) {
386  for (unsigned int j = 0; j < val_3; ++j) {
387  (*this)[i][j] = R[i][j];
388  (*this)[i + index_3][j + index_3] = R[i][j];
389  (*this)[i][j + index_3] = skewaR[i][j];
390  }
391  }
392 
393  return *this;
394 }
395 
412 {
413  buildFrom(t, vpRotationMatrix(thetau));
414  return *this;
415 }
416 
430 {
431  buildFrom(vpRotationMatrix(thetau));
432  return *this;
433 }
434 
454 {
455  if (full) {
457  }
458  else {
460  }
461 
462  return *this;
463 }
464 
467 {
470  extract(R);
472  extract(T);
474  RtT = -(R.t() * T);
475 
476  Wi.buildFrom(RtT, R.t());
477 
478  return Wi;
479 }
480 
483 
486 {
487  const unsigned int val_3 = 3;
488  for (unsigned int i = 0; i < val_3; ++i) {
489  for (unsigned int j = 0; j < val_3; ++j) {
490  R[i][j] = (*this)[i][j];
491  }
492  }
493 }
494 
497 {
499  extract(R);
500  vpMatrix skTR(3, 3);
501  const unsigned int val_3 = 3;
502  for (unsigned int i = 0; i < val_3; ++i) {
503  for (unsigned int j = 0; j < val_3; ++j) {
504  skTR[i][j] = (*this)[i][j + val_3];
505  }
506  }
507 
508  vpMatrix skT = skTR * R.t();
509  const unsigned int index_0 = 0;
510  const unsigned int index_1 = 1;
511  const unsigned int index_2 = 2;
512  tv[index_0] = skT[index_2][index_1];
513  tv[index_1] = skT[index_0][index_2];
514  tv[index_2] = skT[index_1][index_0];
515 }
516 
536 int vpVelocityTwistMatrix::print(std::ostream &s, unsigned int length, char const *intro) const
537 {
538  typedef std::string::size_type size_type;
539 
540  unsigned int m = getRows();
541  unsigned int n = getCols();
542 
543  std::vector<std::string> values(m * n);
544  std::ostringstream oss;
545  std::ostringstream ossFixed;
546  std::ios_base::fmtflags original_flags = oss.flags();
547 
548  // --comment: could be used ossFixed << std::fixed
549  ossFixed.setf(std::ios::fixed, std::ios::floatfield);
550 
551  size_type maxBefore = 0; // the length of the integral part
552  size_type maxAfter = 0; // number of decimals plus
553  // one place for the decimal point
554  for (unsigned int i = 0; i < m; ++i) {
555  for (unsigned int j = 0; j < n; ++j) {
556  oss.str("");
557  oss << (*this)[i][j];
558  if (oss.str().find("e") != std::string::npos) {
559  ossFixed.str("");
560  ossFixed << (*this)[i][j];
561  oss.str(ossFixed.str());
562  }
563 
564  values[(i * n) + j] = oss.str();
565  size_type thislen = values[(i * n) + j].size();
566  size_type p = values[(i * n) + j].find('.');
567 
568  if (p == std::string::npos) {
569  maxBefore = vpMath::maximum(maxBefore, thislen);
570  // maxAfter remains the same
571  }
572  else {
573  maxBefore = vpMath::maximum(maxBefore, p);
574  maxAfter = vpMath::maximum(maxAfter, thislen - p - 1);
575  }
576  }
577  }
578 
579  size_type totalLength = length;
580  // increase totalLength according to maxBefore
581  totalLength = vpMath::maximum(totalLength, maxBefore);
582  // decrease maxAfter according to totalLength
583  maxAfter = std::min<size_type>(maxAfter, totalLength - maxBefore);
584  if (maxAfter == 1) {
585  maxAfter = 0;
586  }
587 
588  // the following line is useful for debugging
589  // std::cerr <<totalLength <<" " <<maxBefore <<" " <<maxAfter <<"\n";
590 
591  if (intro) {
592  s << intro;
593  }
594  s << "[" << m << "," << n << "]=\n";
595 
596  for (unsigned int i = 0; i < m; ++i) {
597  s << " ";
598  for (unsigned int j = 0; j < n; ++j) {
599  size_type p = values[(i * n) + j].find('.');
600  s.setf(std::ios::right, std::ios::adjustfield);
601  s.width(static_cast<std::streamsize>(maxBefore));
602  s << values[(i * n) + j].substr(0, p).c_str();
603 
604  if (maxAfter > 0) {
605  s.setf(std::ios::left, std::ios::adjustfield);
606  if (p != std::string::npos) {
607  s.width(static_cast<std::streamsize>(maxAfter));
608  s << values[(i * n) + j].substr(p, maxAfter).c_str();
609  }
610  else {
611  assert(maxAfter > 1);
612  s.width(static_cast<std::streamsize>(maxAfter));
613  s << ".0";
614  }
615  }
616 
617  s << ' ';
618  }
619  s << std::endl;
620  }
621 
622  s.flags(original_flags); // restore s to standard state
623 
624  return static_cast<int>(maxBefore + maxAfter);
625 }
626 
627 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
628 
635 void vpVelocityTwistMatrix::setIdentity() { eye(); }
636 
637 #endif // #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
638 END_VISP_NAMESPACE
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
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.
vpRotationMatrix t() const
Implementation of a rotation vector as axis-angle minimal representation.
Class that consider the case of a translation vector.
vpVelocityTwistMatrix operator*(const vpVelocityTwistMatrix &V) const
void extract(vpRotationMatrix &R) const
Extract the rotation matrix from the velocity twist matrix.
vpVelocityTwistMatrix inverse() const
Invert the velocity twist matrix.
int print(std::ostream &s, unsigned int length, char const *intro=0) const
vpVelocityTwistMatrix & operator=(const vpVelocityTwistMatrix &V)
vpVelocityTwistMatrix & buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)