Visual Servoing Platform  version 3.0.0
vpPoseVirtualVisualServoing.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
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 http://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  * Pose computation.
32  *
33  * Authors:
34  * Eric Marchand
35  *
36  *****************************************************************************/
37 
43 #include <visp3/vision/vpPose.h>
44 #include <visp3/core/vpPoint.h>
45 #include <visp3/core/vpExponentialMap.h>
46 #include <visp3/core/vpRobust.h>
47 
55 void
57 {
58  try
59  {
60 
61  double residu_1 = 1e8 ;
62  double r =1e8-1;
63 
64  // we stop the minimization when the error is bellow 1e-8
65 
66  int iter = 0 ;
67 
68  unsigned int nb = (unsigned int)listP.size() ;
69  vpMatrix L(2*nb,6) ;
70  vpColVector err(2*nb) ;
71  vpColVector sd(2*nb),s(2*nb) ;
72  vpColVector v ;
73 
74  vpPoint P;
75  std::list<vpPoint> lP ;
76 
77  // create sd
78  unsigned int k =0 ;
79  for (std::list<vpPoint>::const_iterator it = listP.begin(); it != listP.end(); ++it)
80  {
81  P = *it;
82  sd[2*k] = P.get_x() ;
83  sd[2*k+1] = P.get_y() ;
84  lP.push_back(P);
85  k ++;
86  }
87 
88  vpHomogeneousMatrix cMoPrev = cMo;
89  while((int)((residu_1 - r)*1e12) !=0)
90  {
91  residu_1 = r ;
92 
93  // Compute the interaction matrix and the error
94  k =0 ;
95  for (std::list<vpPoint>::const_iterator it = lP.begin(); it != lP.end(); ++it)
96  {
97  P = *it;
98  // forward projection of the 3D model for a given pose
99  // change frame coordinates
100  // perspective projection
101  P.track(cMo) ;
102 
103  double x = s[2*k] = P.get_x(); /* point projected from cMo */
104  double y = s[2*k+1] = P.get_y();
105  double Z = P.get_Z() ;
106  L[2*k][0] = -1/Z ;
107  L[2*k][1] = 0 ;
108  L[2*k][2] = x/Z ;
109  L[2*k][3] = x*y ;
110  L[2*k][4] = -(1+x*x) ;
111  L[2*k][5] = y ;
112 
113  L[2*k+1][0] = 0 ;
114  L[2*k+1][1] = -1/Z ;
115  L[2*k+1][2] = y/Z ;
116  L[2*k+1][3] = 1+y*y ;
117  L[2*k+1][4] = -x*y ;
118  L[2*k+1][5] = -x ;
119 
120  k+=1 ;
121  }
122  err = s - sd ;
123 
124  // compute the residual
125  r = err.sumSquare() ;
126 
127  // compute the pseudo inverse of the interaction matrix
128  vpMatrix Lp ;
129  L.pseudoInverse(Lp,1e-16) ;
130 
131  // compute the VVS control law
132  v = -lambda*Lp*err ;
133 
134  //std::cout << "r=" << r <<std::endl ;
135  // update the pose
136 
137  cMoPrev = cMo;
138  cMo = vpExponentialMap::direct(v).inverse()*cMo ; ;
139  if (iter++>vvsIterMax) break ;
140  }
141 
142  if(computeCovariance)
143  covarianceMatrix = vpMatrix::computeCovarianceMatrixVVS(cMoPrev, err, L);
144  }
145 
146  catch(...)
147  {
148  vpERROR_TRACE(" ") ;
149  throw ;
150  }
151 }
152 
160 void
162 {
163  try{
164 
165  double residu_1 = 1e8 ;
166  double r =1e8-1;
167 
168  // we stop the minimization when the error is bellow 1e-8
169  vpMatrix W ;
170  vpRobust robust((unsigned int)(2*listP.size())) ;
171  robust.setThreshold(0.0000) ;
172  vpColVector w,res ;
173 
174  unsigned int nb = (unsigned int)listP.size() ;
175  vpMatrix L(2*nb,6) ;
176  vpColVector error(2*nb) ;
177  vpColVector sd(2*nb),s(2*nb) ;
178  vpColVector v ;
179 
180  listP.front() ;
181  vpPoint P;
182  std::list<vpPoint> lP ;
183 
184  // create sd
185  unsigned int k_ =0 ;
186  for (std::list<vpPoint>::const_iterator it = listP.begin(); it != listP.end(); ++it)
187  {
188  P = *it;
189  sd[2*k_] = P.get_x() ;
190  sd[2*k_+1] = P.get_y() ;
191  lP.push_back(P) ;
192  k_ ++;
193  }
194  int iter = 0 ;
195  res.resize(s.getRows()/2) ;
196  w.resize(s.getRows()/2) ;
197  W.resize(s.getRows(), s.getRows()) ;
198  w =1 ;
199 
200  while((int)((residu_1 - r)*1e12) !=0)
201  {
202  residu_1 = r ;
203 
204  // Compute the interaction matrix and the error
205  k_ =0 ;
206  for (std::list<vpPoint>::const_iterator it = lP.begin(); it != lP.end(); ++it)
207  {
208  P = *it;
209  // forward projection of the 3D model for a given pose
210  // change frame coordinates
211  // perspective projection
212  P.track(cMo) ;
213 
214  double x = s[2*k_] = P.get_x(); // point projected from cMo
215  double y = s[2*k_+1] = P.get_y();
216  double Z = P.get_Z() ;
217  L[2*k_][0] = -1/Z ;
218  L[2*k_][1] = 0 ;
219  L[2*k_][2] = x/Z ;
220  L[2*k_][3] = x*y ;
221  L[2*k_][4] = -(1+x*x) ;
222  L[2*k_][5] = y ;
223 
224  L[2*k_+1][0] = 0 ;
225  L[2*k_+1][1] = -1/Z ;
226  L[2*k_+1][2] = y/Z ;
227  L[2*k_+1][3] = 1+y*y ;
228  L[2*k_+1][4] = -x*y ;
229  L[2*k_+1][5] = -x ;
230 
231  k_ ++;
232 
233  }
234  error = s - sd ;
235 
236  // compute the residual
237  r = error.sumSquare() ;
238 
239  for(unsigned int k=0 ; k <error.getRows()/2 ; k++)
240  {
241  res[k] = vpMath::sqr(error[2*k]) + vpMath::sqr(error[2*k+1]) ;
242  }
243  robust.setIteration(0);
244  robust.MEstimator(vpRobust::TUKEY, res, w);
245 
246  // compute the pseudo inverse of the interaction matrix
247  for (unsigned int k=0 ; k < error.getRows()/2 ; k++)
248  {
249  W[2*k][2*k] = w[k] ;
250  W[2*k+1][2*k+1] = w[k] ;
251  }
252  // compute the pseudo inverse of the interaction matrix
253  vpMatrix Lp ;
254  (W*L).pseudoInverse(Lp,1e-6) ;
255 
256  // compute the VVS control law
257  v = -lambda*Lp*W*error ;
258 
259  cMo = vpExponentialMap::direct(v).inverse()*cMo ; ;
260  if (iter++>vvsIterMax) break ;
261  }
262 
263  if(computeCovariance)
264  covarianceMatrix = vpMatrix::computeCovarianceMatrix(L,v,-lambda*error, W*W); // Remark: W*W = W*W.t() since the matrix is diagonale, but using W*W is more efficient.
265  }
266  catch(...)
267  {
268  vpERROR_TRACE(" ") ;
269  throw ;
270  }
271 
272 }
273 
274 
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:92
static vpMatrix computeCovarianceMatrixVVS(const vpHomogeneousMatrix &cMo, const vpColVector &deltaS, const vpMatrix &Ls, const vpMatrix &W)
void MEstimator(const vpRobustEstimatorType method, const vpColVector &residues, vpColVector &weights)
Compute the weights according a residue vector and a PsiFunction.
Definition: vpRobust.cpp:132
void poseVirtualVSrobust(vpHomogeneousMatrix &cMo)
compute the pose using a robust virtual visual servoing approach
void resize(const unsigned int nrows, const unsigned int ncols, const bool flagNullify=true)
Definition: vpArray2D.h:167
Implementation of an homogeneous matrix and operations on such kind of matrices.
#define vpERROR_TRACE
Definition: vpDebug.h:391
void track(const vpHomogeneousMatrix &cMo)
double get_y() const
Get the point y coordinate in the image plane.
Definition: vpPoint.cpp:458
std::list< vpPoint > listP
array of point (use here class vpPoint)
Definition: vpPose.h:91
static vpMatrix computeCovarianceMatrix(const vpMatrix &A, const vpColVector &x, const vpColVector &b)
void poseVirtualVS(vpHomogeneousMatrix &cMo)
compute the pose using virtual visual servoing approach
Class that defines what is a point.
Definition: vpPoint.h:59
double lambda
parameters use for the virtual visual servoing approach
Definition: vpPose.h:96
static double sqr(double x)
Definition: vpMath.h:110
double get_x() const
Get the point x coordinate in the image plane.
Definition: vpPoint.cpp:456
unsigned int getRows() const
Return the number of rows of the 2D array.
Definition: vpArray2D.h:152
double get_Z() const
Get the point Z coordinate in the camera frame.
Definition: vpPoint.cpp:442
double sumSquare() const
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
vpHomogeneousMatrix inverse() const
static vpHomogeneousMatrix direct(const vpColVector &v)
Contains an M-Estimator and various influence function.
Definition: vpRobust.h:59
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.
Definition: vpMatrix.cpp:1756
void setThreshold(const double noise_threshold)
Definition: vpRobust.h:124
void setIteration(const unsigned int iter)
Set iteration.
Definition: vpRobust.h:118
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:217