ViSP  2.9.0
testPose.cpp
1 /****************************************************************************
2  *
3  * $Id: testPose.cpp 4658 2014-02-09 09:50:14Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Compute the pose of a 3D object using the Dementhon, Lagrange and
36  * Non-Linear approach.
37  *
38  * Authors:
39  * Eric Marchand
40  * Fabien Spindler
41  *
42  *****************************************************************************/
43 
44 #include <visp/vpPose.h>
45 #include <visp/vpPoint.h>
46 #include <visp/vpMath.h>
47 #include <visp/vpTranslationVector.h>
48 #include <visp/vpRxyzVector.h>
49 #include <visp/vpRotationMatrix.h>
50 #include <visp/vpHomogeneousMatrix.h>
51 #include <visp/vpDebug.h>
52 #include <visp/vpParseArgv.h>
53 
54 #include <stdlib.h>
55 #include <stdio.h>
56 
57 // List of allowed command line options
58 #define GETOPTARGS "h"
59 
60 #define L 0.035
61 
70 void usage(const char *name, const char *badparam);
71 bool getOptions(int argc, const char **argv);
72 void print_pose(const vpHomogeneousMatrix &cMo, const std::string &legend);
73 int compare_pose(const vpPose &pose, const vpHomogeneousMatrix &cMo_ref, const vpHomogeneousMatrix &cMo_est,
74  const std::string &legend);
75 
76 
82 void usage(const char *name, const char *badparam)
83 {
84  fprintf(stdout, "\n\
85 Compute the pose of a 3D object using the Dementhon, Lagrange and\n\
86 Non-Linear approach.\n\
87 \n\
88 SYNOPSIS\n\
89  %s [-h]\n", name);
90 
91  fprintf(stdout, "\n\
92 OPTIONS: Default\n\
93  -h\n\
94  Print the help.\n");
95 
96  if (badparam)
97  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
98 }
106 bool getOptions(int argc, const char **argv)
107 {
108  const char *optarg_;
109  int c;
110  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
111 
112  switch (c) {
113  case 'h': usage(argv[0], NULL); return false; break;
114 
115  default:
116  usage(argv[0], optarg_);
117  return false; break;
118  }
119  }
120 
121  if ((c == 1) || (c == -1)) {
122  // standalone param or error
123  usage(argv[0], NULL);
124  std::cerr << "ERROR: " << std::endl;
125  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
126  return false;
127  }
128 
129  return true;
130 }
131 
132 // print the resulting estimated pose
133 void print_pose(const vpHomogeneousMatrix &cMo, const std::string &legend)
134 {
135  vpPoseVector cpo = vpPoseVector(cMo);
136 
137  std::cout << std::endl << legend << "\n "
138  << "tx = " << cpo[0] << "\n "
139  << "ty = " << cpo[1] << "\n "
140  << "tz = " << cpo[2] << "\n "
141  << "tux = vpMath::rad(" << vpMath::deg(cpo[3]) << ")\n "
142  << "tuy = vpMath::rad(" << vpMath::deg(cpo[4]) << ")\n "
143  << "tuz = vpMath::rad(" << vpMath::deg(cpo[5]) << ")\n"
144  << std::endl;
145 }
146 
147 // test if pose is well estimated
148 int compare_pose(const vpPose &pose, const vpHomogeneousMatrix &cMo_ref, const vpHomogeneousMatrix &cMo_est,
149  const std::string &legend)
150 {
151  vpPoseVector pose_ref = vpPoseVector(cMo_ref);
152  vpPoseVector pose_est = vpPoseVector(cMo_est);
153 
154  int fail = 0;
155 
156  // Test done on the 3D pose
157  for(unsigned int i=0; i<6; i++) {
158  if (std::fabs(pose_ref[i]-pose_est[i]) > 0.001)
159  fail = 1;
160  }
161 
162  std::cout << "Based on 3D parameters " << legend << " is " << (fail ? "badly" : "well") << " estimated" << std::endl;
163 
164  // Test done on the residual
165  double r = pose.computeResidual(cMo_est);
166  if (pose.listP.size() < 4) {
167  fail = 1;
168  std::cout << "Not enough point" << std::endl;
169  return fail;
170  }
171  r = sqrt(r)/pose.listP.size();
172  //std::cout << "Residual on each point (meter): " << r << std::endl;
173  fail = (r > 0.1) ? 1 : 0;
174  std::cout << "Based on 2D residual (" << r << ") " << legend << " is " << (fail ? "badly" : "well") << " estimated" << std::endl;
175  return fail;
176 }
177 
178 int
179 main(int argc, const char ** argv)
180 {
181  try {
182  // Read the command line options
183  if (getOptions(argc, argv) == false) {
184  exit (-1);
185  }
186 
187  vpPoint P[5] ; // Point to be tracked
188  vpPose pose ;
189  pose.clearPoint() ;
190 
191  P[0].setWorldCoordinates(-L,-L, 0 ) ;
192  P[1].setWorldCoordinates(L,-L, 0 ) ;
193  P[2].setWorldCoordinates(L,L, 0 ) ;
194  P[3].setWorldCoordinates(-2*L, 3*L, 0 ) ;
195  P[4].setWorldCoordinates(-L,L, 0.01 ) ;
196  //P[3].setWorldCoordinates(-L,L, 0 ) ;
197 
198  int test_fail = 0, fail = 0;
199  vpPoseVector cpo_ref = vpPoseVector(0.01, 0.02, 0.25, vpMath::rad(5), 0,vpMath::rad(10));
200  vpHomogeneousMatrix cMo_ref(cpo_ref) ;
201  vpHomogeneousMatrix cMo ; // will contain the estimated pose
202 
203  for(int i=0 ; i < 5 ; i++) {
204  P[i].project(cMo_ref) ;
205  //P[i].print();
206  pose.addPoint(P[i]) ; // and added to the pose computation class
207  }
208 
209  // Let's go ...
210  print_pose(cMo_ref, std::string("Reference pose")); // print the reference pose
211 
212  std::cout <<"-------------------------------------------------"<<std::endl ;
213  pose.computePose(vpPose::LAGRANGE, cMo) ;
214 
215  print_pose(cMo, std::string("Pose estimated by Lagrange"));
216  fail = compare_pose(pose, cMo_ref, cMo, "pose by Lagrange");
217  test_fail |= fail;
218 
219  std::cout <<"--------------------------------------------------"<<std::endl ;
220  pose.computePose(vpPose::DEMENTHON, cMo) ;
221 
222  print_pose(cMo, std::string("Pose estimated by Dementhon"));
223  fail = compare_pose(pose, cMo_ref, cMo, "pose by Dementhon");
224  test_fail |= fail;
225 
226  std::cout <<"--------------------------------------------------"<<std::endl ;
228  pose.setRansacThreshold(0.01);
229  pose.computePose(vpPose::RANSAC, cMo) ;
230 
231  print_pose(cMo, std::string("Pose estimated by Ransac"));
232  fail = compare_pose(pose, cMo_ref, cMo, "pose by Ransac");
233  test_fail |= fail;
234 
235  std::cout <<"--------------------------------------------------"<<std::endl ;
237 
238  print_pose(cMo, std::string("Pose estimated by Lagrange than Lowe"));
239  fail = compare_pose(pose, cMo_ref, cMo, "pose by Lagrange than Lowe");
240  test_fail |= fail;
241 
242  std::cout <<"--------------------------------------------------"<<std::endl ;
244 
245  print_pose(cMo, std::string("Pose estimated by Dementhon than Lowe"));
246  fail = compare_pose(pose, cMo_ref, cMo, "pose by Dementhon than Lowe");
247  test_fail |= fail;
248 
249  // Now Virtual Visual servoing
250 
251  std::cout <<"--------------------------------------------------"<<std::endl ;
252  pose.computePose(vpPose::VIRTUAL_VS, cMo) ;
253 
254  print_pose(cMo, std::string("Pose estimated by VVS"));
255  fail = compare_pose(pose, cMo_ref, cMo, "pose by VVS");
256  test_fail |= fail;
257 
258  std::cout <<"-------------------------------------------------"<<std::endl ;
260 
261  print_pose(cMo, std::string("Pose estimated by Dementhon than by VVS"));
262  fail = compare_pose(pose, cMo_ref, cMo, "pose by Dementhon than by VVS");
263  test_fail |= fail;
264 
265  std::cout <<"-------------------------------------------------"<<std::endl ;
267 
268  print_pose(cMo, std::string("Pose estimated by Lagrange than by VVS"));
269  fail = compare_pose(pose, cMo_ref, cMo, "pose by Lagrange than by VVS");
270  test_fail |= fail;
271 
272  std::cout << "\nGlobal pose estimation test " << (test_fail ? "fail" : "is ok") << std::endl;
273 
274  return test_fail;
275  }
276  catch(vpException e) {
277  std::cout << "Catch an exception: " << e << std::endl;
278  return 1;
279  }
280 }
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
error that can be emited by ViSP classes.
Definition: vpException.h:76
void setRansacThreshold(const double &t)
Definition: vpPose.h:170
std::list< vpPoint > listP
array of point (use here class vpPoint)
Definition: vpPose.h:95
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:79
Class that defines what is a point.
Definition: vpPoint.h:65
Class used for pose computation from N points (pose from point only).
Definition: vpPose.h:78
static double rad(double deg)
Definition: vpMath.h:100
void setRansacNbInliersToReachConsensus(const unsigned int &nbC)
Definition: vpPose.h:169
static double deg(double rad)
Definition: vpMath.h:93
The pose is a complete representation of every rigid motion in the euclidian space.
Definition: vpPoseVector.h:92
void computePose(vpPoseMethodType methode, vpHomogeneousMatrix &cMo)
compute the pose for a given method
Definition: vpPose.cpp:386
void addPoint(const vpPoint &P)
Add a new point in this array.
Definition: vpPose.cpp:155
double computeResidual(const vpHomogeneousMatrix &cMo) const
Compute and return the residual expressed in meter for the pose matrix 'cMo'.
Definition: vpPose.cpp:344
void setWorldCoordinates(const double ox, const double oy, const double oz)
Set the point world coordinates. We mean here the coordinates of the point in the object frame...
Definition: vpPoint.cpp:74
void clearPoint()
suppress all the point in the array of point
Definition: vpPose.cpp:133