Visual Servoing Platform  version 3.6.1 under development (2024-05-09)
wireframeSimulator.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
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/gui/vpDisplayD3D.h>
50 #include <visp3/gui/vpDisplayGDI.h>
51 #include <visp3/gui/vpDisplayGTK.h>
52 #include <visp3/gui/vpDisplayOpenCV.h>
53 #include <visp3/gui/vpDisplayX.h>
54 #include <visp3/io/vpImageIo.h>
55 #include <visp3/io/vpParseArgv.h>
56 #include <visp3/robot/vpWireFrameSimulator.h>
57 
58 #define GETOPTARGS "cdh"
59 
60 #ifdef VISP_HAVE_DISPLAY
61 
62 void usage(const char *name, const char *badparam);
63 bool getOptions(int argc, const char **argv, bool &display, bool &click);
64 
73 void usage(const char *name, const char *badparam)
74 {
75  fprintf(stdout, "\n\
76 Demonstration of the wireframe simulator.\n\
77 \n\
78 The goal of this example is to present the basic functionalities of the wire frame simulator.\n\
79 \n\
80 SYNOPSIS\n\
81  %s [-c] [-d] [-h]\n",
82  name);
83 
84  fprintf(stdout, "\n\
85 OPTIONS: Default\n\
86  -c \n\
87  Disable mouse click.\n\
88 \n\
89  -d \n\
90  Turn off the display.\n\
91 \n\
92  -h\n\
93  Print the help.\n");
94 
95  if (badparam)
96  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
97 }
98 
111 bool getOptions(int argc, const char **argv, bool &display, bool &click)
112 {
113  const char *optarg_;
114  int c;
115  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
116 
117  switch (c) {
118  case 'c':
119  click = false;
120  break;
121  case 'd':
122  display = false;
123  break;
124  case 'h':
125  usage(argv[0], nullptr);
126  return false;
127  break;
128 
129  default:
130  usage(argv[0], optarg_);
131  return false;
132  break;
133  }
134  }
135 
136  if ((c == 1) || (c == -1)) {
137  // standalone param or error
138  usage(argv[0], nullptr);
139  std::cerr << "ERROR: " << std::endl;
140  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
141  return false;
142  }
143 
144  return true;
145 }
146 
147 int main(int argc, const char **argv)
148 {
149  try {
150  bool opt_display = true;
151  bool opt_click = true;
152 
153  // Read the command line options
154  if (getOptions(argc, argv, opt_display, opt_click) == false) {
155  return EXIT_FAILURE;
156  }
157 
158  /*
159  Three vpImage are created : one for the main camera and the others
160  for two external cameras
161  */
162  vpImage<vpRGBa> Iint(480, 640, 255);
163  vpImage<vpRGBa> Iext1(480, 640, 255);
164  vpImage<vpRGBa> Iext2(480, 640, 255);
165 
166 /*
167 Create a display for each different cameras.
168 */
169 #if defined(VISP_HAVE_X11)
170  vpDisplayX display[3];
171 #elif defined(HAVE_OPENCV_HIGHGUI)
173 #elif defined(VISP_HAVE_GDI)
175 #elif defined(VISP_HAVE_D3D9)
177 #elif defined(VISP_HAVE_GTK)
179 #endif
180 
181  if (opt_display) {
182  // Display size is automatically defined by the image (I) size
183  display[0].init(Iint, 100, 100, "The internal view");
184  display[1].init(Iext1, 100, 100, "The first external view");
185  display[2].init(Iext2, 100, 100, "The second external view");
186  vpDisplay::setWindowPosition(Iint, 0, 0);
187  vpDisplay::setWindowPosition(Iext1, 700, 0);
188  vpDisplay::setWindowPosition(Iext2, 0, 550);
189  vpDisplay::display(Iint);
190  vpDisplay::flush(Iint);
191  vpDisplay::display(Iext1);
192  vpDisplay::flush(Iext1);
193  vpDisplay::display(Iext2);
194  vpDisplay::flush(Iext2);
195  }
196 
197  // The homogeneous matrix which gives the current position of the main
198  // camera relative to the object
199  vpHomogeneousMatrix cMo(0, 0.05, 1.3, vpMath::rad(15), vpMath::rad(25), 0);
200 
201  // The homogeneous matrix which gives the desired position of the main
202  // camera relative to the object
204 
205  // Declaration of the simulator
207  /*
208  Set the scene. It enables to choose the shape of the object and the shape
209  of the desired object which is displayed in the main camera view. It
210  exists several objects in ViSP. See the html documentation of the
211  simulator class to have the complete list.
212 
213  Note : if you don't want to have a desired object displayed in the main
214  camera view you can use the initObject Method.
215 
216  Here the object is a plate with 4 points and it is the same object which
217  is used to display the object at the desired position.
218  */
220 
221  /*
222  The object at the current position will be displayed in blue
223  The object at the desired position will be displayed in red
224  The camera will be display in green
225  */
229  /*
230  Set the position of the object frame in the current and desired camera frame
231  */
232  sim.setCameraPositionRelObj(cMo);
233  sim.setDesiredCameraPosition(cdMo);
234  /*
235  Set the main external camera's position relative to the world reference
236  frame. More information about the different frames are given in the html
237  documentation.
238  */
239  vpHomogeneousMatrix camMw(vpHomogeneousMatrix(0.0, 0, 4.5, vpMath::rad(0), vpMath::rad(-30), 0));
240  sim.setExternalCameraPosition(camMw);
241 
242  /*
243  Set the parameters of the cameras (internal and external)
244  */
245  vpCameraParameters camera(1000, 1000, 320, 240);
246  sim.setInternalCameraParameters(camera);
247  sim.setExternalCameraParameters(camera);
248 
249  vpHomogeneousMatrix camoMw(vpHomogeneousMatrix(-0.3, 0.2, 2.5, vpMath::rad(0), vpMath::rad(10), 0));
250 
251  if (opt_display) {
252  // Get the view of the internal camera
253  sim.getInternalImage(Iint);
254  // Get the view of the main external camera
255  sim.getExternalImage(Iext1);
256  // Get the view of an external camera that you can positionned thanks
257  // to a vpHomogeneousMatrix which describes the position of the world reference frame in the camera frame
258  sim.getExternalImage(Iext2, camoMw);
259  // Display the views.
260 
261  vpDisplay::flush(Iint);
262  vpDisplay::flush(Iext1);
263  vpDisplay::flush(Iext2);
264  }
265 
266  std::cout << std::endl;
267  std::cout << "Here are presented the effect of the basic functions of "
268  "the simulator"
269  << std::endl;
270  std::cout << std::endl;
271 
272  if (opt_display) {
273  if (opt_click) {
274  std::cout << "Click on the internal view window to continue. the "
275  "object will move. The external cameras are fixed. The "
276  "main camera moves too because the homogeneous matrix "
277  "cMo didn't change."
278  << std::endl;
279  vpDisplay::getClick(Iint);
280  }
281  vpDisplay::display(Iint);
282  vpDisplay::display(Iext1);
283  vpDisplay::display(Iext2);
284  }
285  /*
286  To move the object you have to define a vpHomogeneousMatrix which gives
287  the position of the object relative to the world refrenece frame.
288  */
289  vpHomogeneousMatrix mov(0.05, 0.05, 0.2, vpMath::rad(10), 0, 0);
290  sim.set_fMo(mov);
291 
292  if (opt_display) {
293  // Get the view of the internal camera
294  sim.getInternalImage(Iint);
295  // Get the view of the main external camera
296  sim.getExternalImage(Iext1);
297  // Get the view of an external camera that you can positionned thanks
298  // to a vpHomogeneousMatrix which describes the position of the world reference frame in the camera frame
299  sim.getExternalImage(Iext2, camoMw);
300  // Display the views.
301 
302  vpDisplay::flush(Iint);
303  vpDisplay::flush(Iext1);
304  vpDisplay::flush(Iext2);
305  }
306 
307  std::cout << std::endl;
308  if (opt_display) {
309  if (opt_click) {
310  std::cout << "Click on the internal view window to continue" << std::endl;
311  vpDisplay::getClick(Iint);
312  }
313  }
314  std::cout << std::endl;
315  std::cout << "Now you can move the main external camera. Click inside "
316  "the corresponding window with one of the three buttons of "
317  "your mouse and move the pointer."
318  << std::endl;
319  std::cout << std::endl;
320  std::cout << "Click on the internal view window when you are finished" << std::endl;
321 
322  /*
323  To move the main external camera you need a loop containing the
324  getExternalImage method. This functionnality is only available for the
325  main external camera.
326  */
327  if (opt_display && opt_click) {
328  while (!vpDisplay::getClick(Iint, false)) {
329  vpDisplay::display(Iext1);
330  sim.getExternalImage(Iext1);
331  vpDisplay::flush(Iext1);
332  }
333  }
334 
335  std::cout << std::endl;
336  std::cout << "You have seen the main capabilities of the simulator. "
337  "Other specific functionalities are available. Please "
338  "refers to the html documentation to access the list of all "
339  "functions"
340  << std::endl;
341  return EXIT_SUCCESS;
342  } catch (const vpException &e) {
343  std::cout << "Catch an exception: " << e << std::endl;
344  return EXIT_SUCCESS;
345  }
346 }
347 #else
348 int main()
349 {
350  std::cout << "You do not have X11, or GDI (Graphical Device Interface), or GTK functionalities to display images..."
351  << std::endl;
352  std::cout << "Tip if you are on a unix-like system:" << std::endl;
353  std::cout << "- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
354  std::cout << "Tip if you are on a windows-like system:" << std::endl;
355  std::cout << "- Install GDI, configure again ViSP using cmake and build again this example" << std::endl;
356  return EXIT_SUCCESS;
357 }
358 
359 #endif
Generic class defining intrinsic camera parameters.
static const vpColor red
Definition: vpColor.h:211
static const vpColor blue
Definition: vpColor.h:217
static const vpColor green
Definition: vpColor.h:214
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed....
Definition: vpDisplayD3D.h:101
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:128
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:128
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void flush(const vpImage< unsigned char > &I)
static void setWindowPosition(const vpImage< unsigned char > &I, int winx, int winy)
error that can be emitted by ViSP classes.
Definition: vpException.h:59
Implementation of an homogeneous matrix and operations on such kind of matrices.
static double rad(double deg)
Definition: vpMath.h:127
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:69
Implementation of a wire frame simulator. Compared to the vpSimulator class, it does not require thir...
void setCameraPositionRelObj(const vpHomogeneousMatrix &cMo_)
void getInternalImage(vpImage< unsigned char > &I)
void initScene(const vpSceneObject &obj, const vpSceneDesiredObject &desiredObject)
void setCurrentViewColor(const vpColor &col)
void setCameraColor(const vpColor &col)
void setDesiredViewColor(const vpColor &col)
void setExternalCameraPosition(const vpHomogeneousMatrix &cam_Mf)
void set_fMo(const vpHomogeneousMatrix &fMo_)
void setDesiredCameraPosition(const vpHomogeneousMatrix &cdMo_)
void setInternalCameraParameters(const vpCameraParameters &cam)
void setExternalCameraParameters(const vpCameraParameters &cam)
void getExternalImage(vpImage< unsigned char > &I)
void display(vpImage< unsigned char > &I, const std::string &title)
Display a gray-scale image.