Visual Servoing Platform  version 3.6.1 under development (2025-03-13)
servoSimuSphere.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  * Demonstration of the wireframe simulator with a simple visual servoing
33  *
34 *****************************************************************************/
35 
42 #include <cmath> // std::fabs
43 #include <limits> // numeric_limits
44 #include <stdlib.h>
45 
46 #include <visp3/core/vpCameraParameters.h>
47 #include <visp3/core/vpConfig.h>
48 #include <visp3/core/vpHomogeneousMatrix.h>
49 #include <visp3/core/vpImage.h>
50 #include <visp3/core/vpIoTools.h>
51 #include <visp3/core/vpMath.h>
52 #include <visp3/core/vpSphere.h>
53 #include <visp3/core/vpTime.h>
54 #include <visp3/core/vpVelocityTwistMatrix.h>
55 #include <visp3/gui/vpDisplayFactory.h>
56 #include <visp3/gui/vpPlot.h>
57 #include <visp3/io/vpImageIo.h>
58 #include <visp3/io/vpParseArgv.h>
59 #include <visp3/robot/vpSimulatorCamera.h>
60 #include <visp3/robot/vpWireFrameSimulator.h>
61 #include <visp3/visual_features/vpFeatureBuilder.h>
62 #include <visp3/visual_features/vpGenericFeature.h>
63 #include <visp3/vs/vpServo.h>
64 
65 #define GETOPTARGS "dhp"
66 
67 #if defined(VISP_HAVE_DISPLAY) && (defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
68 
69 #if defined(ENABLE_VISP_NAMESPACE)
70 using namespace VISP_NAMESPACE_NAME;
71 #endif
72 
81 void usage(const char *name, const char *badparam)
82 {
83  fprintf(stdout, "\n\
84 Demonstration of the wireframe simulator with a simple visual servoing.\n\
85  \n\
86 The visual servoing consists in bringing the camera at a desired position from the object.\n\
87  \n\
88 The visual features used to compute the pose of the camera and thus the control law are special moments computed with the sphere's parameters.\n\
89  \n\
90 SYNOPSIS\n\
91  %s [-d] [-p] [-h]\n",
92  name);
93 
94  fprintf(stdout, "\n\
95 OPTIONS: Default\n\
96  -d \n\
97  Turn off the display.\n\
98  \n\
99  -p \n\
100  Turn off the plotter.\n\
101  \n\
102  -h\n\
103  Print the help.\n");
104 
105  if (badparam)
106  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
107 }
108 
121 bool getOptions(int argc, const char **argv, bool &display, bool &plot)
122 {
123  const char *optarg_;
124  int c;
125  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
126 
127  switch (c) {
128  case 'd':
129  display = false;
130  break;
131  case 'p':
132  plot = false;
133  break;
134  case 'h':
135  usage(argv[0], nullptr);
136  return false;
137 
138  default:
139  usage(argv[0], optarg_);
140  return false;
141  }
142  }
143 
144  if ((c == 1) || (c == -1)) {
145  // standalone param or error
146  usage(argv[0], nullptr);
147  std::cerr << "ERROR: " << std::endl;
148  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
149  return false;
150  }
151 
152  return true;
153 }
154 
155 /*
156  Computes the virtual visual features corresponding to the sphere and stores
157  it in the generic feature.
158 
159  The visual feature vector is computed thanks to the following formula : s =
160  {sx, sy, sz} sx = gx*h2/(sqrt(h2+1) sx = gy*h2/(sqrt(h2+1) sz = sqrt(h2+1)
161 
162  with gx and gy the center of gravity of the ellipse,
163  with h2 = (gx²+gy²)/(4*n20*gy²+4*n02*gx²-8n11gxgy)
164  with n20,n02,n11 the second order centered moments of the sphere normalized by its area
165  (i.e., such that \f$n_{ij} = \mu_{ij}/a\f$ where \f$\mu_{ij}\f$ are the centered moments and a the area)
166 */
167 void computeVisualFeatures(const vpSphere &sphere, vpGenericFeature &s)
168 {
169  double gx = sphere.get_x();
170  double gy = sphere.get_y();
171  double n02 = sphere.get_n02();
172  double n20 = sphere.get_n20();
173  double n11 = sphere.get_n11();
174  double h2;
175  // if (gx != 0 || gy != 0)
176  if (std::fabs(gx) > std::numeric_limits<double>::epsilon() || std::fabs(gy) > std::numeric_limits<double>::epsilon())
177  h2 = (vpMath::sqr(gx) + vpMath::sqr(gy)) /
178  (4 * n20 * vpMath::sqr(gy) + 4 * n02 * vpMath::sqr(gx) - 8 * n11 * gx * gy);
179  else
180  h2 = 1 / (4 * n20);
181 
182  double sx = gx * h2 / (sqrt(h2 + 1));
183  double sy = gy * h2 / (sqrt(h2 + 1));
184  double sz = sqrt(h2 + 1); //(h2-(vpMath::sqr(sx)+vpMath::sqr(sy)-1))/(2*sqrt(h2));
185 
186  s.set_s(sx, sy, sz);
187 }
188 
189 /*
190  Computes the interaction matrix such as L = [-1/R*I3 [s]x]
191 
192  with R the radius of the sphere
193  with I3 the 3x3 identity matrix
194  with [s]x the skew matrix related to s
195 */
196 void computeInteractionMatrix(const vpGenericFeature &s, const vpSphere &sphere, vpMatrix &L)
197 {
198  L = 0;
199  L[0][0] = -1 / sphere.getR();
200  L[1][1] = -1 / sphere.getR();
201  L[2][2] = -1 / sphere.getR();
202 
203  double s0, s1, s2;
204  s.get_s(s0, s1, s2);
205 
206  vpTranslationVector c(s0, s1, s2);
207  vpMatrix sk;
208  sk = c.skew();
209 
210  for (unsigned int i = 0; i < 3; i++)
211  for (unsigned int j = 0; j < 3; j++)
212  L[i][j + 3] = sk[i][j];
213 }
214 
215 int main(int argc, const char **argv)
216 {
217  const unsigned int NB_DISPLAYS = 3;
218 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
219  std::shared_ptr<vpDisplay> display[NB_DISPLAYS];
220  for (unsigned int i = 0; i < NB_DISPLAYS; ++i) {
221  display[i] = vpDisplayFactory::createDisplay();
222  }
223 #else
224  vpDisplay *display[NB_DISPLAYS];
225  for (unsigned int i = 0; i < NB_DISPLAYS; ++i) {
226  display[i] = vpDisplayFactory::allocateDisplay();
227  }
228 #endif
229  unsigned int exit_status = EXIT_SUCCESS;
230  try {
231  bool opt_display = true;
232  bool opt_plot = true;
233 
234  // Read the command line options
235  if (getOptions(argc, argv, opt_display, opt_plot) == false) {
236  return EXIT_FAILURE;
237  }
238 
239  vpImage<vpRGBa> Iint(480, 640, vpRGBa(255));
240  vpImage<vpRGBa> Iext1(480, 640, vpRGBa(255));
241  vpImage<vpRGBa> Iext2(480, 640, vpRGBa(255));
242 
243  if (opt_display) {
244  // Display size is automatically defined by the image (I) size
245  display[0]->init(Iint, 100, 100, "The internal view");
246  display[1]->init(Iext1, 100, 100, "The first external view");
247  display[2]->init(Iext2, 100, 100, "The second external view");
248  vpDisplay::setWindowPosition(Iint, 0, 0);
249  vpDisplay::setWindowPosition(Iext1, 750, 0);
250  vpDisplay::setWindowPosition(Iext2, 0, 550);
251  vpDisplay::display(Iint);
252  vpDisplay::flush(Iint);
253  vpDisplay::display(Iext1);
254  vpDisplay::flush(Iext1);
255  vpDisplay::display(Iext2);
256  vpDisplay::flush(Iext2);
257  }
258 
259  vpPlot *plotter = nullptr;
260 
261  vpServo task;
262  vpSimulatorCamera robot;
263  float sampling_time = 0.020f; // Sampling period in second
264  robot.setSamplingTime(sampling_time);
265 
266  // Since the task gain lambda is very high, we need to increase default
267  // max velocities
268  robot.setMaxTranslationVelocity(10);
270 
271  // Set initial position of the object in the camera frame
272  vpHomogeneousMatrix cMo(0, 0.1, 2.0, vpMath::rad(35), vpMath::rad(25), 0);
273  // Set desired position of the object in the camera frame
274  vpHomogeneousMatrix cdMo(0.0, 0.0, 0.8, vpMath::rad(0), vpMath::rad(0), vpMath::rad(0));
275  // Set initial position of the object in the world frame
276  vpHomogeneousMatrix wMo(0.0, 0.0, 0, 0, 0, 0);
277  // Position of the camera in the world frame
279  wMc = wMo * cMo.inverse();
280 
281  robot.setPosition(wMc);
282 
283  // The sphere
284  vpSphere sphere(0, 0, 0, 0.15);
285 
286  // Projection of the sphere
287  sphere.track(cMo);
288 
289  // Set the current visual feature
290  vpGenericFeature s(3);
291  computeVisualFeatures(sphere, s);
292 
293  // Projection of the points
294  sphere.track(cdMo);
295 
296  vpGenericFeature sd(3);
297  computeVisualFeatures(sphere, sd);
298 
299  vpMatrix L(3, 6);
300  computeInteractionMatrix(sd, sphere, L);
301  sd.setInteractionMatrix(L);
302 
305 
307  vpVelocityTwistMatrix cVe(cMe);
308  task.set_cVe(cVe);
309 
310  vpMatrix eJe;
311  robot.get_eJe(eJe);
312  task.set_eJe(eJe);
313 
314  task.addFeature(s, sd);
315 
316  task.setLambda(7);
317 
318  if (opt_plot) {
319  plotter = new vpPlot(2, 480, 640, 750, 550, "Real time curves plotter");
320  plotter->setTitle(0, "Visual features error");
321  plotter->setTitle(1, "Camera velocities");
322  plotter->initGraph(0, task.getDimension());
323  plotter->initGraph(1, 6);
324  plotter->setLegend(0, 0, "error_feat_sx");
325  plotter->setLegend(0, 1, "error_feat_sy");
326  plotter->setLegend(0, 2, "error_feat_sz");
327  plotter->setLegend(1, 0, "vc_x");
328  plotter->setLegend(1, 1, "vc_y");
329  plotter->setLegend(1, 2, "vc_z");
330  plotter->setLegend(1, 3, "wc_x");
331  plotter->setLegend(1, 4, "wc_y");
332  plotter->setLegend(1, 5, "wc_z");
333  }
334 
336 
337  // Set the scene
339 
340  // Initialize simulator frames
341  sim.set_fMo(wMo); // Position of the object in the world reference frame
342  sim.setCameraPositionRelObj(cMo); // Initial position of the object in the camera frame
343  sim.setDesiredCameraPosition(cdMo); // Desired position of the object in the camera frame
344 
345  // Set the External camera position
346  vpHomogeneousMatrix camMf(0.0, 0, 3.5, vpMath::rad(0), vpMath::rad(30), 0);
347  sim.setExternalCameraPosition(camMf);
348 
349  // Computes the position of a camera which is fixed in the object frame
350  vpHomogeneousMatrix camoMf(0, 0.0, 2.5, 0, vpMath::rad(140), 0);
351  camoMf = camoMf * (sim.get_fMo().inverse());
352 
353  // Set the parameters of the cameras (internal and external)
354  vpCameraParameters camera(1000, 1000, 320, 240);
355  sim.setInternalCameraParameters(camera);
356  sim.setExternalCameraParameters(camera);
357 
358  int max_iter = 10;
359 
360  if (opt_display) {
361  max_iter = 1000;
362  // Get the internal and external views
363  sim.getInternalImage(Iint);
364  sim.getExternalImage(Iext1);
365  sim.getExternalImage(Iext2, camoMf);
366 
367  // Display the object frame (current and desired position)
368  vpDisplay::displayFrame(Iint, cMo, camera, 0.2, vpColor::none);
369  vpDisplay::displayFrame(Iint, cdMo, camera, 0.2, vpColor::none);
370 
371  // Display the object frame the world reference frame and the camera
372  // frame
373  vpDisplay::displayFrame(Iext1, camMf * sim.get_fMo() * cMo.inverse(), camera, 0.2, vpColor::none);
374  vpDisplay::displayFrame(Iext1, camMf * sim.get_fMo(), camera, 0.2, vpColor::none);
375  vpDisplay::displayFrame(Iext1, camMf, camera, 0.2, vpColor::none);
376 
377  // Display the world reference frame and the object frame
378  vpDisplay::displayFrame(Iext2, camoMf, camera, 0.2, vpColor::none);
379  vpDisplay::displayFrame(Iext2, camoMf * sim.get_fMo(), camera, 0.05, vpColor::none);
380 
381  vpDisplay::displayText(Iint, 20, 20, "Click to start visual servo", vpColor::red);
382 
383  vpDisplay::flush(Iint);
384  vpDisplay::flush(Iext1);
385  vpDisplay::flush(Iext2);
386 
387  std::cout << "Click on a display" << std::endl;
388  while (!vpDisplay::getClick(Iint, false) && !vpDisplay::getClick(Iext1, false) &&
389  !vpDisplay::getClick(Iext2, false)) {
390  };
391  }
392 
393  // Print the task
394  task.print();
395 
396  int iter = 0;
397  bool stop = false;
398  vpColVector v;
399 
400  double t_prev, t = vpTime::measureTimeMs();
401 
402  while (iter++ < max_iter && !stop) {
403  t_prev = t;
404  t = vpTime::measureTimeMs();
405 
406  if (opt_display) {
407  vpDisplay::display(Iint);
408  vpDisplay::display(Iext1);
409  vpDisplay::display(Iext2);
410  }
411 
412  robot.get_eJe(eJe);
413  task.set_eJe(eJe);
414 
415  wMc = robot.getPosition();
416  cMo = wMc.inverse() * wMo;
417 
418  sphere.track(cMo);
419 
420  // Set the current visual feature
421  computeVisualFeatures(sphere, s);
422 
423  v = task.computeControlLaw();
425  sim.setCameraPositionRelObj(cMo);
426 
427  // Compute the position of the external view which is fixed in the object frame
428  camoMf.buildFrom(0, 0.0, 2.5, 0, vpMath::rad(150), 0);
429  camoMf = camoMf * (sim.get_fMo().inverse());
430 
431  if (opt_plot) {
432  plotter->plot(0, iter, task.getError());
433  plotter->plot(1, iter, v);
434  }
435 
436  if (opt_display) {
437  // Get the internal and external views
438  sim.getInternalImage(Iint);
439  sim.getExternalImage(Iext1);
440  sim.getExternalImage(Iext2, camoMf);
441 
442  // Display the object frame (current and desired position)
443  vpDisplay::displayFrame(Iint, cMo, camera, 0.2, vpColor::none);
444  vpDisplay::displayFrame(Iint, cdMo, camera, 0.2, vpColor::none);
445 
446  // Display the camera frame, the object frame the world reference
447  // frame
448  vpDisplay::displayFrame(Iext1, sim.getExternalCameraPosition() * sim.get_fMo() * cMo.inverse(), camera, 0.2,
449  vpColor::none);
450  vpDisplay::displayFrame(Iext1, sim.getExternalCameraPosition() * sim.get_fMo(), camera, 0.2, vpColor::none);
452 
453  // Display the world reference frame and the object frame
454  vpDisplay::displayFrame(Iext2, camoMf, camera, 0.2, vpColor::none);
455  vpDisplay::displayFrame(Iext2, camoMf * sim.get_fMo(), camera, 0.05, vpColor::none);
456 
457  vpDisplay::displayText(Iint, 20, 20, "Click to stop visual servo", vpColor::red);
458 
459  std::stringstream ss;
460  ss << "Loop time: " << t - t_prev << " ms";
461  vpDisplay::displayText(Iint, 40, 20, ss.str(), vpColor::red);
462 
463  if (vpDisplay::getClick(Iint, false)) {
464  stop = true;
465  }
466 
467  vpDisplay::flush(Iint);
468  vpDisplay::flush(Iext1);
469  vpDisplay::flush(Iext2);
470 
471  vpTime::wait(t, sampling_time * 1000); // Wait ms
472  }
473 
474  std::cout << "|| s - s* || = " << (task.getError()).sumSquare() << std::endl;
475  }
476 
477  if (opt_plot && plotter != nullptr) {
478  vpDisplay::display(Iint);
479  sim.getInternalImage(Iint);
480  vpDisplay::displayFrame(Iint, cMo, camera, 0.2, vpColor::none);
481  vpDisplay::displayFrame(Iint, cdMo, camera, 0.2, vpColor::none);
482  vpDisplay::displayText(Iint, 20, 20, "Click to quit", vpColor::red);
483  if (vpDisplay::getClick(Iint)) {
484  stop = true;
485  }
486  vpDisplay::flush(Iint);
487 
488  delete plotter;
489  }
490 
491  task.print();
492  exit_status = EXIT_SUCCESS;
493  }
494  catch (const vpException &e) {
495  std::cout << "Catch an exception: " << e << std::endl;
496  exit_status = EXIT_FAILURE;
497  }
498 
499 #if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
500  for (unsigned int i = 0; i < NB_DISPLAYS; ++i) {
501  delete display[i];
502  }
503 #endif
504 
505  return exit_status;
506 }
507 #elif !(defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
508 int main()
509 {
510  std::cout << "Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
511  return EXIT_SUCCESS;
512 }
513 #else
514 int main()
515 {
516  std::cout << "You do not have X11, or GDI (Graphical Device Interface), or GTK functionalities to display images..."
517  << std::endl;
518  std::cout << "Tip if you are on a unix-like system:" << std::endl;
519  std::cout << "- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
520  std::cout << "Tip if you are on a windows-like system:" << std::endl;
521  std::cout << "- Install GDI, configure again ViSP using cmake and build again this example" << std::endl;
522  return EXIT_SUCCESS;
523 }
524 #endif
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
static const vpColor red
Definition: vpColor.h:198
static const vpColor none
Definition: vpColor.h:210
Class that defines generic functionalities for display.
Definition: vpDisplay.h:178
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void displayFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double size, const vpColor &color=vpColor::none, unsigned int thickness=1, const vpImagePoint &offset=vpImagePoint(0, 0), const std::string &frameName="", const vpColor &textColor=vpColor::black, const vpImagePoint &textOffset=vpImagePoint(15, 15))
static void flush(const vpImage< unsigned char > &I)
static void setWindowPosition(const vpImage< unsigned char > &I, int winx, int winy)
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
error that can be emitted by ViSP classes.
Definition: vpException.h:60
void track(const vpHomogeneousMatrix &cMo)
Class that enables to define a feature or a set of features which are not implemented in ViSP as a sp...
void get_s(vpColVector &s) const
get the value of all the features.
void set_s(const vpColVector &s)
set the value of all the features.
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpHomogeneousMatrix inverse() const
static double rad(double deg)
Definition: vpMath.h:129
static double sqr(double x)
Definition: vpMath.h:203
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:70
This class enables real time drawing of 2D or 3D graphics. An instance of the class open a window whi...
Definition: vpPlot.h:112
void initGraph(unsigned int graphNum, unsigned int curveNbr)
Definition: vpPlot.cpp:203
void setLegend(unsigned int graphNum, unsigned int curveNum, const std::string &legend)
Definition: vpPlot.cpp:552
void plot(unsigned int graphNum, unsigned int curveNum, double x, double y)
Definition: vpPlot.cpp:270
void setTitle(unsigned int graphNum, const std::string &title)
Definition: vpPlot.cpp:510
Definition: vpRGBa.h:70
void get_eJe(vpMatrix &eJe) VP_OVERRIDE
void setVelocity(const vpRobot::vpControlFrameType frame, const vpColVector &vel) VP_OVERRIDE
@ CAMERA_FRAME
Definition: vpRobot.h:84
void setMaxRotationVelocity(double maxVr)
Definition: vpRobot.cpp:261
void setMaxTranslationVelocity(double maxVt)
Definition: vpRobot.cpp:240
void setInteractionMatrixType(const vpServoIteractionMatrixType &interactionMatrixType, const vpServoInversionType &interactionMatrixInversion=PSEUDO_INVERSE)
Definition: vpServo.cpp:380
@ EYEINHAND_L_cVe_eJe
Definition: vpServo.h:168
unsigned int getDimension() const
Definition: vpServo.cpp:366
void addFeature(vpBasicFeature &s_cur, vpBasicFeature &s_star, unsigned int select=vpBasicFeature::FEATURE_ALL)
Definition: vpServo.cpp:331
void set_cVe(const vpVelocityTwistMatrix &cVe_)
Definition: vpServo.h:1043
void print(const vpServo::vpServoPrintType display_level=ALL, std::ostream &os=std::cout)
Definition: vpServo.cpp:171
void setLambda(double c)
Definition: vpServo.h:991
void set_eJe(const vpMatrix &eJe_)
Definition: vpServo.h:1106
void setServo(const vpServoType &servo_type)
Definition: vpServo.cpp:134
vpColVector getError() const
Definition: vpServo.h:515
vpColVector computeControlLaw()
Definition: vpServo.cpp:705
@ DESIRED
Definition: vpServo.h:208
Class that defines the simplest robot: a free flying camera.
Class that defines a 3D sphere in the object frame and allows forward projection of a 3D sphere in th...
Definition: vpSphere.h:80
double get_n02() const
Definition: vpSphere.h:106
double get_y() const
Definition: vpSphere.h:102
double get_n11() const
Definition: vpSphere.h:105
double get_x() const
Definition: vpSphere.h:101
double getR() const
Definition: vpSphere.h:111
double get_n20() const
Definition: vpSphere.h:104
Class that consider the case of a translation vector.
Implementation of a wire frame simulator. Compared to the vpSimulator class, it does not require thir...
vpHomogeneousMatrix getExternalCameraPosition() const
void setCameraPositionRelObj(const vpHomogeneousMatrix &cMo_)
void getInternalImage(vpImage< unsigned char > &I)
void initScene(const vpSceneObject &obj, const vpSceneDesiredObject &desiredObject)
void setExternalCameraPosition(const vpHomogeneousMatrix &cam_Mf)
void set_fMo(const vpHomogeneousMatrix &fMo_)
vpHomogeneousMatrix get_fMo() const
void setDesiredCameraPosition(const vpHomogeneousMatrix &cdMo_)
void setInternalCameraParameters(const vpCameraParameters &cam)
void setExternalCameraParameters(const vpCameraParameters &cam)
@ SPHERE
A 15cm radius sphere.
void getExternalImage(vpImage< unsigned char > &I)
std::shared_ptr< vpDisplay > createDisplay()
Return a smart pointer vpDisplay specialization if a GUI library is available or nullptr otherwise.
vpDisplay * allocateDisplay()
Return a newly allocated vpDisplay specialization if a GUI library is available or nullptr otherwise.
VISP_EXPORT int wait(double t0, double t)
VISP_EXPORT double measureTimeMs()