Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
servoSimuCylinder2DCamVelocityDisplay.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 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  * Simulation of a 2D visual servoing on a cylinder.
32  *
33  * Authors:
34  * Eric Marchand
35  * Fabien Spindler
36  *
37  *****************************************************************************/
38 
49 #include <visp3/core/vpDebug.h>
50 #include <visp3/core/vpConfig.h>
51 
52 #if (defined (VISP_HAVE_X11) || defined(VISP_HAVE_GTK) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV))
53 
54 #include <stdlib.h>
55 #include <stdio.h>
56 
57 #include <visp3/core/vpCameraParameters.h>
58 #include <visp3/core/vpCylinder.h>
59 #include <visp3/gui/vpDisplayX.h>
60 #include <visp3/gui/vpDisplayGTK.h>
61 #include <visp3/gui/vpDisplayGDI.h>
62 #include <visp3/gui/vpDisplayOpenCV.h>
63 #include <visp3/visual_features/vpFeatureBuilder.h>
64 #include <visp3/visual_features/vpFeatureLine.h>
65 #include <visp3/core/vpHomogeneousMatrix.h>
66 #include <visp3/core/vpImage.h>
67 #include <visp3/core/vpMath.h>
68 #include <visp3/io/vpParseArgv.h>
69 #include <visp3/vs/vpServo.h>
70 #include <visp3/robot/vpSimulatorCamera.h>
71 #include <visp3/vs/vpServoDisplay.h>
72 
73 // List of allowed command line options
74 #define GETOPTARGS "cdh"
75 
76 void usage(const char *name, const char *badparam);
77 bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display);
78 
87 void usage(const char *name, const char *badparam)
88 {
89  fprintf(stdout, "\n\
90 Simulation of a 2D visual servoing on a cylinder:\n\
91 - eye-in-hand control law,\n\
92 - velocity computed in the camera frame,\n\
93 - display the camera view.\n\
94  \n\
95 SYNOPSIS\n\
96  %s [-c] [-d] [-h]\n", name);
97 
98  fprintf(stdout, "\n\
99 OPTIONS: Default\n\
100  \n\
101  -c\n\
102  Disable the mouse click. Useful to automaze the \n\
103  execution of this program without humain intervention.\n\
104  \n\
105  -d \n\
106  Turn off the display.\n\
107  \n\
108  -h\n\
109  Print the help.\n");
110 
111  if (badparam)
112  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
113 }
114 
126 bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display)
127 {
128  const char *optarg_;
129  int c;
130  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
131 
132  switch (c) {
133  case 'c': click_allowed = false; break;
134  case 'd': display = false; break;
135  case 'h': usage(argv[0], NULL); return false; break;
136 
137  default:
138  usage(argv[0], optarg_);
139  return false; break;
140  }
141  }
142 
143  if ((c == 1) || (c == -1)) {
144  // standalone param or error
145  usage(argv[0], NULL);
146  std::cerr << "ERROR: " << std::endl;
147  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
148  return false;
149  }
150 
151  return true;
152 }
153 
154 
155 int
156 main(int argc, const char ** argv)
157 {
158  try {
159  bool opt_display = true;
160  bool opt_click_allowed = true;
161 
162  // Read the command line options
163  if (getOptions(argc, argv, opt_click_allowed, opt_display) == false) {
164  exit (-1);
165  }
166 
167  vpImage<unsigned char> I(512,512,255) ;
168 
169  // We open a window using either X11, GTK or GDI.
170 #if defined VISP_HAVE_X11
171  vpDisplayX display;
172 #elif defined VISP_HAVE_GTK
173  vpDisplayGTK display;
174 #elif defined VISP_HAVE_GDI
175  vpDisplayGDI display;
176 #elif defined VISP_HAVE_OPENCV
177  vpDisplayOpenCV display;
178 #endif
179 
180  if (opt_display) {
181  try{
182  // Display size is automatically defined by the image (I) size
183  display.init(I, 100, 100,"Camera view...") ;
184  // Display the image
185  // The image class has a member that specify a pointer toward
186  // the display that has been initialized in the display declaration
187  // therefore is is no longuer necessary to make a reference to the
188  // display variable.
189  vpDisplay::display(I) ;
190  vpDisplay::flush(I) ;
191  }
192  catch(...)
193  {
194  vpERROR_TRACE("Error while displaying the image") ;
195  exit(-1);
196  }
197  }
198 
199  double px, py ; px = py = 600 ;
200  double u0, v0 ; u0 = v0 = 256 ;
201 
202  vpCameraParameters cam(px,py,u0,v0);
203 
204  vpServo task ;
205  vpSimulatorCamera robot ;
206 
207  // sets the initial camera location
208  vpHomogeneousMatrix cMo(-0.2,0.1,2,
209  vpMath::rad(5), vpMath::rad(5), vpMath::rad(20));
210 
211  vpHomogeneousMatrix wMc, wMo;
212  robot.getPosition(wMc) ;
213  wMo = wMc * cMo; // Compute the position of the object in the world frame
214 
215  // sets the final camera location (for simulation purpose)
216  vpHomogeneousMatrix cMod(0,0,1,
217  vpMath::rad(-60), vpMath::rad(0), vpMath::rad(0));
218 
219  // sets the cylinder coordinates in the world frame
220  vpCylinder cylinder(0,1,0, // direction
221  0,0,0, // point of the axis
222  0.1) ; // radius
223 
224  // sets the desired position of the visual feature
225  cylinder.track(cMod) ;
226  cylinder.print() ;
227 
228  vpFeatureLine ld[2] ;
229  int i ;
230  for(i=0 ; i < 2 ; i++)
231  vpFeatureBuilder::create(ld[i],cylinder,i) ;
232 
233  // computes the cylinder coordinates in the camera frame and its 2D coordinates
234  // sets the current position of the visual feature
235  cylinder.track(cMo) ;
236  cylinder.print() ;
237 
238  vpFeatureLine l[2] ;
239  for(i=0 ; i < 2 ; i++)
240  {
241  vpFeatureBuilder::create(l[i],cylinder,i) ;
242  l[i].print() ;
243  }
244 
245  // define the task
246  // - we want an eye-in-hand control law
247  // - robot is controlled in the camera frame
249  // task.setInteractionMatrixType(vpServo::CURRENT, vpServo::PSEUDO_INVERSE) ;
250  // it can also be interesting to test these possibilities
251  // task.setInteractionMatrixType(vpServo::MEAN, vpServo::PSEUDO_INVERSE) ;
253  //task.setInteractionMatrixType(vpServo::DESIRED, vpServo::TRANSPOSE) ;
254  // task.setInteractionMatrixType(vpServo::CURRENT, vpServo::TRANSPOSE) ;
255 
256  // - we want to see 2 lines on 2 lines
257  task.addFeature(l[0],ld[0]) ;
258  task.addFeature(l[1],ld[1]) ;
259 
260  vpServoDisplay::display(task,cam,I) ;
261  vpDisplay::flush(I) ;
262 
263  // Display task information
264  task.print() ;
265 
266  if (opt_display && opt_click_allowed) {
267  std::cout << "\n\nClick in the camera view window to start..." << std::endl;
269  }
270 
271  // - set the gain
272  task.setLambda(1) ;
273 
274  // Display task information
275  task.print() ;
276 
277  unsigned int iter=0 ;
278  // loop
279  do
280  {
281  std::cout << "---------------------------------------------" << iter++ <<std::endl ;
282  vpColVector v ;
283 
284  // get the robot position
285  robot.getPosition(wMc) ;
286  // Compute the position of the camera wrt the object frame
287  cMo = wMc.inverse() * wMo;
288 
289  // new line position
290  // retrieve x,y and Z of the vpLine structure
291  cylinder.track(cMo) ;
292  // cylinder.print() ;
293  for(i=0 ; i < 2 ; i++)
294  {
295  vpFeatureBuilder::create(l[i],cylinder,i) ;
296  // l[i].print() ;
297  }
298 
299  if (opt_display) {
300  vpDisplay::display(I) ;
301  vpServoDisplay::display(task,cam,I) ;
302  vpDisplay::flush(I) ;
303  }
304 
305  // compute the control law
306  v = task.computeControlLaw() ;
307 
308  // send the camera velocity to the controller
310 
311  std::cout << "|| s - s* || = " << ( task.getError() ).sumSquare() <<std::endl ; ;
312 
313  // vpDisplay::getClick(I) ;
314  }
315  while(( task.getError() ).sumSquare() > 1e-9) ;
316 
317  if (opt_display && opt_click_allowed) {
318  std::cout << "\nClick in the camera view window to end..." << std::endl;
320  }
321 
322  // Display task information
323  task.print() ;
324  task.kill();
325  return 0;
326  }
327  catch(vpException &e) {
328  std::cout << "Catch a ViSP exception: " << e << std::endl;
329  return 1;
330  }
331 }
332 
333 #else
334 int
335 main()
336 {
337  vpERROR_TRACE("You do not have X11, GTK, GDI or OpenCV display functionalities...");
338 }
339 
340 #endif
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
void setVelocity(const vpRobot::vpControlFrameType frame, const vpColVector &vel)
void print(const unsigned int select=FEATURE_ALL) const
Implementation of an homogeneous matrix and operations on such kind of matrices.
Class that defines the simplest robot: a free flying camera.
#define vpERROR_TRACE
Definition: vpDebug.h:391
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:153
void addFeature(vpBasicFeature &s, vpBasicFeature &s_star, const unsigned int select=vpBasicFeature::FEATURE_ALL)
Definition: vpServo.cpp:512
error that can be emited by ViSP classes.
Definition: vpException.h:73
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
static void flush(const vpImage< unsigned char > &I)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:76
void kill()
Definition: vpServo.cpp:191
vpColVector getError() const
Definition: vpServo.h:271
vpColVector computeControlLaw()
Definition: vpServo.cpp:954
static void display(const vpImage< unsigned char > &I)
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
Generic class defining intrinsic camera parameters.
void setLambda(double c)
Definition: vpServo.h:391
Class that defines a 2D line visual feature which is composed by two parameters that are and ...
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:138
vpHomogeneousMatrix getPosition() const
void setInteractionMatrixType(const vpServoIteractionMatrixType &interactionMatrixType, const vpServoInversionType &interactionMatrixInversion=PSEUDO_INVERSE)
Definition: vpServo.cpp:585
static double rad(double deg)
Definition: vpMath.h:104
Class that defines what is a cylinder.
Definition: vpCylinder.h:93
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
vpHomogeneousMatrix inverse() const
void print(const vpServo::vpServoPrintType display_level=ALL, std::ostream &os=std::cout)
Definition: vpServo.cpp:314
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
void setServo(const vpServoType &servo_type)
Definition: vpServo.cpp:222
static void display(const vpServo &s, const vpCameraParameters &cam, const vpImage< unsigned char > &I, vpColor currentColor=vpColor::green, vpColor desiredColor=vpColor::red, unsigned int thickness=1)