Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
vpFeatureThetaU.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See https://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * ThetaU visual feature.
33  *
34 *****************************************************************************/
35 
41 #include <visp3/core/vpMath.h>
42 #include <visp3/visual_features/vpBasicFeature.h>
43 #include <visp3/visual_features/vpFeatureThetaU.h>
44 
45 // Exception
46 #include <visp3/core/vpException.h>
47 #include <visp3/visual_features/vpFeatureException.h>
48 
49 // Debug trace
50 #include <visp3/core/vpDebug.h>
51 
52 /*
53 
54 attributes and members directly related to the vpBasicFeature needs
55 other functionalities are useful but not mandatory
56 
57 */
58 
66 {
67  // feature dimension
68  dim_s = 3;
69  nbParameters = 3;
70 
71  // memory allocation
72  s.resize(dim_s);
73  if (flags == nullptr)
74  flags = new bool[nbParameters];
75  for (unsigned int i = 0; i < nbParameters; i++)
76  flags[i] = false;
77 }
78 
87 {
88  // vpTRACE("0x%x", this);
89  init();
90 }
91 
100 {
101  // vpTRACE("0x%x", this);
102  init();
103 
104  // kind of rotation representation
105  rotation = r;
106 }
107 
128 {
129  init();
130 
131  build(tu);
132 }
133 
152 {
153  init();
154 
155  vpThetaUVector tu(R);
156  build(tu);
157 }
158 
179 {
180  init();
182  M.extract(R);
183  vpThetaUVector tu(R);
184  build(tu);
185 }
186 
187 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
205 {
206  build(tu);
207 }
208 
226 {
227  build(R);
228 }
229 
250 {
251  build(M);
252 }
253 #endif
254 
272 {
273  s[0] = tu[0];
274  s[1] = tu[1];
275  s[2] = tu[2];
276  for (unsigned int i = 0; i < nbParameters; ++i) {
277  flags[i] = true;
278  }
279  return *this;
280 }
281 
298 {
299  vpThetaUVector tu(R);
300  build(tu);
301  return *this;
302 }
303 
323 {
325  M.extract(R);
326  vpThetaUVector tu(R);
327  build(tu);
328  return *this;
329 }
330 
340 
349 void vpFeatureThetaU::set_TUx(double tu_x)
350 {
351  s[0] = tu_x;
352  flags[0] = true;
353 }
362 void vpFeatureThetaU::set_TUy(double tu_y)
363 {
364  s[1] = tu_y;
365  flags[1] = true;
366 }
375 void vpFeatureThetaU::set_TUz(double tu_z)
376 {
377  s[2] = tu_z;
378  flags[2] = true;
379 }
380 
390 {
391  return rotation;
392 }
393 
400 double vpFeatureThetaU::get_TUx() const { return s[0]; }
401 
407 double vpFeatureThetaU::get_TUy() const { return s[1]; }
408 
414 double vpFeatureThetaU::get_TUz() const { return s[2]; }
415 
479 {
480 
481  vpMatrix L;
482  L.resize(0, 6);
483 
485  for (unsigned int i = 0; i < nbParameters; i++) {
486  if (flags[i] == false) {
487  switch (i) {
488  case 0:
489  vpTRACE("Warning !!! The interaction matrix is computed but Tu_x "
490  "was not set yet");
491  break;
492  case 1:
493  vpTRACE("Warning !!! The interaction matrix is computed but Tu_y "
494  "was not set yet");
495  break;
496  case 2:
497  vpTRACE("Warning !!! The interaction matrix is computed but Tu_z "
498  "was not set yet");
499  break;
500  default:
501  vpTRACE("Problem during the reading of the variable flags");
502  }
503  }
504  }
505  resetFlags();
506  }
507 
508  // Lw computed using Lw = [theta/2 u]_x +/- (I + alpha [u]_x [u]_x)
509  vpColVector u(3);
510  for (unsigned int i = 0; i < 3; i++) {
511  u[i] = s[i] / 2.0;
512  }
513 
514  vpMatrix Lw(3, 3);
515  Lw = vpColVector::skew(u); /* [theta/2 u]_x */
516 
517  vpMatrix U2(3, 3);
518  U2.eye();
519 
520  double theta = sqrt(s.sumSquare());
521  if (theta >= 1e-6) {
522  for (unsigned int i = 0; i < 3; i++)
523  u[i] = s[i] / theta;
524 
525  vpMatrix skew_u;
526  skew_u = vpColVector::skew(u);
527  U2 += (1 - vpMath::sinc(theta) / vpMath::sqr(vpMath::sinc(theta / 2.0))) * skew_u * skew_u;
528  }
529 
530  if (rotation == cdRc) {
531  Lw += U2;
532  }
533  else {
534  Lw -= U2;
535  }
536 
537  // This version is a simplification
538  if (vpFeatureThetaU::selectTUx() & select) {
539  vpMatrix Lx(1, 6);
540 
541  Lx[0][0] = 0;
542  Lx[0][1] = 0;
543  Lx[0][2] = 0;
544  for (int i = 0; i < 3; i++)
545  Lx[0][i + 3] = Lw[0][i];
546 
547  L = vpMatrix::stack(L, Lx);
548  }
549 
550  if (vpFeatureThetaU::selectTUy() & select) {
551  vpMatrix Ly(1, 6);
552 
553  Ly[0][0] = 0;
554  Ly[0][1] = 0;
555  Ly[0][2] = 0;
556  for (int i = 0; i < 3; i++)
557  Ly[0][i + 3] = Lw[1][i];
558 
559  L = vpMatrix::stack(L, Ly);
560  }
561 
562  if (vpFeatureThetaU::selectTUz() & select) {
563  vpMatrix Lz(1, 6);
564 
565  Lz[0][0] = 0;
566  Lz[0][1] = 0;
567  Lz[0][2] = 0;
568  for (int i = 0; i < 3; i++)
569  Lz[0][i + 3] = Lw[2][i];
570 
571  L = vpMatrix::stack(L, Lz);
572  }
573 
574  return L;
575 }
576 
638 vpColVector vpFeatureThetaU::error(const vpBasicFeature &s_star, unsigned int select)
639 {
640 
641  if (fabs(s_star.get_s().sumSquare()) > 1e-6) {
642  vpERROR_TRACE("s* should be zero ! ");
643  throw(vpFeatureException(vpFeatureException::badInitializationError, "s* should be zero !"));
644  }
645 
646  vpColVector e(0);
647 
648  if (vpFeatureThetaU::selectTUx() & select) {
649  vpColVector ex(1);
650  ex[0] = s[0];
651  e = vpColVector::stack(e, ex);
652  }
653 
654  if (vpFeatureThetaU::selectTUy() & select) {
655  vpColVector ey(1);
656  ey[0] = s[1];
657  e = vpColVector::stack(e, ey);
658  }
659 
660  if (vpFeatureThetaU::selectTUz() & select) {
661  vpColVector ez(1);
662  ez[0] = s[2];
663  e = vpColVector::stack(e, ez);
664  }
665  return e;
666 }
667 
694 void vpFeatureThetaU::print(unsigned int select) const
695 {
696  std::cout << "ThetaU:";
697  if (vpFeatureThetaU::selectTUx() & select) {
698  std::cout << " tux=" << s[0];
699  }
700  if (vpFeatureThetaU::selectTUy() & select) {
701  std::cout << " tuy=" << s[1];
702  }
703  if (vpFeatureThetaU::selectTUz() & select) {
704  std::cout << " tuz=" << s[2];
705  }
706  std::cout << std::endl;
707 }
708 
721 {
722  vpFeatureThetaU *feature;
723  if (rotation == cdRc)
724  feature = new vpFeatureThetaU(vpFeatureThetaU::cdRc);
725  else // if (rotation == cRcd
726  feature = new vpFeatureThetaU(vpFeatureThetaU::cRcd);
727 
728  return feature;
729 }
730 
737  const vpColor & /* color */, unsigned int /* thickness */) const
738 {
739  static int firsttime = 0;
740 
741  if (firsttime == 0) {
742  firsttime = 1;
743  vpERROR_TRACE("not implemented");
744  // Do not throw and error since it is not subject
745  // to produce a failure
746  }
747 }
753 void vpFeatureThetaU::display(const vpCameraParameters & /* cam */, const vpImage<vpRGBa> & /* I */,
754  const vpColor & /* color */, unsigned int /* thickness */) const
755 {
756  static int firsttime = 0;
757 
758  if (firsttime == 0) {
759  firsttime = 1;
760  vpERROR_TRACE("not implemented");
761  // Do not throw and error since it is not subject
762  // to produce a failure
763  }
764 }
765 
790 unsigned int vpFeatureThetaU::selectTUx() { return FEATURE_LINE[0]; }
815 unsigned int vpFeatureThetaU::selectTUy() { return FEATURE_LINE[1]; }
840 unsigned int vpFeatureThetaU::selectTUz() { return FEATURE_LINE[2]; }
841 END_VISP_NAMESPACE
class that defines what is a visual feature
vpColVector s
State of the visual feature.
unsigned int nbParameters
Number of parameters needed to compute the interaction matrix.
vpColVector get_s(unsigned int select=FEATURE_ALL) const
Get the feature vector .
unsigned int dim_s
Dimension of the visual feature.
static const unsigned int FEATURE_LINE[32]
vpBasicFeatureDeallocatorType deallocate
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
double sumSquare() const
void stack(double d)
static vpMatrix skew(const vpColVector &v)
void resize(unsigned int i, bool flagNullify=true)
Definition: vpColVector.h:1143
Class to define RGB colors available for display functionalities.
Definition: vpColor.h:157
Error that can be emitted by the vpBasicFeature class and its derivates.
@ badInitializationError
Wrong feature initialization.
Class that defines a 3D visual feature from a axis/angle parametrization that represent the rotatio...
vpFeatureThetaU * duplicate() const VP_OVERRIDE
Feature duplication.
vpFeatureThetaURotationRepresentationType
vpFeatureThetaURotationRepresentationType getFeatureThetaURotationType() const
static unsigned int selectTUy()
vpColVector error(const vpBasicFeature &s_star, unsigned int select=FEATURE_ALL) VP_OVERRIDE
void print(unsigned int select=FEATURE_ALL) const VP_OVERRIDE
vpFeatureThetaU & build(const vpThetaUVector &tu)
void set_TUx(double tu_x)
double get_TUx() const
void set_TUz(double tu_z)
vpMatrix interaction(unsigned int select=FEATURE_ALL) VP_OVERRIDE
void buildFrom(vpThetaUVector &tu)
double get_TUy() const
double get_TUz() const
static unsigned int selectTUx()
void setFeatureThetaURotationType(const vpFeatureThetaURotationRepresentationType r)
static unsigned int selectTUz()
void display(const vpCameraParameters &cam, const vpImage< unsigned char > &I, const vpColor &color=vpColor::green, unsigned int thickness=1) const VP_OVERRIDE
void set_TUy(double tu_y)
void init() VP_OVERRIDE
Implementation of an homogeneous matrix and operations on such kind of matrices.
void extract(vpRotationMatrix &R) const
static double sinc(double x)
Definition: vpMath.cpp:268
static double sqr(double x)
Definition: vpMath.h:203
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169
void stack(const vpMatrix &A)
Implementation of a rotation matrix and operations on such kind of matrices.
Implementation of a rotation vector as axis-angle minimal representation.
#define vpTRACE
Definition: vpDebug.h:436
#define vpERROR_TRACE
Definition: vpDebug.h:409