Visual Servoing Platform  version 3.6.1 under development (2024-11-15)
testFeatureMoment.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  * Example of visual servoing with moments using a polygon as object container
32  */
33 
38 #include <visp3/core/vpDebug.h>
39 #include <visp3/core/vpHomogeneousMatrix.h>
40 #include <visp3/core/vpMomentCommon.h>
41 #include <visp3/core/vpMomentDatabase.h>
42 #include <visp3/core/vpMomentObject.h>
43 #include <visp3/core/vpPlane.h>
44 #include <visp3/visual_features/vpFeatureMomentCommon.h>
45 #include <visp3/vs/vpServo.h>
46 
47 #include <iostream>
48 #include <limits>
49 
50 #ifdef ENABLE_VISP_NAMESPACE
51 using namespace VISP_NAMESPACE_NAME;
52 #endif
53 
54 // initialize scene in the interface
55 void initScene(const vpHomogeneousMatrix &cMo, const vpHomogeneousMatrix &cdMo, vpMomentObject &src,
56  vpMomentObject &dst);
57 
58 vpMatrix execute(const vpHomogeneousMatrix &cMo, const vpHomogeneousMatrix &cdMo, vpMomentObject &src,
59  vpMomentObject &dst); // launch the test
60 void planeToABC(const vpPlane &pl, double &A, double &B, double &C);
61 int test(double x, double y, double z, double alpha);
62 
63 // Compute a set of parallel positions and check if the matrix is in the right
64 // form;
65 int main()
66 {
67 #if (defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
68  try {
69  int sum = 0;
70  for (double i = -0.2; i < 0.2; i += 0.1) {
71  for (double j = -0.2; j < 0.2; j += 0.1) {
72  for (double k = -vpMath::rad(30); k < vpMath::rad(30); k += vpMath::rad(10)) {
73  for (double l = 0.5; l < 1.5; l += 0.1) {
74  sum += test(i, j, l, k);
75  }
76  }
77  }
78  }
79  if (sum < 0)
80  return EXIT_FAILURE;
81  else
82  return EXIT_SUCCESS;
83  }
84  catch (const vpException &e) {
85  std::cout << "Catch an exception: " << e << std::endl;
86  return EXIT_FAILURE;
87  }
88 #else
89  std::cout << "Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
90  return EXIT_SUCCESS;
91 #endif
92 }
93 
94 int test(double x, double y, double z, double alpha)
95 {
96  // intial pose
97  vpHomogeneousMatrix cMo(x, y, z, -vpMath::rad(0), vpMath::rad(0), alpha);
98  // Desired pose
100 
101  // source and destination objects for moment manipulation
102  vpMomentObject src(6);
103  vpMomentObject dst(6);
104 
105  // init and run the simulation
106  initScene(cMo, cdMo, src, dst); // initialize graphical scene (for
107  // interface)
108 
109  vpMatrix mat = execute(cMo, cdMo, src, dst);
110 
111  if (fabs(mat[0][0] - (-1)) > std::numeric_limits<double>::epsilon() * 1e10)
112  return -1;
113  if (fabs(mat[0][1] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
114  return -1;
115  if (fabs(mat[0][2] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
116  return -1;
117 
118  if (fabs(mat[1][0] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
119  return -1;
120  if (fabs(mat[1][1] - (-1)) > std::numeric_limits<double>::epsilon() * 1e10)
121  return -1;
122  if (fabs(mat[1][2] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
123  return -1;
124 
125  if (fabs(mat[2][0] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
126  return -1;
127  if (fabs(mat[2][1] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
128  return -1;
129  if (fabs(mat[2][2] - (-1)) > std::numeric_limits<double>::epsilon() * 1e10)
130  return -1;
131  if (fabs(mat[2][5] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
132  return -1;
133 
134  if (fabs(mat[3][0] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
135  return -1;
136  if (fabs(mat[3][1] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
137  return -1;
138  if (fabs(mat[3][2] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
139  return -1;
140  if (fabs(mat[3][5] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
141  return -1;
142 
143  if (fabs(mat[4][0] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
144  return -1;
145  if (fabs(mat[4][1] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
146  return -1;
147  if (fabs(mat[4][2] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
148  return -1;
149  if (fabs(mat[4][5] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
150  return -1;
151 
152  if (fabs(mat[5][0] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
153  return -1;
154  if (fabs(mat[5][1] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
155  return -1;
156  if (fabs(mat[5][2] - (0)) > std::numeric_limits<double>::epsilon() * 1e10)
157  return -1;
158  if (fabs(mat[5][5] - (-1)) > std::numeric_limits<double>::epsilon() * 1e10)
159  return -1;
160 
161  return 0;
162 }
163 
164 void initScene(const vpHomogeneousMatrix &cMo, const vpHomogeneousMatrix &cdMo, vpMomentObject &src,
165  vpMomentObject &dst)
166 {
167  std::vector<vpPoint> src_pts;
168  std::vector<vpPoint> dst_pts;
169 
170  double x[5] = { 0.2, 0.2, -0.2, -0.2, 0.2 };
171  double y[5] = { -0.1, 0.1, 0.1, -0.1, -0.1 };
172  int nbpoints = 4;
173 
174  for (int i = 0; i < nbpoints; i++) {
175  vpPoint p(x[i], y[i], 0.0);
176  p.track(cMo);
177  src_pts.push_back(p);
178  }
179 
181  src.fromVector(src_pts);
182  for (int i = 0; i < nbpoints; i++) {
183  vpPoint p(x[i], y[i], 0.0);
184  p.track(cdMo);
185  dst_pts.push_back(p);
186  }
188  dst.fromVector(dst_pts);
189 }
190 
191 vpMatrix execute(const vpHomogeneousMatrix &cMo, const vpHomogeneousMatrix &cdMo, vpMomentObject &src,
192  vpMomentObject &dst)
193 {
194  vpServo::vpServoIteractionMatrixType interaction_type = vpServo::CURRENT; // current or desired
195 
196  vpServo task;
198  // A,B,C parameters of source and destination plane
199  double A;
200  double B;
201  double C;
202  double Ad;
203  double Bd;
204  double Cd;
205  // init main object: using moments up to order 6
206 
207  // Initializing values from regular plane (with ax+by+cz=d convention)
208  vpPlane pl;
209  pl.setABCD(0, 0, 1.0, 0);
210  pl.changeFrame(cMo);
211  planeToABC(pl, A, B, C);
212 
213  pl.setABCD(0, 0, 1.0, 0);
214  pl.changeFrame(cdMo);
215  planeToABC(pl, Ad, Bd, Cd);
216 
217  // extracting initial position (actually we only care about Zdst)
219  cdMo.extract(vec);
220 
223  // don't need to be specific, vpMomentCommon automatically loads
224  // Xg,Yg,An,Ci,Cj,Alpha moments
226  vec[2]);
228  vec[2]);
229  // same thing with common features
230  vpFeatureMomentCommon featureMoments(moments);
231  vpFeatureMomentCommon featureMomentsDes(momentsDes);
232 
233  moments.updateAll(src);
234  momentsDes.updateAll(dst);
235 
236  featureMoments.updateAll(A, B, C);
237  featureMomentsDes.updateAll(Ad, Bd, Cd);
238 
239  // setup the interaction type
240  task.setInteractionMatrixType(interaction_type);
243  task.addFeature(featureMoments.getFeatureGravityNormalized(), featureMomentsDes.getFeatureGravityNormalized());
244  task.addFeature(featureMoments.getFeatureAn(), featureMomentsDes.getFeatureAn());
245  // the moments are different in case of a symmetric object
246  task.addFeature(featureMoments.getFeatureCInvariant(), featureMomentsDes.getFeatureCInvariant(),
247  (1 << 10) | (1 << 11));
248  task.addFeature(featureMoments.getFeatureAlpha(), featureMomentsDes.getFeatureAlpha());
249 
250  task.setLambda(0.4);
251 
252  task.computeControlLaw();
253  vpMatrix mat = task.computeInteractionMatrix();
254  return mat;
255 }
256 
257 void planeToABC(const vpPlane &pl, double &A, double &B, double &C)
258 {
259  A = -pl.getA() / pl.getD();
260  B = -pl.getB() / pl.getD();
261  C = -pl.getC() / pl.getD();
262 }
error that can be emitted by ViSP classes.
Definition: vpException.h:60
This class allows to access common vpFeatureMoments in a pre-filled database.
Implementation of an homogeneous matrix and operations on such kind of matrices.
void extract(vpRotationMatrix &R) const
static double rad(double deg)
Definition: vpMath.h:129
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169
This class initializes and allows access to commonly used moments.
static std::vector< double > getMu3(vpMomentObject &object)
static double getAlpha(vpMomentObject &object)
static double getSurface(vpMomentObject &object)
Class for generic objects.
void setType(vpObjectType input_type)
void fromVector(std::vector< vpPoint > &points)
This class defines the container for a plane geometrical structure.
Definition: vpPlane.h:57
void changeFrame(const vpHomogeneousMatrix &cMo)
Definition: vpPlane.cpp:391
double getD() const
Definition: vpPlane.h:106
double getA() const
Definition: vpPlane.h:100
double getC() const
Definition: vpPlane.h:104
void setABCD(double a, double b, double c, double d)
Definition: vpPlane.h:88
double getB() const
Definition: vpPlane.h:102
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition: vpPoint.h:79
void setInteractionMatrixType(const vpServoIteractionMatrixType &interactionMatrixType, const vpServoInversionType &interactionMatrixInversion=PSEUDO_INVERSE)
Definition: vpServo.cpp:380
@ EYEINHAND_CAMERA
Definition: vpServo.h:161
void addFeature(vpBasicFeature &s_cur, vpBasicFeature &s_star, unsigned int select=vpBasicFeature::FEATURE_ALL)
Definition: vpServo.cpp:331
void setLambda(double c)
Definition: vpServo.h:986
void setServo(const vpServoType &servo_type)
Definition: vpServo.cpp:134
vpMatrix computeInteractionMatrix()
Definition: vpServo.cpp:452
vpColVector computeControlLaw()
Definition: vpServo.cpp:705
vpServoIteractionMatrixType
Definition: vpServo.h:196
@ CURRENT
Definition: vpServo.h:202
Class that consider the case of a translation vector.