Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
servoSimuSquareLine2DCamVelocityDisplay.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 line.
32  *
33  * Authors:
34  * Nicolas Melchior
35  *
36  *****************************************************************************/
37 
48 #include <visp3/core/vpDebug.h>
49 #include <visp3/core/vpConfig.h>
50 
51 #if (defined (VISP_HAVE_X11) || defined(VISP_HAVE_GTK) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV))
52 
53 #include <stdlib.h>
54 #include <stdio.h>
55 
56 #include <visp3/core/vpCameraParameters.h>
57 #include <visp3/gui/vpDisplayX.h>
58 #include <visp3/gui/vpDisplayGTK.h>
59 #include <visp3/gui/vpDisplayGDI.h>
60 #include <visp3/gui/vpDisplayOpenCV.h>
61 #include <visp3/visual_features/vpFeatureBuilder.h>
62 #include <visp3/visual_features/vpFeatureLine.h>
63 #include <visp3/core/vpHomogeneousMatrix.h>
64 #include <visp3/core/vpImage.h>
65 #include <visp3/core/vpLine.h>
66 #include <visp3/core/vpMath.h>
67 #include <visp3/io/vpParseArgv.h>
68 #include <visp3/vs/vpServo.h>
69 #include <visp3/vs/vpServoDisplay.h>
70 #include <visp3/robot/vpSimulatorCamera.h>
71 
72 // List of allowed command line options
73 #define GETOPTARGS "cdh"
74 
75 void usage(const char *name, const char *badparam);
76 bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display);
77 
86 void usage(const char *name, const char *badparam)
87 {
88  fprintf(stdout, "\n\
89 Simulation of 2D a visual servoing on a line:\n\
90 - eye-in-hand control law,\n\
91 - velocity computed in the camera frame,\n\
92 - display the camera view.\n\
93  \n\
94 SYNOPSIS\n\
95  %s [-c] [-d] [-h]\n", name);
96 
97  fprintf(stdout, "\n\
98 OPTIONS: Default\n\
99  \n\
100  -c\n\
101  Disable the mouse click. Useful to automaze the \n\
102  execution of this program without humain intervention.\n\
103  \n\
104  -d \n\
105  Turn off the display.\n\
106  \n\
107  -h\n\
108  Print the help.\n");
109 
110  if (badparam)
111  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
112 }
113 
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,0) ;
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  // Set the camera parameters
200  double px, py ; px = py = 600 ;
201  double u0, v0 ; u0 = v0 = 256 ;
202 
203  vpCameraParameters cam(px,py,u0,v0);
204 
205  vpServo task ;
206  vpSimulatorCamera robot ;
207 
208  // sets the initial camera location
209  vpHomogeneousMatrix cMo(0.2,0.2,1,
210  vpMath::rad(45), vpMath::rad(45), vpMath::rad(125));
211 
212  // Compute the position of the object in the world frame
213  vpHomogeneousMatrix wMc, wMo;
214  robot.getPosition(wMc) ;
215  wMo = wMc * cMo;
216 
217  // sets the final camera location (for simulation purpose)
218  vpHomogeneousMatrix cMod(0,0,1,
219  vpMath::rad(0), vpMath::rad(0), vpMath::rad(0));
220 
221 
222  int nbline = 4;
223 
224  // sets the line coordinates (2 planes) in the world frame
225  vpLine line[4] ;
226  line[0].setWorldCoordinates(1,0,0,0.05,0,0,1,0);
227  line[1].setWorldCoordinates(0,1,0,0.05,0,0,1,0);
228  line[2].setWorldCoordinates(1,0,0,-0.05,0,0,1,0);
229  line[3].setWorldCoordinates(0,1,0,-0.05,0,0,1,0);
230 
231  vpFeatureLine ld[4] ;
232  vpFeatureLine l[4] ;
233 
234  // sets the desired position of the visual feature
235  for(int i = 0; i < nbline; i++)
236  {
237  line[i].track(cMod) ;
238  line[i].print() ;
239 
240  vpFeatureBuilder::create(ld[i],line[i]) ;
241  }
242 
243  // computes the line coordinates in the camera frame and its 2D coordinates
244  // sets the current position of the visual feature
245  for(int i = 0; i < nbline; i++)
246  {
247  line[i].track(cMo) ;
248  line[i].print() ;
249 
250  vpFeatureBuilder::create(l[i],line[i]) ;
251  l[i].print() ;
252  }
253 
254  // define the task
255  // - we want an eye-in-hand control law
256  // - robot is controlled in the camera frame
259  //It could be also interesting to test the following tasks
260  //task.setInteractionMatrixType(vpServo::DESIRED, vpServo::PSEUDO_INVERSE);
261  //task.setInteractionMatrixType(vpServo::MEAN, vpServo::PSEUDO_INVERSE);
262 
263  // we want to see a four lines on four lines
264  for(int i = 0; i < nbline; i++)
265  task.addFeature(l[i],ld[i]) ;
266 
267  vpDisplay::display(I) ;
268  vpServoDisplay::display(task,cam,I) ;
269  vpDisplay::flush(I) ;
270 
271  // set the gain
272  task.setLambda(1) ;
273 
274  // Display task information
275  task.print() ;
276 
277  if (opt_display && opt_click_allowed) {
278  std::cout << "\n\nClick in the camera view window to start..." << std::endl;
280  }
281 
282  unsigned int iter=0 ;
283  // loop
284  while(iter++<200)
285  {
286  std::cout << "---------------------------------------------" << iter <<std::endl ;
287  vpColVector v ;
288 
289  // get the robot position
290  robot.getPosition(wMc) ;
291  // Compute the position of the camera wrt the object frame
292  cMo = wMc.inverse() * wMo;
293 
294  // new line position: retrieve x,y and Z of the vpLine structure
295  for(int i = 0; i < nbline; i++)
296  {
297  line[i].track(cMo) ;
298  vpFeatureBuilder::create(l[i],line[i]);
299  }
300 
301  if (opt_display) {
302  vpDisplay::display(I) ;
303  vpServoDisplay::display(task,cam,I) ;
304  vpDisplay::flush(I) ;
305  }
306 
307  // compute the control law
308  v = task.computeControlLaw() ;
309 
310  // send the camera velocity to the controller
312 
313  std::cout << "|| s - s* || = " << ( task.getError() ).sumSquare() <<std::endl ; ;
314 
315  }
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  std::cout << "You do not have X11, GTK, GDI or OpenCV display functionalities..." << std::endl;
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.
void setWorldCoordinates(const double &A1, const double &B1, const double &C1, const double &D1, const double &A2, const double &B2, const double &C2, const double &D2)
Definition: vpLine.cpp:94
#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="")
void track(const vpHomogeneousMatrix &cMo)
static void flush(const vpImage< unsigned char > &I)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:76
Class that defines a line in the object frame, the camera frame and the image plane. All the parameters must be set in meter.
Definition: vpLine.h:105
void kill()
Definition: vpServo.cpp:191
vpColVector getError() const
Definition: vpServo.h:271
virtual void print() const
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
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)