ViSP  2.10.0
servoMomentPoints.cpp
1 /****************************************************************************
2  *
3  * $Id: servoMomentPoints.cpp 4673 2014-02-17 09:06:49Z 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  * Example of visual servoing with moments using discrete points as object
36  * container
37  *
38  * Authors:
39  * Filip Novotny
40  *
41  *****************************************************************************/
42 
48 #include <visp/vpDebug.h>
49 #include <visp/vpConfig.h>
50 #include <iostream>
51 #include <visp/vpHomogeneousMatrix.h>
52 #include <visp/vpMomentObject.h>
53 #include <visp/vpMomentDatabase.h>
54 #include <visp/vpMomentCommon.h>
55 #include <visp/vpFeatureMomentCommon.h>
56 #include <visp/vpDisplayX.h>
57 #include <visp/vpDisplayGTK.h>
58 #include <visp/vpDisplayGDI.h>
59 #include <visp/vpCameraParameters.h>
60 #include <visp/vpIoTools.h>
61 #include <visp/vpMath.h>
62 #include <visp/vpHomogeneousMatrix.h>
63 #include <visp/vpServo.h>
64 #include <visp/vpDebug.h>
65 #include <visp/vpFeatureBuilder.h>
66 #include <visp/vpFeaturePoint.h>
67 #include <visp/vpSimulatorAfma6.h>
68 #include <visp/vpPlane.h>
69 
70 
71 #if !defined(_WIN32) && !defined(VISP_HAVE_PTHREAD)
72 // Robot simulator used in this example is not available
73 int main()
74 {
75  std::cout << "Can't run this example since vpSimulatorAfma6 capability is not available." << std::endl;
76  std::cout << "You should install pthread third-party library." << std::endl;
77 }
78 // No display available
79 #elif !defined(VISP_HAVE_X11) && !defined(VISP_HAVE_OPENCV) && !defined(VISP_HAVE_GDI) && !defined(VISP_HAVE_D3D9) && !defined(VISP_HAVE_GTK)
80 int main()
81 {
82  std::cout << "Can't run this example since no display capability is available." << std::endl;
83  std::cout << "You should install one of the following third-party library: X11, OpenCV, GDI, GTK." << std::endl;
84 }
85 #else
86 
87 //setup robot parameters
88 void paramRobot();
89 
90 //update moment objects and interface
91 void refreshScene(vpMomentObject &obj);
92 //initialize scene in the interface
93 void initScene();
94 //initialize the moment features
95 void initFeatures();
96 
97 void init(vpHomogeneousMatrix& cMo, vpHomogeneousMatrix& cdMo);
98 void execute(unsigned int nbIter); //launch the simulation
99 void setInteractionMatrixType(vpServo::vpServoIteractionMatrixType type);
100 double error();
101 void planeToABC(vpPlane& pl, double& A,double& B, double& C);
102 void paramRobot();
103 void removeJointLimits(vpSimulatorAfma6& robot);
104 
105 int main()
106 {
107  try { //intial pose
108  vpHomogeneousMatrix cMo(0.05,0.1,1.5,vpMath::rad(30),vpMath::rad(20),-vpMath::rad(15));
109  //Desired pose
111 
112  //init and run the simulation
113  init(cMo,cdMo);
114  execute(1500);
115  return 0;
116  }
117  catch(vpException e) {
118  std::cout << "Catch an exception: " << e << std::endl;
119  return 1;
120  }
121 }
122 
123 //init the right display
124 #if defined VISP_HAVE_X11
125 vpDisplayX displayInt;
126 #elif defined VISP_HAVE_OPENCV
127 vpDisplayOpenCV displayInt;
128 #elif defined VISP_HAVE_GDI
129 vpDisplayGDI displayInt;
130 #elif defined VISP_HAVE_D3D9
131 vpDisplayD3D displayInt;
132 #elif defined VISP_HAVE_GTK
133 vpDisplayGTK displayInt;
134 #endif
135 
136 //start and destination positioning matrices
139 
140 vpSimulatorAfma6 robot(false);//robot used in this simulation
141 vpImage<vpRGBa> Iint(480,640, 255);//internal image used for interface display
142 vpServo::vpServoIteractionMatrixType interaction_type; //current or desired
143 vpServo task; //servoing task
144 vpCameraParameters cam;//robot camera parameters
145 double _error; //current error
146 vpImageSimulator imsim;//image simulator used to simulate the perspective-projection camera
147 
148 //moment sets and their corresponding features
149 vpMomentCommon *moments;
150 vpMomentCommon *momentsDes;
151 vpFeatureMomentCommon *featureMoments;
152 vpFeatureMomentCommon *featureMomentsDes;
153 
154 //source and destination objects for moment manipulation
155 vpMomentObject src(6);
156 vpMomentObject dst(6);
157 
158 
159 void initScene(){
160  std::vector<vpPoint> src_pts;
161  std::vector<vpPoint> dst_pts;
162 
163  double x[8] = { 1,3, 4,-1 ,-3,-2,-1,1};
164  double y[8] = { 0,1, 4, 4, -2,-2, 1,0};
165  int nbpoints = 8;
166 
167  for (int i = 0 ; i < nbpoints ; i++){
168  vpPoint p;
169  p.setWorldCoordinates(x[i]/20,y[i]/20,0.0);
170  p.track(cMo) ;
171  src_pts.push_back(p);
172  }
173 
175  src.fromVector(src_pts);
176  for (int i = 0 ; i < nbpoints ; i++){
177  vpPoint p;
178  p.setWorldCoordinates(x[i]/20,y[i]/20,0.0);
179  p.track(cdMo) ;
180  dst_pts.push_back(p);
181  }
183  dst.fromVector(dst_pts);
184 
185 }
186 
187 void initFeatures(){
188  //A,B,C parameters of source and destination plane
189  double A; double B; double C;
190  double Ad; double Bd; double Cd;
191  //init main object: using moments up to order 6
192 
193  //Initializing values from regular plane (with ax+by+cz=d convention)
194  vpPlane pl;
195  pl.setABCD(0,0,1.0,0);
196  pl.changeFrame(cMo);
197  planeToABC(pl,A,B,C);
198 
199  pl.setABCD(0,0,1.0,0);
200  pl.changeFrame(cdMo);
201  planeToABC(pl,Ad,Bd,Cd);
202 
203  //extracting initial position (actually we only care about Zdst)
205  cdMo.extract(vec);
206 
208  //don't need to be specific, vpMomentCommon automatically loads Xg,Yg,An,Ci,Cj,Alpha moments
211  //same thing with common features
212  featureMoments = new vpFeatureMomentCommon(*moments);
213  featureMomentsDes = new vpFeatureMomentCommon(*momentsDes);
214 
215  moments->updateAll(src);
216  momentsDes->updateAll(dst);
217 
218  featureMoments->updateAll(A,B,C);
219  featureMomentsDes->updateAll(Ad,Bd,Cd);
220 
221  //setup the interaction type
222  task.setInteractionMatrixType(interaction_type) ;
224  task.addFeature(featureMoments->getFeatureGravityNormalized(),featureMomentsDes->getFeatureGravityNormalized());
225  task.addFeature(featureMoments->getFeatureAn(),featureMomentsDes->getFeatureAn());
226  task.addFeature(featureMoments->getFeatureCInvariant(),featureMomentsDes->getFeatureCInvariant(),(1 << 3) | (1 << 5));
227  task.addFeature(featureMoments->getFeatureAlpha(),featureMomentsDes->getFeatureAlpha());
228 
229  task.setLambda(1.) ;
230 }
231 
232 
233 void refreshScene(vpMomentObject &obj){
234  //double x[8] = { 0.05,0.15, 0.2,-0.05 ,-0.15,-0.1,-0.05,0.05};
235  //double y[8] = { 0,0.05, 0.2, 0.2, -0.1,-0.1, 0.05,0};
236  double x[8] = { 1,3, 4,-1 ,-3,-2,-1,1};
237  double y[8] = { 0,1, 4, 4, -2,-2, 1,0};
238  int nbpoints = 8;
239  std::vector<vpPoint> cur_pts;
240 
241  for (int i = 0 ; i < nbpoints ; i++){
242  vpPoint p;
243  p.setWorldCoordinates(x[i]/20,y[i]/20,0.0);
244  p.track(cMo) ;
245  cur_pts.push_back(p);
246  }
247  obj.fromVector(cur_pts);
248 }
249 
250 void init(vpHomogeneousMatrix& _cMo, vpHomogeneousMatrix& _cdMo)
251 
252 {
253  cMo = _cMo; //init source matrix
254  cdMo = _cdMo; //init destination matrix
255  interaction_type = vpServo::CURRENT; //use interaction matrix for current position
256 
257  displayInt.init(Iint,700,0, "Visual servoing with moments") ;
258 
259  paramRobot(); //set up robot parameters
260 
262  initScene(); //initialize graphical scene (for interface)
263  initFeatures();//initialize moment features
264 }
265 
266 void execute(unsigned int nbIter){
267  //init main object: using moments up to order 6
268  vpMomentObject obj(6);
269  //setting object type (disrete, continuous[form polygon])
271 
272  vpTRACE("Display task information " ) ;
273  task.print() ;
274 
275  vpDisplay::display(Iint);
276  robot.getInternalView(Iint);
277  vpDisplay::flush(Iint);
278  unsigned int iter=0;
279 
281  while(iter++<nbIter ){
282  vpColVector v ;
283  //get the cMo
284  cMo = robot.get_cMo();
285  //setup the plane in A,B,C style
286  vpPlane pl;
287  double A,B,C;
288  pl.setABCD(0,0,1.0,0);
289  pl.changeFrame(cMo);
290  planeToABC(pl,A,B,C);
291 
292  //track points, draw points and add refresh our object
293  refreshScene(obj);
294  //this is the most important thing to do: update our moments
295  moments->updateAll(obj);
296  //and update our features. Do it in that order. Features need to use the information computed by moments
297  featureMoments->updateAll(A,B,C);
298 
299  vpDisplay::display(Iint) ;
300  robot.getInternalView(Iint);
301  vpDisplay::flush(Iint);
302 
303  if (iter == 1)
304  vpDisplay::getClick(Iint) ;
305  v = task.computeControlLaw() ;
306 
307  //pilot robot using position control. The displacement is t*v with t=10ms step
308  //robot.setPosition(vpRobot::CAMERA_FRAME,0.01*v);
310 
311 
312  _error = ( task.getError() ).sumSquare();
313  }
314 
315  task.kill();
316 
317  vpTRACE("\n\nClick in the internal view window to end...");
318  vpDisplay::getClick(Iint) ;
319 
320  delete moments;
321  delete momentsDes;
322  delete featureMoments;
323  delete featureMomentsDes;
324 }
325 
326 void removeJointLimits(vpSimulatorAfma6& robot_)
327 {
328  vpColVector limMin(6);
329  vpColVector limMax(6);
330  limMin[0] = vpMath::rad(-3600);
331  limMin[1] = vpMath::rad(-3600);
332  limMin[2] = vpMath::rad(-3600);
333  limMin[3] = vpMath::rad(-3600);
334  limMin[4] = vpMath::rad(-3600);
335  limMin[5] = vpMath::rad(-3600);
336 
337  limMax[0] = vpMath::rad(3600);
338  limMax[1] = vpMath::rad(3600);
339  limMax[2] = vpMath::rad(3600);
340  limMax[3] = vpMath::rad(3600);
341  limMax[4] = vpMath::rad(3600);
342  limMax[5] = vpMath::rad(3600);
343 
344  robot_.setJointLimit(limMin,limMax);
345  robot_.setMaxRotationVelocity(99999);
346  robot_.setMaxTranslationVelocity(999999);
347 }
348 
349 void planeToABC(vpPlane& pl, double& A,double& B, double& C){
350  if(fabs(pl.getD())<std::numeric_limits<double>::epsilon()){
351  std::cout << "Invalid position:" << std::endl;
352  std::cout << cMo << std::endl;
353  std::cout << "Cannot put plane in the form 1/Z=Ax+By+C." << std::endl;
354  throw vpException(vpException::divideByZeroError,"invalid position!");
355  }
356  A=-pl.getA()/pl.getD();
357  B=-pl.getB()/pl.getD();
358  C=-pl.getC()/pl.getD();
359 }
360 
361 void paramRobot(){
362  /*Initialise the robot and especially the camera*/
364  robot.setCurrentViewColor(vpColor(150,150,150));
365  robot.setDesiredViewColor(vpColor(200,200,200));
367  removeJointLimits(robot);
369  robot.setConstantSamplingTimeMode(true);
370  /*Initialise the position of the object relative to the pose of the robot's camera*/
371  robot.initialiseObjectRelativeToCamera(cMo);
372 
373  /*Set the desired position (for the displaypart)*/
374  robot.setDesiredCameraPosition(cdMo);
375  robot.getCameraParameters(cam,Iint);
376 }
377 
378 void setInteractionMatrixType(vpServo::vpServoIteractionMatrixType type){interaction_type=type;}
379 double error(){return _error;}
380 
381 #endif
The object displayed at the desired position is the same than the scene object defined in vpSceneObje...
Perspective projection without distortion model.
void setMaxTranslationVelocity(const double maxVt)
Definition: vpRobot.cpp:242
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
#define vpTRACE
Definition: vpDebug.h:418
A plate with 8 points at coordinates (0.05,0,0), (0.15,0.05,0), (0.2,0.2,0), (-0.05,0.2,0), (-0.15,-0.1,0), (-0.1,-0.1,0), (-0.05,0.05,0) and (0.5,0,0). ach point is represented by a circle with 2cm radius.
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:132
Class to define colors available for display functionnalities.
Definition: vpColor.h:125
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
This class allows to access common vpFeatureMoments in a pre-filled database.
error that can be emited by ViSP classes.
Definition: vpException.h:76
void setJointLimit(const vpColVector &limitMin, const vpColVector &limitMax)
void setABCD(const double a, const double b, const double c, const double d)
Definition: vpPlane.h:102
Class for generic objects.
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const char *title=NULL)
void track(const vpHomogeneousMatrix &cMo)
static void flush(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:2232
virtual vpRobotStateType setRobotState(const vpRobot::vpRobotStateType newState)
Definition: vpRobot.cpp:205
Class that defines what is a point.
Definition: vpPoint.h:65
Display for windows using Direct3D.
Definition: vpDisplayD3D.h:109
void kill()
Definition: vpServo.cpp:189
Initialize the velocity controller.
Definition: vpRobot.h:70
vpColVector getError() const
Definition: vpServo.h:257
vpColVector computeControlLaw()
Definition: vpServo.cpp:902
vpFeatureMomentAlpha & getFeatureAlpha()
void updateAll(double A, double B, double C)
void changeFrame(const vpHomogeneousMatrix &cMo)
Definition: vpPlane.cpp:376
static std::vector< double > getMu3(vpMomentObject &object)
static void display(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:210
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 which enables to project an image in the 3D space and get the view of a virtual camera...
Simulator of Irisa's gantry robot named Afma6.
The vpDisplayGTK allows to display image using the GTK+ library version 1.2.
Definition: vpDisplayGTK.h:145
void extract(vpRotationMatrix &R) const
vpServoIteractionMatrixType
Definition: vpServo.h:187
void fromVector(std::vector< vpPoint > &points)
static double getSurface(vpMomentObject &object)
void setInteractionMatrixType(const vpServoIteractionMatrixType &interactionMatrixType, const vpServoInversionType &interactionMatrixInversion=PSEUDO_INVERSE)
Definition: vpServo.cpp:522
vpFeatureMomentCInvariant & getFeatureCInvariant()
static double rad(double deg)
Definition: vpMath.h:100
void updateAll(vpMomentObject &object)
void setMaxRotationVelocity(const double maxVr)
Definition: vpRobot.cpp:266
This class initializes and allows access to commonly used moments.
static double getAlpha(vpMomentObject &object)
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
vpFeatureMomentGravityCenterNormalized & getFeatureGravityNormalized()
double getB() const
Definition: vpPlane.h:117
void setType(vpObjectType input_type)
void print(const vpServo::vpServoPrintType display_level=ALL, std::ostream &os=std::cout)
Definition: vpServo.cpp:251
double getA() const
Definition: vpPlane.h:115
double getC() const
Definition: vpPlane.h:119
virtual bool getClick(bool blocking=true)=0
This class defines the container for a plane geometrical structure.
Definition: vpPlane.h:67
vpFeatureMomentAreaNormalized & getFeatureAn()
void setServo(const vpServoType &servo_type)
Definition: vpServo.cpp:220
void setVelocity(const vpRobot::vpControlFrameType frame, const vpColVector &v)
Class that consider the case of a translation vector.
double getD() const
Definition: vpPlane.h:121
void setWorldCoordinates(const double ox, const double oy, const double oz)
Set the point world coordinates. We mean here the coordinates of the point in the object frame...
Definition: vpPoint.cpp:74