Visual Servoing Platform  version 3.6.1 under development (2024-12-17)
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 
59 BEGIN_VISP_NAMESPACE
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  buildFrom(tu);
132 }
133 
152 {
153  init();
154 
155  vpThetaUVector tu(R);
156  buildFrom(tu);
157 }
158 
179 {
180  init();
182  M.extract(R);
183  vpThetaUVector tu(R);
184  buildFrom(tu);
185 }
186 
204 {
205  s[0] = tu[0];
206  s[1] = tu[1];
207  s[2] = tu[2];
208  for (unsigned int i = 0; i < nbParameters; ++i) {
209  flags[i] = true;
210  }
211  return *this;
212 }
213 
230 {
231  vpThetaUVector tu(R);
232  buildFrom(tu);
233  return *this;
234 }
235 
255 {
257  M.extract(R);
258  vpThetaUVector tu(R);
259  buildFrom(tu);
260  return *this;
261 }
262 
272 
281 void vpFeatureThetaU::set_TUx(double tu_x)
282 {
283  s[0] = tu_x;
284  flags[0] = true;
285 }
294 void vpFeatureThetaU::set_TUy(double tu_y)
295 {
296  s[1] = tu_y;
297  flags[1] = true;
298 }
307 void vpFeatureThetaU::set_TUz(double tu_z)
308 {
309  s[2] = tu_z;
310  flags[2] = true;
311 }
312 
322 {
323  return rotation;
324 }
325 
332 double vpFeatureThetaU::get_TUx() const { return s[0]; }
333 
339 double vpFeatureThetaU::get_TUy() const { return s[1]; }
340 
346 double vpFeatureThetaU::get_TUz() const { return s[2]; }
347 
411 {
412 
413  vpMatrix L;
414  L.resize(0, 6);
415 
417  for (unsigned int i = 0; i < nbParameters; i++) {
418  if (flags[i] == false) {
419  switch (i) {
420  case 0:
421  vpTRACE("Warning !!! The interaction matrix is computed but Tu_x "
422  "was not set yet");
423  break;
424  case 1:
425  vpTRACE("Warning !!! The interaction matrix is computed but Tu_y "
426  "was not set yet");
427  break;
428  case 2:
429  vpTRACE("Warning !!! The interaction matrix is computed but Tu_z "
430  "was not set yet");
431  break;
432  default:
433  vpTRACE("Problem during the reading of the variable flags");
434  }
435  }
436  }
437  resetFlags();
438  }
439 
440  // Lw computed using Lw = [theta/2 u]_x +/- (I + alpha [u]_x [u]_x)
441  vpColVector u(3);
442  for (unsigned int i = 0; i < 3; i++) {
443  u[i] = s[i] / 2.0;
444  }
445 
446  vpMatrix Lw(3, 3);
447  Lw = vpColVector::skew(u); /* [theta/2 u]_x */
448 
449  vpMatrix U2(3, 3);
450  U2.eye();
451 
452  double theta = sqrt(s.sumSquare());
453  if (theta >= 1e-6) {
454  for (unsigned int i = 0; i < 3; i++)
455  u[i] = s[i] / theta;
456 
457  vpMatrix skew_u;
458  skew_u = vpColVector::skew(u);
459  U2 += (1 - vpMath::sinc(theta) / vpMath::sqr(vpMath::sinc(theta / 2.0))) * skew_u * skew_u;
460  }
461 
462  if (rotation == cdRc) {
463  Lw += U2;
464  }
465  else {
466  Lw -= U2;
467  }
468 
469  // This version is a simplification
470  if (vpFeatureThetaU::selectTUx() & select) {
471  vpMatrix Lx(1, 6);
472 
473  Lx[0][0] = 0;
474  Lx[0][1] = 0;
475  Lx[0][2] = 0;
476  for (int i = 0; i < 3; i++)
477  Lx[0][i + 3] = Lw[0][i];
478 
479  L = vpMatrix::stack(L, Lx);
480  }
481 
482  if (vpFeatureThetaU::selectTUy() & select) {
483  vpMatrix Ly(1, 6);
484 
485  Ly[0][0] = 0;
486  Ly[0][1] = 0;
487  Ly[0][2] = 0;
488  for (int i = 0; i < 3; i++)
489  Ly[0][i + 3] = Lw[1][i];
490 
491  L = vpMatrix::stack(L, Ly);
492  }
493 
494  if (vpFeatureThetaU::selectTUz() & select) {
495  vpMatrix Lz(1, 6);
496 
497  Lz[0][0] = 0;
498  Lz[0][1] = 0;
499  Lz[0][2] = 0;
500  for (int i = 0; i < 3; i++)
501  Lz[0][i + 3] = Lw[2][i];
502 
503  L = vpMatrix::stack(L, Lz);
504  }
505 
506  return L;
507 }
508 
570 vpColVector vpFeatureThetaU::error(const vpBasicFeature &s_star, unsigned int select)
571 {
572 
573  if (fabs(s_star.get_s().sumSquare()) > 1e-6) {
574  vpERROR_TRACE("s* should be zero ! ");
575  throw(vpFeatureException(vpFeatureException::badInitializationError, "s* should be zero !"));
576  }
577 
578  vpColVector e(0);
579 
580  if (vpFeatureThetaU::selectTUx() & select) {
581  vpColVector ex(1);
582  ex[0] = s[0];
583  e = vpColVector::stack(e, ex);
584  }
585 
586  if (vpFeatureThetaU::selectTUy() & select) {
587  vpColVector ey(1);
588  ey[0] = s[1];
589  e = vpColVector::stack(e, ey);
590  }
591 
592  if (vpFeatureThetaU::selectTUz() & select) {
593  vpColVector ez(1);
594  ez[0] = s[2];
595  e = vpColVector::stack(e, ez);
596  }
597  return e;
598 }
599 
626 void vpFeatureThetaU::print(unsigned int select) const
627 {
628  std::cout << "ThetaU:";
629  if (vpFeatureThetaU::selectTUx() & select) {
630  std::cout << " tux=" << s[0];
631  }
632  if (vpFeatureThetaU::selectTUy() & select) {
633  std::cout << " tuy=" << s[1];
634  }
635  if (vpFeatureThetaU::selectTUz() & select) {
636  std::cout << " tuz=" << s[2];
637  }
638  std::cout << std::endl;
639 }
640 
653 {
654  vpFeatureThetaU *feature;
655  if (rotation == cdRc)
656  feature = new vpFeatureThetaU(vpFeatureThetaU::cdRc);
657  else // if (rotation == cRcd
658  feature = new vpFeatureThetaU(vpFeatureThetaU::cRcd);
659 
660  return feature;
661 }
662 
669  const vpColor & /* color */, unsigned int /* thickness */) const
670 {
671  static int firsttime = 0;
672 
673  if (firsttime == 0) {
674  firsttime = 1;
675  vpERROR_TRACE("not implemented");
676  // Do not throw and error since it is not subject
677  // to produce a failure
678  }
679 }
685 void vpFeatureThetaU::display(const vpCameraParameters & /* cam */, const vpImage<vpRGBa> & /* I */,
686  const vpColor & /* color */, unsigned int /* thickness */) const
687 {
688  static int firsttime = 0;
689 
690  if (firsttime == 0) {
691  firsttime = 1;
692  vpERROR_TRACE("not implemented");
693  // Do not throw and error since it is not subject
694  // to produce a failure
695  }
696 }
697 
722 unsigned int vpFeatureThetaU::selectTUx() { return FEATURE_LINE[0]; }
747 unsigned int vpFeatureThetaU::selectTUy() { return FEATURE_LINE[1]; }
772 unsigned int vpFeatureThetaU::selectTUz() { return FEATURE_LINE[2]; }
773 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
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
double get_TUy() const
double get_TUz() const
static unsigned int selectTUx()
void setFeatureThetaURotationType(const vpFeatureThetaURotationRepresentationType r)
vpFeatureThetaU & buildFrom(const vpThetaUVector &tu)
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.