Visual Servoing Platform  version 3.4.0
servoSimuSquareLine2DCamVelocityDisplay.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 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 http://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  * Simulation of a 2D visual servoing on a line.
33  *
34  * Authors:
35  * Nicolas Melchior
36  *
37  *****************************************************************************/
38 
48 #include <visp3/core/vpConfig.h>
49 #include <visp3/core/vpDebug.h>
50 
51 #if (defined(VISP_HAVE_X11) || defined(VISP_HAVE_GTK) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV)) \
52  && (defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
53 
54 #include <stdio.h>
55 #include <stdlib.h>
56 
57 #include <visp3/core/vpCameraParameters.h>
58 #include <visp3/core/vpHomogeneousMatrix.h>
59 #include <visp3/core/vpImage.h>
60 #include <visp3/core/vpLine.h>
61 #include <visp3/core/vpMath.h>
62 #include <visp3/gui/vpDisplayGDI.h>
63 #include <visp3/gui/vpDisplayGTK.h>
64 #include <visp3/gui/vpDisplayOpenCV.h>
65 #include <visp3/gui/vpDisplayX.h>
66 #include <visp3/io/vpParseArgv.h>
67 #include <visp3/robot/vpSimulatorCamera.h>
68 #include <visp3/visual_features/vpFeatureBuilder.h>
69 #include <visp3/visual_features/vpFeatureLine.h>
70 #include <visp3/vs/vpServo.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 2D a visual servoing on a line:\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 
127 bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display)
128 {
129  const char *optarg_;
130  int c;
131  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
132 
133  switch (c) {
134  case 'c':
135  click_allowed = false;
136  break;
137  case 'd':
138  display = false;
139  break;
140  case 'h':
141  usage(argv[0], NULL);
142  return false;
143 
144  default:
145  usage(argv[0], optarg_);
146  return false;
147  }
148  }
149 
150  if ((c == 1) || (c == -1)) {
151  // standalone param or error
152  usage(argv[0], NULL);
153  std::cerr << "ERROR: " << std::endl;
154  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
155  return false;
156  }
157 
158  return true;
159 }
160 
161 int main(int argc, const char **argv)
162 {
163  try {
164  bool opt_display = true;
165  bool opt_click_allowed = true;
166 
167  // Read the command line options
168  if (getOptions(argc, argv, opt_click_allowed, opt_display) == false) {
169  exit(-1);
170  }
171 
172  vpImage<unsigned char> I(512, 512, 0);
173 
174 // We open a window using either X11, GTK or GDI.
175 #if defined VISP_HAVE_X11
176  vpDisplayX display;
177 #elif defined VISP_HAVE_GTK
178  vpDisplayGTK display;
179 #elif defined VISP_HAVE_GDI
180  vpDisplayGDI display;
181 #elif defined VISP_HAVE_OPENCV
182  vpDisplayOpenCV display;
183 #endif
184 
185  if (opt_display) {
186  try {
187  // Display size is automatically defined by the image (I) size
188  display.init(I, 100, 100, "Camera view...");
189  // Display the image
190  // The image class has a member that specify a pointer toward
191  // the display that has been initialized in the display declaration
192  // therefore is is no longuer necessary to make a reference to the
193  // display variable.
195  vpDisplay::flush(I);
196  } catch (...) {
197  vpERROR_TRACE("Error while displaying the image");
198  exit(-1);
199  }
200  }
201 
202  // Set the camera parameters
203  double px, py;
204  px = py = 600;
205  double u0, v0;
206  u0 = v0 = 256;
207 
208  vpCameraParameters cam(px, py, u0, v0);
209 
210  vpServo task;
211  vpSimulatorCamera robot;
212 
213  // sets the initial camera location
214  vpHomogeneousMatrix cMo(0.2, 0.2, 1, vpMath::rad(45), vpMath::rad(45), vpMath::rad(125));
215 
216  // Compute the position of the object in the world frame
217  vpHomogeneousMatrix wMc, wMo;
218  robot.getPosition(wMc);
219  wMo = wMc * cMo;
220 
221  // sets the final camera location (for simulation purpose)
222  vpHomogeneousMatrix cMod(0, 0, 1, vpMath::rad(0), vpMath::rad(0), vpMath::rad(0));
223 
224  int nbline = 4;
225 
226  // sets the line coordinates (2 planes) in the world frame
227  vpLine line[4];
228  line[0].setWorldCoordinates(1, 0, 0, 0.05, 0, 0, 1, 0);
229  line[1].setWorldCoordinates(0, 1, 0, 0.05, 0, 0, 1, 0);
230  line[2].setWorldCoordinates(1, 0, 0, -0.05, 0, 0, 1, 0);
231  line[3].setWorldCoordinates(0, 1, 0, -0.05, 0, 0, 1, 0);
232 
233  vpFeatureLine ld[4];
234  vpFeatureLine l[4];
235 
236  // sets the desired position of the visual feature
237  for (int i = 0; i < nbline; i++) {
238  line[i].track(cMod);
239  line[i].print();
240 
241  vpFeatureBuilder::create(ld[i], line[i]);
242  }
243 
244  // computes the line coordinates in the camera frame and its 2D
245  // coordinates sets the current position of the visual feature
246  for (int i = 0; i < nbline; i++) {
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,
261  // vpServo::PSEUDO_INVERSE); task.setInteractionMatrixType(vpServo::MEAN,
262  // vpServo::PSEUDO_INVERSE);
263 
264  // we want to see a four lines on four lines
265  for (int i = 0; i < nbline; i++)
266  task.addFeature(l[i], ld[i]);
267 
269  vpServoDisplay::display(task, cam, I);
270  vpDisplay::flush(I);
271 
272  // set the gain
273  task.setLambda(1);
274 
275  // Display task information
276  task.print();
277 
278  if (opt_display && opt_click_allowed) {
279  std::cout << "\n\nClick in the camera view window to start..." << std::endl;
281  }
282 
283  unsigned int iter = 0;
284  // loop
285  while (iter++ < 200) {
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 object frame in the camera 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  line[i].track(cMo);
297  vpFeatureBuilder::create(l[i], line[i]);
298  }
299 
300  if (opt_display) {
302  vpServoDisplay::display(task, cam, I);
303  vpDisplay::flush(I);
304  }
305 
306  // compute the control law
307  v = task.computeControlLaw();
308 
309  // send the camera velocity to the controller
311 
312  std::cout << "|| s - s* || = " << (task.getError()).sumSquare() << std::endl;
313  }
314 
315  if (opt_display && opt_click_allowed) {
316  vpDisplay::displayText(I, 20, 20, "Click to quit...", vpColor::white);
317  vpDisplay::flush(I);
319  }
320 
321  // Display task information
322  task.print();
323  return EXIT_SUCCESS;
324  } catch (const vpException &e) {
325  std::cout << "Catch a ViSP exception: " << e << std::endl;
326  return EXIT_FAILURE;
327  }
328 }
329 
330 #elif !(defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
331 int main()
332 {
333  std::cout << "Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
334  return EXIT_SUCCESS;
335 }
336 #else
337 int main()
338 {
339  std::cout << "You do not have X11, or GTK, or GDI (Graphical Device Interface) or OpenCV functionalities to display images..." << std::endl;
340  std::cout << "Tip if you are on a unix-like system:" << std::endl;
341  std::cout << "- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
342  std::cout << "Tip if you are on a windows-like system:" << std::endl;
343  std::cout << "- Install GDI, configure again ViSP using cmake and build again this example" << std::endl;
344  return EXIT_SUCCESS;
345 }
346 #endif
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
void setVelocity(const vpRobot::vpControlFrameType frame, const vpColVector &vel)
Implementation of an homogeneous matrix and operations on such kind of matrices.
Class that defines the simplest robot: a free flying camera.
void addFeature(vpBasicFeature &s, vpBasicFeature &s_star, unsigned int select=vpBasicFeature::FEATURE_ALL)
Definition: vpServo.cpp:490
#define vpERROR_TRACE
Definition: vpDebug.h:393
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:150
error that can be emited by ViSP classes.
Definition: vpException.h:71
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:69
Class that defines a 3D line in the object frame and allows forward projection of the line in the cam...
Definition: vpLine.h:104
vpColVector getError() const
Definition: vpServo.h:278
void setWorldCoordinates(const double &oA1, const double &oB1, const double &oC1, const double &oD1, const double &oA2, const double &oB2, const double &oC2, const double &oD2)
Definition: vpLine.cpp:85
virtual void print() const
vpColVector computeControlLaw()
Definition: vpServo.cpp:929
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:404
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:134
vpHomogeneousMatrix getPosition() const
void setInteractionMatrixType(const vpServoIteractionMatrixType &interactionMatrixType, const vpServoInversionType &interactionMatrixInversion=PSEUDO_INVERSE)
Definition: vpServo.cpp:567
static double rad(double deg)
Definition: vpMath.h:110
void print(unsigned int select=FEATURE_ALL) const
Implementation of column vector and the associated operations.
Definition: vpColVector.h:130
vpHomogeneousMatrix inverse() const
void print(const vpServo::vpServoPrintType display_level=ALL, std::ostream &os=std::cout)
Definition: vpServo.cpp:306
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
static const vpColor white
Definition: vpColor.h:212
void setServo(const vpServoType &servo_type)
Definition: vpServo.cpp:218
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)