Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
servoSimu4Points.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 <stdlib.h>
43 
44 #include <visp3/core/vpCameraParameters.h>
45 #include <visp3/core/vpHomogeneousMatrix.h>
46 #include <visp3/core/vpImage.h>
47 #include <visp3/core/vpIoTools.h>
48 #include <visp3/core/vpMath.h>
49 #include <visp3/core/vpTime.h>
50 #include <visp3/core/vpVelocityTwistMatrix.h>
51 #include <visp3/gui/vpDisplayD3D.h>
52 #include <visp3/gui/vpDisplayGDI.h>
53 #include <visp3/gui/vpDisplayGTK.h>
54 #include <visp3/gui/vpDisplayOpenCV.h>
55 #include <visp3/gui/vpDisplayX.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/vpFeaturePoint.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 \n\
87 position from the object.\n\
88  \n\
89 The visual features used to compute the pose of the camera and \n\
90 thus the control law are four points.\n\
91  \n\
92 This demonstration explains also how to move the object around a world\n\
93 reference frame. Here, the movement is a rotation around the x and y axis\n\
94 at a given distance from the world frame. In fact the object trajectory\n\
95 is on a sphere whose center is the origin of the world frame.\n\
96  \n\
97 SYNOPSIS\n\
98  %s [-d] [-p] [-h]\n",
99  name);
100 
101  fprintf(stdout, "\n\
102 OPTIONS: Default\n\
103  -d \n\
104  Turn off the display.\n\
105  \n\
106  -p \n\
107  Turn off the plotter.\n\
108  \n\
109  -h\n\
110  Print the help.\n");
111 
112  if (badparam)
113  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
114 }
115 
128 bool getOptions(int argc, const char **argv, bool &display, bool &plot)
129 {
130  const char *optarg_;
131  int c;
132  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
133 
134  switch (c) {
135  case 'd':
136  display = false;
137  break;
138  case 'p':
139  plot = false;
140  break;
141  case 'h':
142  usage(argv[0], nullptr);
143  return false;
144 
145  default:
146  usage(argv[0], optarg_);
147  return false;
148  }
149  }
150 
151  if ((c == 1) || (c == -1)) {
152  // standalone param or error
153  usage(argv[0], nullptr);
154  std::cerr << "ERROR: " << std::endl;
155  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
156  return false;
157  }
158 
159  return true;
160 }
161 
162 int main(int argc, const char **argv)
163 {
164  try {
165  bool opt_display = true;
166  bool opt_plot = true;
167  std::string filename = vpIoTools::getParent(argv[0]) + "/mire.png";
168  std::cout << "Read " << filename << std::endl;
169 
170  // Read the command line options
171  if (getOptions(argc, argv, opt_display, opt_plot) == false) {
172  return EXIT_FAILURE;
173  }
174 
175  vpImage<vpRGBa> Iint(480, 640, vpRGBa(255));
176  vpImage<vpRGBa> Iext1(480, 640, vpRGBa(255));
177  vpImage<vpRGBa> Iext2(480, 640, vpRGBa(255));
178 
179 #if defined(VISP_HAVE_X11)
180  vpDisplayX display[3];
181 #elif defined(HAVE_OPENCV_HIGHGUI)
182  vpDisplayOpenCV display[3];
183 #elif defined(VISP_HAVE_GDI)
184  vpDisplayGDI display[3];
185 #elif defined(VISP_HAVE_D3D9)
186  vpDisplayD3D display[3];
187 #elif defined(VISP_HAVE_GTK)
188  vpDisplayGTK display[3];
189 #endif
190 
191  if (opt_display) {
192  // Display size is automatically defined by the image (I) size
193  display[0].init(Iint, 100, 100, "The internal view");
194  display[1].init(Iext1, 100, 100, "The first external view");
195  display[2].init(Iext2, 100, 100, "The second external view");
196  vpDisplay::setWindowPosition(Iint, 0, 0);
197  vpDisplay::setWindowPosition(Iext1, 750, 0);
198  vpDisplay::setWindowPosition(Iext2, 0, 550);
199  vpDisplay::display(Iint);
200  vpDisplay::flush(Iint);
201  vpDisplay::display(Iext1);
202  vpDisplay::flush(Iext1);
203  vpDisplay::display(Iext2);
204  vpDisplay::flush(Iext2);
205  }
206 
207  vpPlot *plotter = nullptr;
208 
209  if (opt_plot) {
210  plotter = new vpPlot(2, 480, 640, 750, 550, "Real time curves plotter");
211  plotter->setTitle(0, "Visual features error");
212  plotter->setTitle(1, "Camera velocities");
213  plotter->initGraph(0, 8);
214  plotter->initGraph(1, 6);
215  plotter->setLegend(0, 0, "error_feat_p1_x");
216  plotter->setLegend(0, 1, "error_feat_p1_y");
217  plotter->setLegend(0, 2, "error_feat_p2_x");
218  plotter->setLegend(0, 3, "error_feat_p2_y");
219  plotter->setLegend(0, 4, "error_feat_p3_x");
220  plotter->setLegend(0, 5, "error_feat_p3_y");
221  plotter->setLegend(0, 6, "error_feat_p4_x");
222  plotter->setLegend(0, 7, "error_feat_p4_y");
223  plotter->setLegend(1, 0, "vc_x");
224  plotter->setLegend(1, 1, "vc_y");
225  plotter->setLegend(1, 2, "vc_z");
226  plotter->setLegend(1, 3, "wc_x");
227  plotter->setLegend(1, 4, "wc_y");
228  plotter->setLegend(1, 5, "wc_z");
229  }
230 
231  vpServo task;
232  vpSimulatorCamera robot;
233  float sampling_time = 0.020f; // Sampling period in second
234  robot.setSamplingTime(sampling_time);
235 
236  // Since the task gain lambda is very high, we need to increase default
237  // max velocities
238  robot.setMaxTranslationVelocity(10);
240 
241  // Set initial position of the object in the camera frame
242  vpHomogeneousMatrix cMo(0, 0.1, 2.0, vpMath::rad(35), vpMath::rad(25), 0);
243  // Set desired position of the object in the camera frame
244  vpHomogeneousMatrix cdMo(0.0, 0.0, 1.0, vpMath::rad(0), vpMath::rad(0), vpMath::rad(0));
245  // Set initial position of the object in the world frame
246  vpHomogeneousMatrix wMo(0.0, 0.0, 0.2, 0, 0, 0);
247  // Position of the camera in the world frame
249  wMc = wMo * cMo.inverse();
250 
251  // The four point used as visual features
252  vpPoint point[4];
253  point[0].setWorldCoordinates(-0.1, -0.1, 0);
254  point[3].setWorldCoordinates(-0.1, 0.1, 0);
255  point[2].setWorldCoordinates(0.1, 0.1, 0);
256  point[1].setWorldCoordinates(0.1, -0.1, 0);
257 
258  // Projection of the points
259  for (int i = 0; i < 4; i++)
260  point[i].track(cMo);
261 
262  // Set the current visual feature
263  vpFeaturePoint p[4];
264  for (int i = 0; i < 4; i++)
265  vpFeatureBuilder::create(p[i], point[i]);
266 
267  // Projection of the points
268  for (int i = 0; i < 4; i++)
269  point[i].track(cdMo);
270 
271  vpFeaturePoint pd[4];
272  for (int i = 0; i < 4; i++)
273  vpFeatureBuilder::create(pd[i], point[i]);
274 
277 
278  vpHomogeneousMatrix cMe; // Identity
279  vpVelocityTwistMatrix cVe(cMe);
280  task.set_cVe(cVe);
281 
282  vpMatrix eJe;
283  robot.get_eJe(eJe);
284  task.set_eJe(eJe);
285 
286  for (int i = 0; i < 4; i++)
287  task.addFeature(p[i], pd[i]);
288 
289  task.setLambda(10);
290 
291  std::list<vpImageSimulator> list;
292  vpImageSimulator imsim;
293 
294  vpColVector X[4];
295  for (int i = 0; i < 4; i++)
296  X[i].resize(3);
297  X[0][0] = -0.2;
298  X[0][1] = -0.2;
299  X[0][2] = 0;
300 
301  X[1][0] = 0.2;
302  X[1][1] = -0.2;
303  X[1][2] = 0;
304 
305  X[2][0] = 0.2;
306  X[2][1] = 0.2;
307  X[2][2] = 0;
308 
309  X[3][0] = -0.2;
310  X[3][1] = 0.2;
311  X[3][2] = 0;
312 
313  imsim.init(filename.c_str(), X);
314 
315  list.push_back(imsim);
316 
318 
319  // Set the scene
321 
322  // Initialize simulator frames
323  sim.set_fMo(wMo); // Position of the object in the world reference frame
324  sim.setCameraPositionRelObj(cMo); // Initial position of the object in the camera frame
325  sim.setDesiredCameraPosition(cdMo); // Desired position of the object in the camera frame
326 
327  // Set the External camera position
328  vpHomogeneousMatrix camMf(vpHomogeneousMatrix(0.0, 0, 3.5, vpMath::rad(0), vpMath::rad(30), 0));
329  sim.setExternalCameraPosition(camMf);
330 
331  // Computes the position of a camera which is fixed in the object frame
332  vpHomogeneousMatrix camoMf(0, 0.0, 1.5, 0, vpMath::rad(140), 0);
333  camoMf = camoMf * (sim.get_fMo().inverse());
334 
335  // Set the parameters of the cameras (internal and external)
336  vpCameraParameters camera(1000, 1000, 320, 240);
337  sim.setInternalCameraParameters(camera);
338  sim.setExternalCameraParameters(camera);
339 
340  int max_iter = 10;
341 
342  if (opt_display) {
343  max_iter = 2500;
344 
345  // Get the internal and external views
346  sim.getInternalImage(Iint);
347  sim.getExternalImage(Iext1);
348  sim.getExternalImage(Iext2, camoMf);
349 
350  // Display the object frame (current and desired position)
351  vpDisplay::displayFrame(Iint, cMo, camera, 0.2, vpColor::none);
352  vpDisplay::displayFrame(Iint, cdMo, camera, 0.2, vpColor::none);
353 
354  // Display the object frame the world reference frame and the camera
355  // frame
356  vpDisplay::displayFrame(Iext1, camMf * sim.get_fMo() * cMo.inverse(), camera, 0.2, vpColor::none);
357  vpDisplay::displayFrame(Iext1, camMf * sim.get_fMo(), camera, 0.2, vpColor::none);
358  vpDisplay::displayFrame(Iext1, camMf, camera, 0.2, vpColor::none);
359 
360  // Display the world reference frame and the object frame
361  vpDisplay::displayFrame(Iext2, camoMf, camera, 0.2, vpColor::none);
362  vpDisplay::displayFrame(Iext2, camoMf * sim.get_fMo(), camera, 0.05, vpColor::none);
363 
364  vpDisplay::displayText(Iint, 20, 20, "Click to start visual servo", vpColor::red);
365 
366  vpDisplay::flush(Iint);
367  vpDisplay::flush(Iext1);
368  vpDisplay::flush(Iext2);
369 
370  std::cout << "Click on a display" << std::endl;
371 
372  while (!vpDisplay::getClick(Iint, false) && !vpDisplay::getClick(Iext1, false) &&
373  !vpDisplay::getClick(Iext2, false)) {
374  };
375  }
376 
377  robot.setPosition(wMc);
378  // Print the task
379  task.print();
380 
381  int iter = 0;
382  bool stop = false;
383  vpColVector v;
384 
385  double t_prev, t = vpTime::measureTimeMs();
386 
387  while (iter++ < max_iter && !stop) {
388  t_prev = t;
389  t = vpTime::measureTimeMs();
390 
391  if (opt_display) {
392  vpDisplay::display(Iint);
393  vpDisplay::display(Iext1);
394  vpDisplay::display(Iext2);
395  }
396 
397  robot.get_eJe(eJe);
398  task.set_eJe(eJe);
399 
400  wMc = robot.getPosition();
401  cMo = wMc.inverse() * wMo;
402  for (int i = 0; i < 4; i++) {
403  point[i].track(cMo);
404  vpFeatureBuilder::create(p[i], point[i]);
405  }
406 
407  v = task.computeControlLaw();
409 
410  // Compute the movement of the object around the world reference frame.
411  vpHomogeneousMatrix a(0, 0, 0.2, 0, 0, 0);
412  vpHomogeneousMatrix b(0, 0, 0, vpMath::rad(1.5 * iter), 0, 0);
413  vpHomogeneousMatrix c(0, 0, 0, 0, vpMath::rad(2.5 * iter), 0);
414 
415  // Move the object in the world frame
416  wMo = b * c * a;
417 
418  sim.set_fMo(wMo); // Move the object in the simulator
419  sim.setCameraPositionRelObj(cMo);
420 
421  // Compute the position of the external view which is fixed in the
422  // object frame
423  camoMf.build(0, 0.0, 1.5, 0, vpMath::rad(150), 0);
424  camoMf = camoMf * (sim.get_fMo().inverse());
425 
426  if (opt_plot) {
427  plotter->plot(0, iter, task.getError());
428  plotter->plot(1, iter, v);
429  }
430 
431  if (opt_display) {
432  // Get the internal and external views
433  sim.getInternalImage(Iint);
434  sim.getExternalImage(Iext1);
435  sim.getExternalImage(Iext2, camoMf);
436 
437  // Display the object frame (current and desired position)
438  vpDisplay::displayFrame(Iint, cMo, camera, 0.2, vpColor::none);
439  vpDisplay::displayFrame(Iint, cdMo, camera, 0.2, vpColor::none);
440 
441  // Display the camera frame, the object frame the world reference
442  // frame
443  vpDisplay::displayFrame(Iext1, sim.getExternalCameraPosition() * sim.get_fMo() * cMo.inverse(), camera, 0.2,
444  vpColor::none);
445  vpDisplay::displayFrame(Iext1, sim.getExternalCameraPosition() * sim.get_fMo(), camera, 0.2, vpColor::none);
447 
448  // Display the world reference frame and the object frame
449  vpDisplay::displayFrame(Iext2, camoMf, camera, 0.2, vpColor::none);
450  vpDisplay::displayFrame(Iext2, camoMf * sim.get_fMo(), camera, 0.05, vpColor::none);
451 
452  vpDisplay::displayText(Iint, 20, 20, "Click to stop visual servo", vpColor::red);
453 
454  std::stringstream ss;
455  ss << "Loop time: " << t - t_prev << " ms";
456  vpDisplay::displayText(Iint, 40, 20, ss.str(), vpColor::red);
457 
458  if (vpDisplay::getClick(Iint, false)) {
459  stop = true;
460  }
461  vpDisplay::flush(Iint);
462  vpDisplay::flush(Iext1);
463  vpDisplay::flush(Iext2);
464 
465  vpTime::wait(t, sampling_time * 1000); // Wait ms
466  }
467 
468  std::cout << "|| s - s* || = " << (task.getError()).sumSquare() << std::endl;
469  }
470 
471  if (opt_plot && plotter != nullptr) {
472  vpDisplay::display(Iint);
473  sim.getInternalImage(Iint);
474  vpDisplay::displayFrame(Iint, cMo, camera, 0.2, vpColor::none);
475  vpDisplay::displayFrame(Iint, cdMo, camera, 0.2, vpColor::none);
476  vpDisplay::displayText(Iint, 20, 20, "Click to quit", vpColor::red);
477  if (vpDisplay::getClick(Iint)) {
478  stop = true;
479  }
480  vpDisplay::flush(Iint);
481 
482  delete plotter;
483  }
484 
485  task.print();
486 
487  return EXIT_SUCCESS;
488  }
489  catch (const vpException &e) {
490  std::cout << "Catch an exception: " << e << std::endl;
491  return EXIT_FAILURE;
492  }
493 }
494 #elif !(defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
495 int main()
496 {
497  std::cout << "Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
498  return EXIT_SUCCESS;
499 }
500 #else
501 int main()
502 {
503  std::cout << "You do not have X11, or GDI (Graphical Device Interface), or GTK functionalities to display images..."
504  << std::endl;
505  std::cout << "Tip if you are on a unix-like system:" << std::endl;
506  std::cout << "- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
507  std::cout << "Tip if you are on a windows-like system:" << std::endl;
508  std::cout << "- Install GDI, configure again ViSP using cmake and build again this example" << std::endl;
509  return EXIT_SUCCESS;
510 }
511 
512 #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:217
static const vpColor none
Definition: vpColor.h:229
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed....
Definition: vpDisplayD3D.h:106
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:130
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:133
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:135
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
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
Class that defines a 2D point visual feature which is composed by two parameters that are the cartes...
void track(const vpHomogeneousMatrix &cMo)
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpHomogeneousMatrix inverse() const
Class which enables to project an image in the 3D space and get the view of a virtual camera.
void init(const vpImage< unsigned char > &I, vpColVector *X)
static std::string getParent(const std::string &pathname)
Definition: vpIoTools.cpp:1314
static double rad(double deg)
Definition: vpMath.h:129
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
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 setWorldCoordinates(double oX, double oY, double oZ)
Definition: vpPoint.cpp:111
Definition: vpRGBa.h:65
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
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:1038
void print(const vpServo::vpServoPrintType display_level=ALL, std::ostream &os=std::cout)
Definition: vpServo.cpp:171
void setLambda(double c)
Definition: vpServo.h:986
void set_eJe(const vpMatrix &eJe_)
Definition: vpServo.h:1101
void setServo(const vpServoType &servo_type)
Definition: vpServo.cpp:134
vpColVector getError() const
Definition: vpServo.h:510
vpColVector computeControlLaw()
Definition: vpServo.cpp:705
@ DESIRED
Definition: vpServo.h:208
Class that defines the simplest robot: a free flying camera.
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)
void getExternalImage(vpImage< unsigned char > &I)
VISP_EXPORT int wait(double t0, double t)
VISP_EXPORT double measureTimeMs()