ViSP  2.9.0
servoSimuCylinder.cpp
1 /****************************************************************************
2  *
3  * $Id: servoSimuCylinder.cpp 4659 2014-02-09 14:11:51Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Demonstration of the wireframe simulator with a simple visual servoing
36  *
37  * Authors:
38  * Nicolas Melchior
39  *
40  *****************************************************************************/
41 
49 #include <stdlib.h>
50 
51 #include <visp/vpCameraParameters.h>
52 #include <visp/vpCylinder.h>
53 #include <visp/vpDisplayOpenCV.h>
54 #include <visp/vpDisplayX.h>
55 #include <visp/vpDisplayGTK.h>
56 #include <visp/vpDisplayGDI.h>
57 #include <visp/vpDisplayD3D.h>
58 #include <visp/vpFeatureBuilder.h>
59 #include <visp/vpHomogeneousMatrix.h>
60 #include <visp/vpImage.h>
61 #include <visp/vpImageIo.h>
62 #include <visp/vpIoTools.h>
63 #include <visp/vpMath.h>
64 #include <visp/vpParseArgv.h>
65 #include <visp/vpRobotCamera.h>
66 #include <visp/vpServo.h>
67 #include <visp/vpTime.h>
68 #include <visp/vpVelocityTwistMatrix.h>
69 #include <visp/vpWireFrameSimulator.h>
70 
71 #define GETOPTARGS "dh"
72 
73 #ifdef VISP_HAVE_DISPLAY
74 void usage(const char *name, const char *badparam);
75 bool getOptions(int argc, const char **argv, bool &display);
76 
85 void usage(const char *name, const char *badparam)
86 {
87  fprintf(stdout, "\n\
88 Demonstration of the wireframe simulator with a simple visual servoing.\n\
89  \n\
90 The visual servoing consists in bringing the camera at a desired position\n\
91 from the object.\n\
92  \n\
93 The visual features used to compute the pose of the camera and \n\
94 thus the control law are two lines. These features are computed thanks \n\
95 to the equation of a cylinder.\n\
96  \n\
97 This demonstration explains also how to move the object around a world \n\
98 reference frame. Here, the movment is a rotation around the x and y axis \n\
99 at a given distance from the world frame. In fact the object trajectory \n\
100 is on a sphere whose center is the origin of the world frame.\n\
101  \n\
102 SYNOPSIS\n\
103  %s [-d] [-h]\n", name);
104 
105  fprintf(stdout, "\n\
106 OPTIONS: \n\
107  -d \n\
108  Turn off the display.\n\
109  \n\
110  -h\n\
111  Print the help.\n");
112 
113  if (badparam)
114  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
115 }
116 
117 
129 bool getOptions(int argc, const char **argv, bool &display)
130 {
131  const char *optarg_;
132  int c;
133  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
134 
135  switch (c) {
136  case 'd': display = false; break;
137  case 'h': usage(argv[0], NULL); return false; break;
138 
139  default:
140  usage(argv[0], optarg_);
141  return false; break;
142  }
143  }
144 
145  if ((c == 1) || (c == -1)) {
146  // standalone param or error
147  usage(argv[0], NULL);
148  std::cerr << "ERROR: " << std::endl;
149  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
150  return false;
151  }
152 
153  return true;
154 }
155 
156 
157 int
158 main(int argc, const char ** argv)
159 {
160  try {
161  bool opt_display = true;
162 
163  // Read the command line options
164  if (getOptions(argc, argv, opt_display) == false) {
165  exit (-1);
166  }
167 
168  vpImage<vpRGBa> Iint(480,640,255);
169  vpImage<vpRGBa> Iext(480,640,255);
170 
171 #if defined VISP_HAVE_X11
172  vpDisplayX display[2];
173 #elif defined VISP_HAVE_OPENCV
174  vpDisplayOpenCV display[2];
175 #elif defined VISP_HAVE_GDI
176  vpDisplayGDI display[2];
177 #elif defined VISP_HAVE_D3D9
178  vpDisplayD3D display[2];
179 #elif defined VISP_HAVE_GTK
180  vpDisplayGTK display[2];
181 #endif
182 
183  if (opt_display)
184  {
185  // Display size is automatically defined by the image (I) size
186  display[0].init(Iint, 100, 100,"The internal view") ;
187  display[1].init(Iext, 100, 100,"The first external view") ;
188  vpDisplay::setWindowPosition (Iint, 0, 0);
189  vpDisplay::setWindowPosition (Iext, 700, 0);
190  vpDisplay::display(Iint);
191  vpDisplay::flush(Iint);
192  vpDisplay::display(Iext);
193  vpDisplay::flush(Iext);
194  }
195 
196  vpServo task;
197  vpRobotCamera robot ;
198  float sampling_time = 0.040f; // Sampling period in second
199  robot.setSamplingTime(sampling_time);
200 
201  // Set initial position of the object in the camera frame
202  vpHomogeneousMatrix cMo(0,0.1,0.3,vpMath::rad(35),vpMath::rad(25),vpMath::rad(75));
203  // Set desired position of the object in the camera frame
204  vpHomogeneousMatrix cdMo(0.0,0.0,0.5,vpMath::rad(90),vpMath::rad(0),vpMath::rad(0));
205  // Set initial position of the object in the world frame
206  vpHomogeneousMatrix wMo(0.0,0.0,0,0,0,0);
207  // Position of the camera in the world frame
208  vpHomogeneousMatrix wMc, cMw;
209  wMc = wMo * cMo.inverse();
210  cMw = wMc.inverse();
211 
212  // Create a cylinder
213  vpCylinder cylinder(0,0,1,0,0,0,0.1);
214 
215  // Projection of the cylinder
216  cylinder.track(cMo);
217 
218  //Set the current visual feature
219  vpFeatureLine l[2];
222 
223  // Projection of the cylinder
224  cylinder.track(cdMo);
225 
226  vpFeatureLine ld[2];
229 
232 
234  vpVelocityTwistMatrix cVe(cMe);
235  task.set_cVe(cVe);
236 
237  vpMatrix eJe;
238  robot.get_eJe(eJe);
239  task.set_eJe(eJe);
240 
241  for (int i = 0 ; i < 2 ; i++)
242  task.addFeature(l[i],ld[i]) ;
243 
244  task.setLambda(1);
245 
247 
248  // Set the scene
250 
251  // Initialize simulator frames
252  sim.set_fMo( wMo ); // Position of the object in the world reference frame
253  sim.setCameraPositionRelObj(cMo) ; // initial position of the camera
254  sim.setDesiredCameraPosition(cdMo); // desired position of the camera
255 
256  // Set the External camera position
258  sim.setExternalCameraPosition(camMf);
259 
260  // Set the parameters of the cameras (internal and external)
261  vpCameraParameters camera(1000,1000,320,240);
262  sim.setInternalCameraParameters(camera);
263  sim.setExternalCameraParameters(camera);
264 
265  int stop = 10;
266 
267  if (opt_display)
268  {
269  stop = 2500;
270 
271  //Get the internal and external views
272  sim.getInternalImage(Iint);
273  sim.getExternalImage(Iext);
274 
275  //Display the object frame (current and desired position)
276  vpDisplay::displayFrame(Iint,cMo,camera,0.2,vpColor::none);
277  vpDisplay::displayFrame(Iint,cdMo,camera,0.2,vpColor::none);
278 
279  //Display the object frame the world reference frame and the camera frame
280  vpDisplay::displayFrame(Iext,camMf*sim.get_fMo()*cMo.inverse(),camera,0.2,vpColor::none);
281  vpDisplay::displayFrame(Iext,camMf*sim.get_fMo(),camera,0.2,vpColor::none);
282  vpDisplay::displayFrame(Iext,camMf,camera,0.2,vpColor::none);
283 
284  vpDisplay::flush(Iint);
285  vpDisplay::flush(Iext);
286 
287  std::cout << "Click on a display" << std::endl;
288  while (!vpDisplay::getClick(Iint,false) && !vpDisplay::getClick(Iext,false)){};
289  }
290 
291  robot.setPosition( cMw );
292 
293  //Print the task
294  task.print();
295 
296  int iter = 0;
297  vpColVector v ;
298 
299  //Set the secondary task parameters
300  vpColVector e1(6) ; e1 = 0 ;
301  vpColVector e2(6) ; e2 = 0 ;
302  vpColVector proj_e1 ;
303  vpColVector proj_e2 ;
304  iter = 0;
305  double rapport = 0;
306  double vitesse = 0.3;
307  int tempo = 600;
308 
309  while(iter++ < stop)
310  {
311  if (opt_display)
312  {
313  vpDisplay::display(Iint) ;
314  vpDisplay::display(Iext) ;
315  }
316 
317  double t = vpTime::measureTimeMs();
318 
319  robot.get_eJe(eJe) ;
320  task.set_eJe(eJe) ;
321 
322  robot.getPosition(cMw) ;
323  cMo = cMw * wMo;
324 
325  cylinder.track(cMo) ;
328 
329  v = task.computeControlLaw() ;
330 
331  //Compute the velocity with the secondary task
332  if ( iter%tempo < 200 && iter%tempo >= 0)
333  {
334  e2 = 0;
335  e1[0] = -fabs(vitesse) ;
336  proj_e1 = task.secondaryTask(e1);
337  rapport = -vitesse/proj_e1[0];
338  proj_e1 *= rapport ;
339  v += proj_e1 ;
340  }
341 
342  if ( iter%tempo < 300 && iter%tempo >= 200)
343  {
344  e1 = 0;
345  e2[1] = -fabs(vitesse) ;
346  proj_e2 = task.secondaryTask(e2);
347  rapport = -vitesse/proj_e2[1];
348  proj_e2 *= rapport ;
349  v += proj_e2 ;
350  }
351 
352  if ( iter%tempo < 500 && iter%tempo >= 300)
353  {
354  e2 = 0;
355  e1[0] = -fabs(vitesse) ;
356  proj_e1 = task.secondaryTask(e1);
357  rapport = vitesse/proj_e1[0];
358  proj_e1 *= rapport ;
359  v += proj_e1 ;
360  }
361 
362  if ( iter%tempo < 600 && iter%tempo >= 500)
363  {
364  e1 = 0;
365  e2[1] = -fabs(vitesse) ;
366  proj_e2 = task.secondaryTask(e2);
367  rapport = vitesse/proj_e2[1];
368  proj_e2 *= rapport ;
369  v += proj_e2 ;
370  }
371 
373 
374  // Update the simulator frames
375  sim.set_fMo( wMo ); // This line is not really requested since the object doesn't move
376  sim.setCameraPositionRelObj( cMo );
377 
378  if (opt_display)
379  {
380  //Get the internal and external views
381  sim.getInternalImage(Iint);
382  sim.getExternalImage(Iext);
383 
384  //Display the object frame (current and desired position)
385  vpDisplay::displayFrame(Iint,cMo,camera,0.2,vpColor::none);
386  vpDisplay::displayFrame(Iint,cdMo,camera,0.2,vpColor::none);
387 
388  //Display the object frame the world reference frame and the camera frame
392 
393  vpDisplay::flush(Iint);
394  vpDisplay::flush(Iext);
395  }
396 
397  vpTime::wait(t, sampling_time * 1000); // Wait 40 ms
398 
399  std::cout << "|| s - s* || = " << (task.getError() ).sumSquare() <<std::endl ;
400  }
401 
402  task.print() ;
403  task.kill() ;
404 
405  return 0;
406  }
407  catch(vpException e) {
408  std::cout << "Catch an exception: " << e << std::endl;
409  return 1;
410  }
411 }
412 #else
413 int
414 main()
415 {
416  vpERROR_TRACE("You do not have X11, OpenCV, GDI, D3D9 or GTK display functionalities...");
417 }
418 
419 #endif
The object displayed at the desired position is the same than the scene object defined in vpSceneObje...
Definition of the vpMatrix class.
Definition: vpMatrix.h:98
A cylinder of 80cm length and 10cm radius.
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
#define vpERROR_TRACE
Definition: vpDebug.h:395
void setPosition(const vpHomogeneousMatrix &cMw)
void set_fMo(const vpHomogeneousMatrix &fMo_)
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:132
void set_eJe(const vpMatrix &eJe_)
Definition: vpServo.h:439
Define the X11 console to display images.
Definition: vpDisplayX.h:152
void addFeature(vpBasicFeature &s, vpBasicFeature &s_star, const unsigned int select=vpBasicFeature::FEATURE_ALL)
Definition: vpServo.cpp:449
static const vpColor none
Definition: vpColor.h:179
error that can be emited by ViSP classes.
Definition: vpException.h:76
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const char *title=NULL)
void setExternalCameraPosition(const vpHomogeneousMatrix &cam_Mf)
static double measureTimeMs()
Definition: vpTime.cpp:86
static int wait(double t0, double t)
Definition: vpTime.cpp:149
void setDesiredCameraPosition(const vpHomogeneousMatrix &cdMo_)
static void flush(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:1994
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:79
vpColVector secondaryTask(const vpColVector &de2dt)
Definition: vpServo.cpp:1416
virtual void setSamplingTime(const double &delta_t)
Display for windows using Direct3D.
Definition: vpDisplayD3D.h:109
void kill()
Definition: vpServo.cpp:189
vpColVector getError() const
Definition: vpServo.h:257
vpHomogeneousMatrix get_fMo() const
vpColVector computeControlLaw()
Definition: vpServo.cpp:902
virtual void setWindowPosition(int winx, int winy)=0
Class that defines the simplest robot: a free flying camera.
static void display(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:206
The vpDisplayOpenCV allows to display image using the opencv library.
Generic class defining intrinsic camera parameters.
void setLambda(double c)
Definition: vpServo.h:370
Class that defines a 2D line visual feature which is composed by two parameters that are and ...
void initScene(const vpSceneObject &obj, const vpSceneDesiredObject &desiredObject)
The vpDisplayGTK allows to display image using the GTK+ library version 1.2.
Definition: vpDisplayGTK.h:145
Class that consider the particular case of twist transformation matrix that allows to transform a vel...
void getExternalImage(vpImage< unsigned char > &I)
Implementation of a wire frame simulator. Compared to the vpSimulator class, it does not require thir...
static void displayFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double size, const vpColor &color, unsigned int thickness=1)
Definition: vpDisplay.cpp:371
void setInteractionMatrixType(const vpServoIteractionMatrixType &interactionMatrixType, const vpServoInversionType &interactionMatrixInversion=PSEUDO_INVERSE)
Definition: vpServo.cpp:522
static double rad(double deg)
Definition: vpMath.h:100
void setExternalCameraParameters(const vpCameraParameters &cam)
void setCameraPositionRelObj(const vpHomogeneousMatrix &cMo_)
void getInternalImage(vpImage< unsigned char > &I)
void getPosition(vpHomogeneousMatrix &cMw) const
Class that defines what is a cylinder.
Definition: vpCylinder.h:97
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
void get_eJe(vpMatrix &eJe)
void set_cVe(const vpVelocityTwistMatrix &cVe_)
Definition: vpServo.h:414
vpHomogeneousMatrix inverse() const
void setInternalCameraParameters(const vpCameraParameters &cam)
void print(const vpServo::vpServoPrintType display_level=ALL, std::ostream &os=std::cout)
Definition: vpServo.cpp:251
virtual bool getClick(bool blocking=true)=0
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
void setServo(const vpServoType &servo_type)
Definition: vpServo.cpp:220
void setVelocity(const vpRobot::vpControlFrameType frame, const vpColVector &v)
vpHomogeneousMatrix getExternalCameraPosition() const