Visual Servoing Platform  version 3.0.0
vpServo.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 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  * Visual servoing control law.
32  *
33  * Authors:
34  * Eric Marchand
35  * Nicolas Mansard
36  * Fabien Spindler
37  *
38  *****************************************************************************/
39 
40 
41 #include <visp3/vs/vpServo.h>
42 
43 #include <sstream>
44 
45 // Exception
46 #include <visp3/core/vpException.h>
47 
48 // Debug trace
49 #include <visp3/core/vpDebug.h>
50 
69  : L(), error(), J1(), J1p(), s(), sStar(), e1(), e(), q_dot(), v(), servoType(vpServo::NONE),
70  rankJ1(0), featureList(), desiredFeatureList(), featureSelectionList(), lambda(), signInteractionMatrix(1),
71  interactionMatrixType(DESIRED), inversionType(PSEUDO_INVERSE), cVe(), init_cVe(false),
72  cVf(), init_cVf(false), fVe(), init_fVe(false), eJe(), init_eJe(false), fJe(), init_fJe(false),
73  errorComputed(false), interactionMatrixComputed(false), dim_task(0), taskWasKilled(false),
74  forceInteractionMatrixComputation(false), WpW(), I_WpW(), P(), sv(), mu(4.), e1_initial()
75 {
76 }
91  : L(), error(), J1(), J1p(), s(), sStar(), e1(), e(), q_dot(), v(), servoType(servo_type),
92  rankJ1(0), featureList(), desiredFeatureList(), featureSelectionList(), lambda(), signInteractionMatrix(1),
93  interactionMatrixType(DESIRED), inversionType(PSEUDO_INVERSE), cVe(), init_cVe(false),
94  cVf(), init_cVf(false), fVe(), init_fVe(false), eJe(), init_eJe(false), fJe(), init_fJe(false),
95  errorComputed(false), interactionMatrixComputed(false), dim_task(0), taskWasKilled(false),
96  forceInteractionMatrixComputation(false), WpW(), I_WpW(), P(), sv(), mu(4), e1_initial()
97 {
98 }
99 
108 // \exception vpServoException::notKilledProperly : Task was not killed
109 // properly. That means that you should explitly call kill().
110 
112 {
113  if (taskWasKilled == false) {
114  vpTRACE("--- Begin Warning Warning Warning Warning Warning ---");
115  vpTRACE("--- You should explicitly call vpServo.kill()... ---");
116  vpTRACE("--- End Warning Warning Warning Warning Warning ---");
117  // throw(vpServoException(vpServoException::notKilledProperly,
118  // "Task was not killed properly"));
119  }
120 }
121 
122 
137 {
138  // type of visual servoing
140 
141  // Twist transformation matrix
142  init_cVe = false ;
143  init_cVf = false ;
144  init_fVe = false ;
145  // Jacobians
146  init_eJe = false ;
147  init_fJe = false ;
148 
149  dim_task = 0 ;
150 
151  featureList.clear() ;
152  desiredFeatureList.clear() ;
153  featureSelectionList.clear();
154 
156 
159 
160  interactionMatrixComputed = false ;
161  errorComputed = false ;
162 
163  taskWasKilled = false;
164 
166 
167  rankJ1 = 0;
168 }
169 
187 {
188  if (taskWasKilled == false) {
189  // kill the current and desired feature lists
190 
191  // current list
192  for(std::list<vpBasicFeature *>::iterator it = featureList.begin(); it != featureList.end(); ++it) {
193  if ((*it)->getDeallocate() == vpBasicFeature::vpServo) {
194  delete (*it) ;
195  (*it) = NULL ;
196  }
197  }
198  //desired list
199  for(std::list<vpBasicFeature *>::iterator it = desiredFeatureList.begin(); it != desiredFeatureList.end(); ++it) {
200  if ((*it)->getDeallocate() == vpBasicFeature::vpServo) {
201  delete (*it) ;
202  (*it) = NULL ;
203  }
204  }
205 
206  featureList.clear() ;
207  desiredFeatureList.clear() ;
208  taskWasKilled = true;
209  }
210 }
211 
217 void vpServo::setServo(const vpServoType &servo_type)
218 {
219  this->servoType = servo_type ;
220 
223  else
224  signInteractionMatrix = -1 ;
225 
226  // when the control is directly compute in the camera frame
227  // we relieve the end-user to initialize cVa and aJe
229  {
230  vpVelocityTwistMatrix _cVe ; set_cVe(_cVe) ;
231 
232  vpMatrix _eJe ;
233  _eJe.eye(6) ;
234  set_eJe(_eJe) ;
235  };
236 }
237 
238 
247 void
248 vpServo::print(const vpServo::vpServoPrintType displayLevel, std::ostream &os)
249 {
250  switch (displayLevel)
251  {
252  case vpServo::ALL:
253  {
254  os << "Visual servoing task: " <<std::endl ;
255 
256  os << "Type of control law " <<std::endl ;
257  switch( servoType )
258  {
259  case NONE :
260  os << "Type of task have not been chosen yet ! " << std::endl ;
261  break ;
262  case EYEINHAND_CAMERA :
263  os << "Eye-in-hand configuration " << std::endl ;
264  os << "Control in the camera frame " << std::endl ;
265  break ;
266  case EYEINHAND_L_cVe_eJe :
267  os << "Eye-in-hand configuration " << std::endl ;
268  os << "Control in the articular frame " << std::endl ;
269  break ;
270  case EYETOHAND_L_cVe_eJe :
271  os << "Eye-to-hand configuration " << std::endl ;
272  os << "s_dot = _L_cVe_eJe q_dot " << std::endl ;
273  break ;
275  os << "Eye-to-hand configuration " << std::endl ;
276  os << "s_dot = _L_cVe_fVe_eJe q_dot " << std::endl ;
277  break ;
278  case EYETOHAND_L_cVf_fJe :
279  os << "Eye-to-hand configuration " << std::endl ;
280  os << "s_dot = _L_cVf_fJe q_dot " << std::endl ;
281  break ;
282  }
283 
284  os << "List of visual features : s" <<std::endl ;
285  std::list<vpBasicFeature *>::const_iterator it_s;
286  std::list<vpBasicFeature *>::const_iterator it_s_star;
287  std::list<unsigned int>::const_iterator it_select;
288 
289  for (it_s = featureList.begin(), it_select = featureSelectionList.begin(); it_s != featureList.end(); ++it_s, ++it_select)
290  {
291  os << "" ;
292  (*it_s)->print( (*it_select) ) ;
293  }
294 
295  os << "List of desired visual features : s*" <<std::endl ;
296  for (it_s_star = desiredFeatureList.begin(), it_select = featureSelectionList.begin(); it_s_star != desiredFeatureList.end(); ++it_s_star, ++it_select)
297  {
298  os << "" ;
299  (*it_s_star)->print( (*it_select) ) ;
300  }
301 
302  os <<"Interaction Matrix Ls "<<std::endl ;
304  {
305  os << L << std::endl;
306  }
307  else
308  {
309  os << "not yet computed "<<std::endl ;
310  }
311 
312  os <<"Error vector (s-s*) "<<std::endl ;
313  if (errorComputed)
314  {
315  os << error.t() << std::endl;
316  }
317  else
318  {
319  os << "not yet computed "<<std::endl ;
320  }
321 
322  os << "Gain : " << lambda <<std::endl ;
323 
324  break;
325  }
326 
327  case vpServo::CONTROLLER:
328  {
329  os << "Type of control law " <<std::endl ;
330  switch( servoType )
331  {
332  case NONE :
333  os << "Type of task have not been chosen yet ! " << std::endl ;
334  break ;
335  case EYEINHAND_CAMERA :
336  os << "Eye-in-hand configuration " << std::endl ;
337  os << "Control in the camera frame " << std::endl ;
338  break ;
339  case EYEINHAND_L_cVe_eJe :
340  os << "Eye-in-hand configuration " << std::endl ;
341  os << "Control in the articular frame " << std::endl ;
342  break ;
343  case EYETOHAND_L_cVe_eJe :
344  os << "Eye-to-hand configuration " << std::endl ;
345  os << "s_dot = _L_cVe_eJe q_dot " << std::endl ;
346  break ;
348  os << "Eye-to-hand configuration " << std::endl ;
349  os << "s_dot = _L_cVe_fVe_eJe q_dot " << std::endl ;
350  break ;
351  case EYETOHAND_L_cVf_fJe :
352  os << "Eye-to-hand configuration " << std::endl ;
353  os << "s_dot = _L_cVf_fJe q_dot " << std::endl ;
354  break ;
355  }
356  break;
357  }
358 
360  {
361  os << "List of visual features : s" <<std::endl ;
362 
363  std::list<vpBasicFeature *>::const_iterator it_s;
364  std::list<unsigned int>::const_iterator it_select;
365 
366  for (it_s = featureList.begin(), it_select = featureSelectionList.begin(); it_s != featureList.end(); ++it_s, ++it_select)
367  {
368  os << "" ;
369  (*it_s)->print( (*it_select) ) ;
370  }
371  break;
372  }
374  {
375  os << "List of desired visual features : s*" <<std::endl ;
376 
377  std::list<vpBasicFeature *>::const_iterator it_s_star;
378  std::list<unsigned int>::const_iterator it_select;
379 
380  for (it_s_star = desiredFeatureList.begin(), it_select = featureSelectionList.begin(); it_s_star != desiredFeatureList.end(); ++it_s_star, ++it_select)
381  {
382  os << "" ;
383  (*it_s_star)->print( (*it_select) ) ;
384  }
385  break;
386  }
387  case vpServo::GAIN:
388  {
389  os << "Gain : " << lambda <<std::endl ;
390  break;
391  }
393  {
394  os <<"Interaction Matrix Ls "<<std::endl ;
396  os << L << std::endl;
397  }
398  else {
399  os << "not yet computed "<<std::endl ;
400  }
401  break;
402  }
403 
405  case vpServo::MINIMUM:
406 
407  {
408  os <<"Error vector (s-s*) "<<std::endl ;
409  if (errorComputed) {
410  os << error.t() << std::endl;
411  }
412  else {
413  os << "not yet computed "<<std::endl ;
414  }
415 
416  break;
417  }
418  }
419 }
420 
446 void vpServo::addFeature(vpBasicFeature& s_cur, vpBasicFeature &s_star, unsigned int select)
447 {
448  featureList.push_back( &s_cur );
449  desiredFeatureList.push_back( &s_star );
450  featureSelectionList.push_back( select );
451 }
452 
476 void vpServo::addFeature(vpBasicFeature& s_cur, unsigned int select)
477 {
478  featureList.push_back( &s_cur );
479 
480  // in fact we have a problem with s_star that is not defined
481  // by the end user.
482 
483  // If the same user want to compute the interaction at the desired position
484  // this "virtual feature" must exist
485 
486  // a solution is then to duplicate the current feature (s* = s)
487  // and reinitialized s* to 0
488 
489  // it remains the deallocation issue therefore a flag that stipulates that
490  // the feature has been allocated in vpServo is set
491 
492  // vpServo must deallocate the memory (see ~vpServo and kill() )
493 
494  vpBasicFeature *s_star ;
495  s_star = s_cur.duplicate() ;
496 
497  s_star->init() ;
499 
500  desiredFeatureList.push_back( s_star );
501  featureSelectionList.push_back( select );
502 }
503 
505 unsigned int vpServo::getDimension() const
506 {
507  unsigned int dim = 0 ;
508  std::list<vpBasicFeature *>::const_iterator it_s;
509  std::list<unsigned int>::const_iterator it_select;
510 
511  for (it_s = featureList.begin(), it_select = featureSelectionList.begin(); it_s != featureList.end(); ++it_s, ++it_select)
512  {
513  dim += (*it_s)->getDimension(*it_select) ;
514  }
515 
516  return dim;
517 }
518 
520  const vpServoInversionType &interactionMatrixInversion)
521 {
522  this->interactionMatrixType = interactionMatrix_type ;
523  this->inversionType = interactionMatrixInversion ;
524 }
525 
526 
527 static void computeInteractionMatrixFromList (const std::list<vpBasicFeature *> & featureList,
528  const std::list<unsigned int> & featureSelectionList,
529  vpMatrix & L)
530 {
531  if (featureList.empty())
532  {
533  vpERROR_TRACE("feature list empty, cannot compute Ls") ;
535  "feature list empty, cannot compute Ls")) ;
536  }
537 
538  /* The matrix dimension is not known before the affectation loop.
539  * It thus should be allocated on the flight, in the loop.
540  * The first assumption is that the size has not changed. A double
541  * reallocation (realloc(dim*2)) is done if necessary. In particular,
542  * [log_2(dim)+1] reallocations are done for the first matrix computation.
543  * If the allocated size is too large, a correction is done after the loop.
544  * The algorithmic cost is linear in affectation, logarithmic in allocation
545  * numbers and linear in allocation size.
546  */
547 
548  /* First assumption: matrix dimensions have not changed. If 0, they are
549  * initialized to dim 1.*/
550  unsigned int rowL = L.getRows();
551  const unsigned int colL = 6;
552  if (0 == rowL) {
553  rowL = 1;
554  L .resize(rowL, colL);
555  }
556 
557  /* vectTmp is used to store the return values of functions get_s() and
558  * error(). */
559  vpMatrix matrixTmp;
560  unsigned int rowMatrixTmp, colMatrixTmp;
561 
562  /* The cursor are the number of the next case of the vector array to
563  * be affected. A memory reallocation should be done when cursor
564  * is out of the vector-array range.*/
565  unsigned int cursorL = 0;
566 
567  std::list<vpBasicFeature *>::const_iterator it;
568  std::list<unsigned int>::const_iterator it_select;
569 
570  for (it = featureList.begin(), it_select = featureSelectionList.begin(); it != featureList.end(); ++it, ++it_select)
571  {
572  /* Get s. */
573  matrixTmp = (*it)->interaction( *it_select );
574  rowMatrixTmp = matrixTmp .getRows();
575  colMatrixTmp = matrixTmp .getCols();
576 
577  /* Check the matrix L size, and realloc if needed. */
578  while (rowMatrixTmp + cursorL > rowL) {
579  rowL *= 2;
580  L.resize (rowL,colL,false);
581  vpDEBUG_TRACE(15,"Realloc!");
582  }
583 
584  /* Copy the temporarily matrix into L. */
585  for (unsigned int k = 0; k < rowMatrixTmp; ++k, ++cursorL) {
586  for (unsigned int j = 0; j < colMatrixTmp; ++j) {
587  L[cursorL][j] = matrixTmp[k][j];
588  }
589  }
590  }
591 
592  L.resize (cursorL,colL,false);
593 
594  return ;
595 }
596 
597 
605 {
606  try {
607 
608  switch (interactionMatrixType)
609  {
610  case CURRENT:
611  {
612  try
613  {
614  computeInteractionMatrixFromList(this ->featureList,
615  this ->featureSelectionList,
616  L);
617  dim_task = L.getRows() ;
619  }
620 
621  catch(vpException me)
622  {
623  vpERROR_TRACE("Error caught") ;
624  throw ;
625  }
626  }
627  break ;
628  case DESIRED:
629  {
630  try
631  {
633  {
634  computeInteractionMatrixFromList(this ->desiredFeatureList,
635  this ->featureSelectionList, L);
636 
637  dim_task = L.getRows() ;
639  }
640 
641  }
642  catch(vpException me)
643  {
644  vpERROR_TRACE("Error caught") ;
645  throw ;
646  }
647  }
648  break ;
649  case MEAN:
650  {
651  vpMatrix Lstar (L.getRows(), L.getCols());
652  try
653  {
654  computeInteractionMatrixFromList(this ->featureList,
655  this ->featureSelectionList, L);
656  computeInteractionMatrixFromList(this ->desiredFeatureList,
657  this ->featureSelectionList, Lstar);
658  }
659  catch(vpException me)
660  {
661  vpERROR_TRACE("Error caught") ;
662  throw ;
663  }
664  L = (L+Lstar)/2;
665 
666  dim_task = L.getRows() ;
668  }
669  break ;
670  case USER_DEFINED:
671  // dim_task = L.getRows() ;
672  interactionMatrixComputed = false ;
673  break;
674  }
675 
676  }
677  catch(vpException me)
678  {
679  vpERROR_TRACE("Error caught") ;
680  throw ;
681  }
682  return L ;
683 }
684 
694 {
695  if (featureList.empty())
696  {
697  vpERROR_TRACE("feature list empty, cannot compute Ls") ;
699  "feature list empty, cannot compute Ls")) ;
700  }
701  if (desiredFeatureList.empty())
702  {
703  vpERROR_TRACE("feature list empty, cannot compute Ls") ;
705  "feature list empty, cannot compute Ls")) ;
706  }
707 
708  try {
709  vpBasicFeature *current_s ;
710  vpBasicFeature *desired_s ;
711 
712  /* The vector dimensions are not known before the affectation loop.
713  * They thus should be allocated on the flight, in the loop.
714  * The first assumption is that the size has not changed. A double
715  * reallocation (realloc(dim*2)) is done if necessary. In particular,
716  * [log_2(dim)+1] reallocations are done for the first error computation.
717  * If the allocated size is too large, a correction is done after the loop.
718  * The algorithmic cost is linear in affectation, logarithmic in allocation
719  * numbers and linear in allocation size.
720  * No assumptions are made concerning size of each vector: they are
721  * not said equal, and could be different.
722  */
723 
724  /* First assumption: vector dimensions have not changed. If 0, they are
725  * initialized to dim 1.*/
726  unsigned int dimError = error .getRows();
727  unsigned int dimS = s .getRows();
728  unsigned int dimSStar = sStar .getRows();
729  if (0 == dimError) { dimError = 1; error .resize(dimError);}
730  if (0 == dimS) { dimS = 1; s .resize(dimS);}
731  if (0 == dimSStar) { dimSStar = 1; sStar .resize(dimSStar);}
732 
733  /* vectTmp is used to store the return values of functions get_s() and
734  * error(). */
735  vpColVector vectTmp;
736  unsigned int dimVectTmp;
737 
738  /* The cursor are the number of the next case of the vector array to
739  * be affected. A memory reallocation should be done when cursor
740  * is out of the vector-array range.*/
741  unsigned int cursorS = 0;
742  unsigned int cursorSStar = 0;
743  unsigned int cursorError = 0;
744 
745  /* For each cell of the list, copy value of s, s_star and error. */
746  std::list<vpBasicFeature *>::const_iterator it_s;
747  std::list<vpBasicFeature *>::const_iterator it_s_star;
748  std::list<unsigned int>::const_iterator it_select;
749 
750  for (it_s = featureList.begin(), it_s_star = desiredFeatureList.begin(), it_select = featureSelectionList.begin();
751  it_s != featureList.end();
752  ++it_s, ++it_s_star, ++it_select)
753  {
754  current_s = (*it_s);
755  desired_s = (*it_s_star);
756  unsigned int select = (*it_select);
757 
758  /* Get s, and store it in the s vector. */
759  vectTmp = current_s->get_s(select);
760  dimVectTmp = vectTmp .getRows();
761  while (dimVectTmp + cursorS > dimS)
762  { dimS *= 2; s .resize (dimS,false); vpDEBUG_TRACE(15,"Realloc!"); }
763  for (unsigned int k = 0; k < dimVectTmp; ++k) { s[cursorS++] = vectTmp[k]; }
764 
765  /* Get s_star, and store it in the s vector. */
766  vectTmp = desired_s->get_s(select);
767  dimVectTmp = vectTmp .getRows();
768  while (dimVectTmp + cursorSStar > dimSStar) {
769  dimSStar *= 2;
770  sStar.resize (dimSStar,false);
771  }
772  for (unsigned int k = 0; k < dimVectTmp; ++k) {
773  sStar[cursorSStar++] = vectTmp[k];
774  }
775 
776  /* Get error, and store it in the s vector. */
777  vectTmp = current_s->error(*desired_s, select) ;
778  dimVectTmp = vectTmp .getRows();
779  while (dimVectTmp + cursorError > dimError) {
780  dimError *= 2;
781  error.resize (dimError,false);
782  }
783  for (unsigned int k = 0; k < dimVectTmp; ++k) {
784  error[cursorError++] = vectTmp[k];
785  }
786  }
787 
788  /* If too much memory has been allocated, realloc. */
789  s .resize(cursorS,false);
790  sStar .resize(cursorSStar,false);
791  error .resize(cursorError,false);
792 
793  /* Final modifications. */
794  dim_task = error.getRows() ;
795  errorComputed = true ;
796  }
797  catch(vpException me)
798  {
799  vpERROR_TRACE("Error caught") ;
800  throw ;
801  }
802  catch(...)
803  {
804  throw ;
805  }
806  return error ;
807 }
808 
810 {
811  switch (servoType)
812  {
813  case NONE:
814  vpERROR_TRACE("No control law have been yet defined") ;
816  "No control law have been yet defined")) ;
817  break ;
818  case EYEINHAND_CAMERA:
819  return true ;
820  break ;
821  case EYEINHAND_L_cVe_eJe:
822  case EYETOHAND_L_cVe_eJe:
823  if (!init_cVe) vpERROR_TRACE("cVe not initialized") ;
824  if (!init_eJe) vpERROR_TRACE("eJe not initialized") ;
825  return (init_cVe && init_eJe) ;
826  break ;
828  if (!init_cVf) vpERROR_TRACE("cVf not initialized") ;
829  if (!init_fVe) vpERROR_TRACE("fVe not initialized") ;
830  if (!init_eJe) vpERROR_TRACE("eJe not initialized") ;
831  return (init_cVf && init_fVe && init_eJe) ;
832  break ;
833 
834  case EYETOHAND_L_cVf_fJe :
835  if (!init_cVf) vpERROR_TRACE("cVf not initialized") ;
836  if (!init_fJe) vpERROR_TRACE("fJe not initialized") ;
837  return (init_cVf && init_fJe) ;
838  break ;
839  }
840 
841  return false ;
842 }
844 {
845  switch (servoType)
846  {
847  case NONE:
848  vpERROR_TRACE("No control law have been yet defined") ;
850  "No control law have been yet defined")) ;
851  break ;
852  case EYEINHAND_CAMERA:
853  return true ;
854  case EYEINHAND_L_cVe_eJe:
855  if (!init_eJe) vpERROR_TRACE("eJe not updated") ;
856  return (init_eJe) ;
857  break ;
858  case EYETOHAND_L_cVe_eJe:
859  if (!init_cVe) vpERROR_TRACE("cVe not updated") ;
860  if (!init_eJe) vpERROR_TRACE("eJe not updated") ;
861  return (init_cVe && init_eJe) ;
862  break ;
864  if (!init_fVe) vpERROR_TRACE("fVe not updated") ;
865  if (!init_eJe) vpERROR_TRACE("eJe not updated") ;
866  return (init_fVe && init_eJe) ;
867  break ;
868 
869  case EYETOHAND_L_cVf_fJe :
870  if (!init_fJe) vpERROR_TRACE("fJe not updated") ;
871  return (init_fJe) ;
872  break ;
873  }
874 
875  return false ;
876 }
900 {
901  static int iteration =0;
902 
903  try
904  {
905  vpVelocityTwistMatrix cVa ; // Twist transformation matrix
906  vpMatrix aJe ; // Jacobian
907 
908  if (iteration==0)
909  {
910  if (testInitialization() == false) {
911  vpERROR_TRACE("All the matrices are not correctly initialized") ;
913  "Cannot compute control law "
914  "All the matrices are not correctly"
915  "initialized")) ;
916  }
917  }
918  if (testUpdated() == false) {
919  vpERROR_TRACE("All the matrices are not correctly updated") ;
920  }
921 
922  // test if all the required initialization have been done
923  switch (servoType)
924  {
925  case NONE :
926  vpERROR_TRACE("No control law have been yet defined") ;
928  "No control law have been yet defined")) ;
929  break ;
930  case EYEINHAND_CAMERA:
931  case EYEINHAND_L_cVe_eJe:
932  case EYETOHAND_L_cVe_eJe:
933 
934  cVa = cVe ;
935  aJe = eJe ;
936 
937  init_cVe = false ;
938  init_eJe = false ;
939  break ;
941  cVa = cVf*fVe ;
942  aJe = eJe ;
943  init_fVe = false ;
944  init_eJe = false ;
945  break ;
946  case EYETOHAND_L_cVf_fJe :
947  cVa = cVf ;
948  aJe = fJe ;
949  init_fJe = false ;
950  break ;
951  }
952 
954  computeError() ;
955 
956  // compute task Jacobian
957  J1 = L*cVa*aJe ;
958 
959  // handle the eye-in-hand eye-to-hand case
961 
962  // pseudo inverse of the task Jacobian
963  // and rank of the task Jacobian
964  // the image of J1 is also computed to allows the computation
965  // of the projection operator
966  vpMatrix imJ1t, imJ1 ;
967  bool imageComputed = false ;
968 
970  {
971  rankJ1 = J1.pseudoInverse(J1p, sv, 1e-6, imJ1, imJ1t) ;
972 
973  imageComputed = true ;
974  }
975  else
976  J1p = J1.t() ;
977 
978  if (rankJ1 == J1.getCols())
979  {
980  /* if no degrees of freedom remains (rank J1 = ndof)
981  WpW = I, multiply by WpW is useless
982  */
983  e1 = J1p*error ;// primary task
984 
985  WpW.eye(J1.getCols(), J1.getCols()) ;
986  }
987  else
988  {
989  if (imageComputed!=true)
990  {
991  vpMatrix Jtmp ;
992  // image of J1 is computed to allows the computation
993  // of the projection operator
994  rankJ1 = J1.pseudoInverse(Jtmp, sv, 1e-6, imJ1, imJ1t) ;
995  imageComputed = true ;
996  }
997  WpW = imJ1t*imJ1t.t() ;
998 
999 #ifdef DEBUG
1000  std::cout << "rank J1 " << rankJ1 <<std::endl ;
1001  std::cout << "imJ1t"<<std::endl << imJ1t ;
1002  std::cout << "imJ1"<<std::endl << imJ1 ;
1003 
1004  std::cout << "WpW" <<std::endl <<WpW ;
1005  std::cout << "J1" <<std::endl <<J1 ;
1006  std::cout << "J1p" <<std::endl <<J1p ;
1007 #endif
1008  e1 = WpW*J1p*error ;
1009  }
1010  e = - lambda(e1) * e1 ;
1011 
1012  vpMatrix I ;
1013 
1014  I.eye(J1.getCols(),J1.getCols()) ;
1015 
1017 
1018  }
1019  catch(...) {
1020  throw;
1021  }
1022 
1023  iteration++ ;
1024  return e ;
1025 }
1026 
1056 {
1057  static int iteration =0;
1058  //static vpColVector e1_initial;
1059 
1060  try
1061  {
1062  vpVelocityTwistMatrix cVa ; // Twist transformation matrix
1063  vpMatrix aJe ; // Jacobian
1064 
1065  if (iteration==0)
1066  {
1067  if (testInitialization() == false) {
1068  vpERROR_TRACE("All the matrices are not correctly initialized") ;
1070  "Cannot compute control law "
1071  "All the matrices are not correctly"
1072  "initialized")) ;
1073  }
1074  }
1075  if (testUpdated() == false) {
1076  vpERROR_TRACE("All the matrices are not correctly updated") ;
1077  }
1078 
1079  // test if all the required initialization have been done
1080  switch (servoType)
1081  {
1082  case NONE :
1083  vpERROR_TRACE("No control law have been yet defined") ;
1085  "No control law have been yet defined")) ;
1086  break ;
1087  case EYEINHAND_CAMERA:
1088  case EYEINHAND_L_cVe_eJe:
1089  case EYETOHAND_L_cVe_eJe:
1090 
1091  cVa = cVe ;
1092  aJe = eJe ;
1093 
1094  init_cVe = false ;
1095  init_eJe = false ;
1096  break ;
1098  cVa = cVf*fVe ;
1099  aJe = eJe ;
1100  init_fVe = false ;
1101  init_eJe = false ;
1102  break ;
1103  case EYETOHAND_L_cVf_fJe :
1104  cVa = cVf ;
1105  aJe = fJe ;
1106  init_fJe = false ;
1107  break ;
1108  }
1109 
1111  computeError() ;
1112 
1113  // compute task Jacobian
1114  J1 = L*cVa*aJe ;
1115 
1116  // handle the eye-in-hand eye-to-hand case
1118 
1119  // pseudo inverse of the task Jacobian
1120  // and rank of the task Jacobian
1121  // the image of J1 is also computed to allows the computation
1122  // of the projection operator
1123  vpMatrix imJ1t, imJ1 ;
1124  bool imageComputed = false ;
1125 
1127  {
1128  rankJ1 = J1.pseudoInverse(J1p, sv, 1e-6, imJ1, imJ1t) ;
1129 
1130  imageComputed = true ;
1131  }
1132  else
1133  J1p = J1.t() ;
1134 
1135  if (rankJ1 == J1.getCols())
1136  {
1137  /* if no degrees of freedom remains (rank J1 = ndof)
1138  WpW = I, multiply by WpW is useless
1139  */
1140  e1 = J1p*error ;// primary task
1141 
1142  WpW.eye(J1.getCols(), J1.getCols()) ;
1143  }
1144  else
1145  {
1146  if (imageComputed!=true)
1147  {
1148  vpMatrix Jtmp ;
1149  // image of J1 is computed to allows the computation
1150  // of the projection operator
1151  rankJ1 = J1.pseudoInverse(Jtmp, sv, 1e-6, imJ1, imJ1t) ;
1152  imageComputed = true ;
1153  }
1154  WpW = imJ1t*imJ1t.t() ;
1155 
1156 #ifdef DEBUG
1157  std::cout << "rank J1 " << rankJ1 <<std::endl ;
1158  std::cout << "imJ1t"<<std::endl << imJ1t ;
1159  std::cout << "imJ1"<<std::endl << imJ1 ;
1160 
1161  std::cout << "WpW" <<std::endl <<WpW ;
1162  std::cout << "J1" <<std::endl <<J1 ;
1163  std::cout << "J1p" <<std::endl <<J1p ;
1164 #endif
1165  e1 = WpW*J1p*error ;
1166  }
1167 
1168  // memorize the initial e1 value if the function is called the first time or if the time given as parameter is equal to 0.
1169  if (iteration==0 || std::fabs(t) < std::numeric_limits<double>::epsilon()) {
1170  e1_initial = e1;
1171  }
1172  // Security check. If size of e1_initial and e1 differ, that means that e1_initial was not set
1173  if (e1_initial.getRows() != e1.getRows())
1174  e1_initial = e1;
1175 
1176  e = - lambda(e1) * e1 + lambda(e1) * e1_initial*exp(-mu*t);
1177 
1178  vpMatrix I ;
1179 
1180  I.eye(J1.getCols(), J1.getCols()) ;
1181 
1183  }
1184  catch(...) {
1185  throw;
1186  }
1187 
1188  iteration++ ;
1189  return e ;
1190 }
1191 
1221 {
1222  static int iteration =0;
1223 
1224  try
1225  {
1226  vpVelocityTwistMatrix cVa ; // Twist transformation matrix
1227  vpMatrix aJe ; // Jacobian
1228 
1229  if (iteration==0)
1230  {
1231  if (testInitialization() == false) {
1232  vpERROR_TRACE("All the matrices are not correctly initialized") ;
1234  "Cannot compute control law "
1235  "All the matrices are not correctly"
1236  "initialized")) ;
1237  }
1238  }
1239  if (testUpdated() == false) {
1240  vpERROR_TRACE("All the matrices are not correctly updated") ;
1241  }
1242 
1243  // test if all the required initialization have been done
1244  switch (servoType)
1245  {
1246  case NONE :
1247  vpERROR_TRACE("No control law have been yet defined") ;
1249  "No control law have been yet defined")) ;
1250  break ;
1251  case EYEINHAND_CAMERA:
1252  case EYEINHAND_L_cVe_eJe:
1253  case EYETOHAND_L_cVe_eJe:
1254 
1255  cVa = cVe ;
1256  aJe = eJe ;
1257 
1258  init_cVe = false ;
1259  init_eJe = false ;
1260  break ;
1262  cVa = cVf*fVe ;
1263  aJe = eJe ;
1264  init_fVe = false ;
1265  init_eJe = false ;
1266  break ;
1267  case EYETOHAND_L_cVf_fJe :
1268  cVa = cVf ;
1269  aJe = fJe ;
1270  init_fJe = false ;
1271  break ;
1272  }
1273 
1275  computeError() ;
1276 
1277  // compute task Jacobian
1278  J1 = L*cVa*aJe ;
1279 
1280  // handle the eye-in-hand eye-to-hand case
1282 
1283  // pseudo inverse of the task Jacobian
1284  // and rank of the task Jacobian
1285  // the image of J1 is also computed to allows the computation
1286  // of the projection operator
1287  vpMatrix imJ1t, imJ1 ;
1288  bool imageComputed = false ;
1289 
1291  {
1292  rankJ1 = J1.pseudoInverse(J1p, sv, 1e-6, imJ1, imJ1t) ;
1293 
1294  imageComputed = true ;
1295  }
1296  else
1297  J1p = J1.t() ;
1298 
1299  if (rankJ1 == J1.getCols())
1300  {
1301  /* if no degrees of freedom remains (rank J1 = ndof)
1302  WpW = I, multiply by WpW is useless
1303  */
1304  e1 = J1p*error ;// primary task
1305 
1306  WpW.eye(J1.getCols(), J1.getCols()) ;
1307  }
1308  else
1309  {
1310  if (imageComputed!=true)
1311  {
1312  vpMatrix Jtmp ;
1313  // image of J1 is computed to allows the computation
1314  // of the projection operator
1315  rankJ1 = J1.pseudoInverse(Jtmp, sv, 1e-6, imJ1, imJ1t) ;
1316  imageComputed = true ;
1317  }
1318  WpW = imJ1t*imJ1t.t() ;
1319 
1320 #ifdef DEBUG
1321  std::cout << "rank J1 " << rankJ1 <<std::endl ;
1322  std::cout << "imJ1t"<<std::endl << imJ1t ;
1323  std::cout << "imJ1"<<std::endl << imJ1 ;
1324 
1325  std::cout << "WpW" <<std::endl <<WpW ;
1326  std::cout << "J1" <<std::endl <<J1 ;
1327  std::cout << "J1p" <<std::endl <<J1p ;
1328 #endif
1329  e1 = WpW*J1p*error ;
1330  }
1331 
1332  // memorize the initial e1 value if the function is called the first time or if the time given as parameter is equal to 0.
1333  if (iteration==0 || std::fabs(t) < std::numeric_limits<double>::epsilon()) {
1334  e1_initial = e1;
1335  }
1336  // Security check. If size of e1_initial and e1 differ, that means that e1_initial was not set
1337  if (e1_initial.getRows() != e1.getRows())
1338  e1_initial = e1;
1339 
1340  e = - lambda(e1) * e1 + (e_dot_init + lambda(e1) * e1_initial)*exp(-mu*t);
1341 
1342  vpMatrix I ;
1343 
1344  I.eye(J1.getCols(), J1.getCols()) ;
1345 
1347  }
1348  catch(...) {
1349  throw;
1350  }
1351 
1352  iteration++ ;
1353  return e ;
1354 }
1355 
1357 {
1358  // Initialization
1359  unsigned int n = J1.getCols();
1360  P.resize(n,n);
1361 
1362  vpMatrix I;
1363  I.eye(n);
1364 
1365  //Compute classical projection operator
1366  I_WpW = (I - WpW) ;
1367 
1368  // Compute gain depending by the task error to ensure a smooth change between the operators.
1369  double e0_ = 0.1;
1370  double e1_ = 0.7;
1371  double sig = 0.0;
1372 
1373  double norm_e = error.euclideanNorm() ;
1374  if (norm_e > e1_)
1375  sig = 1.0;
1376  else if (e0_ <= norm_e && norm_e <= e1_ )
1377  sig = 1.0 / (1.0 + exp(-12.0 * ( (norm_e-e0_)/((e1_-e0_))) + 6.0 ) );
1378  else
1379  sig = 0.0;
1380 
1381  vpMatrix J1t = J1.transpose();
1382 
1383  double pp = (error.t() * (J1 * J1t) * error);
1384 
1385  vpMatrix ee_t(n,n);
1386  ee_t = error * error.t();
1387 
1388  vpMatrix P_norm_e(n,n);
1389  P_norm_e = I - (1.0 / pp ) * J1t * ee_t * J1;
1390 
1391  P = sig * P_norm_e + (1 - sig) * I_WpW;
1392 
1393  return;
1394 }
1395 
1458 vpColVector vpServo::secondaryTask(const vpColVector &de2dt, const bool &useLargeProjectionOperator)
1459 {
1460  vpColVector sec ;
1461 
1462  if (!useLargeProjectionOperator)
1463  {
1464  if (rankJ1 == J1.getCols())
1465  {
1466  vpERROR_TRACE("no degree of freedom is free, cannot use secondary task") ;
1468  "no degree of freedom is free, cannot use secondary task")) ;
1469  }
1470  else
1471  {
1472 #if 0
1473  // computed in computeControlLaw()
1474  vpMatrix I ;
1475 
1476  I.resize(J1.getCols(),J1.getCols()) ;
1477  I.setIdentity() ;
1478  I_WpW = (I - WpW) ;
1479 #endif
1480  // std::cout << "I-WpW" << std::endl << I_WpW <<std::endl ;
1481  sec = I_WpW*de2dt ;
1482  }
1483  }
1484 
1485  else
1486  sec = P*de2dt;
1487 
1488  return sec ;
1489 }
1490 
1558 vpColVector vpServo::secondaryTask(const vpColVector &e2, const vpColVector &de2dt, const bool &useLargeProjectionOperator)
1559 {
1560  vpColVector sec ;
1561 
1562  if (!useLargeProjectionOperator)
1563  {
1564  if (rankJ1 == J1.getCols())
1565  {
1566  vpERROR_TRACE("no degree of freedom is free, cannot use secondary task") ;
1568  "no degree of freedom is free, cannot use secondary task")) ;
1569  }
1570  else
1571  {
1572 
1573 #if 0
1574  // computed in computeControlLaw()
1575  vpMatrix I ;
1576 
1577  I.resize(J1.getCols(),J1.getCols()) ;
1578  I.setIdentity() ;
1579 
1580  I_WpW = (I - WpW) ;
1581 #endif
1582 
1583  // To be coherent with the primary task the gain must be the same between
1584  // primary and secondary task.
1585  sec = -lambda(e1) *I_WpW*e2 + I_WpW *de2dt ;
1586 
1587 
1588  }
1589  }
1590  else
1591  sec = -lambda(e1) * P *e2 + P *de2dt ;
1592 
1593 
1594  return sec ;
1595 }
1596 
1630  const vpColVector &qmin, const vpColVector &qmax,
1631  const double &rho, const double &rho1, const double &lambda_tune) const
1632 {
1633  unsigned int const n = J1.getCols();
1634 
1635  if (qmin.size() != n || qmax.size() != n )
1636  {
1637  std::stringstream msg;
1638  msg << "Dimension vector qmin (" << qmin.size() << ") or qmax () does not correspond to the number of jacobian columns";
1639  msg << "qmin size: " << qmin.size() << std::endl;
1641  }
1642  if (q.size() != n || dq.size() != n )
1643  {
1644  vpERROR_TRACE("Dimension vector q or dq does not correspont to the number of jacobian columns") ;
1646  "Dimension vector q or dq does not correspont to the number of jacobian columns")) ;
1647  }
1648 
1649  double lambda_l = 0.0;
1650 
1651  vpColVector q2 (n);
1652 
1653  vpColVector q_l0_min(n);
1654  vpColVector q_l0_max(n);
1655  vpColVector q_l1_min(n);
1656  vpColVector q_l1_max(n);
1657 
1658  // Computation of gi ([nx1] vector) and lambda_l ([nx1] vector)
1659  vpMatrix g(n,n);
1660  vpColVector q2_i(n);
1661 
1662  for(unsigned int i = 0; i < n; i++)
1663  {
1664  q_l0_min[i] = qmin[i] + rho *(qmax[i] - qmin[i]);
1665  q_l0_max[i] = qmax[i] - rho *(qmax[i] - qmin[i]);
1666 
1667  q_l1_min[i] = q_l0_min[i] - rho * rho1 * (qmax[i] - qmin[i]);
1668  q_l1_max[i] = q_l0_max[i] + rho * rho1 * (qmax[i] - qmin[i]);
1669 
1670  if (q[i] < q_l0_min[i] )
1671  g[i][i] = -1;
1672  else if (q[i] > q_l0_max[i] )
1673  g[i][i] = 1;
1674  else
1675  g[i][i]= 0;
1676  }
1677 
1678  for(unsigned int i = 0; i < n; i++)
1679  {
1680  if (q[i] > q_l0_min[i] && q[i] < q_l0_max[i])
1681  q2_i = 0 * q2_i;
1682 
1683  else
1684  {
1685  vpColVector Pg_i(n);
1686  Pg_i = (P * g.getCol(i));
1687  double b = ( vpMath::abs(dq[i]) )/( vpMath::abs( Pg_i[i] ) );
1688 
1689  if (b < 1.) // If the ratio b is big we don't activate the joint avoidance limit for the joint.
1690  {
1691  if (q[i] < q_l1_min[i] || q[i] > q_l1_max[i] )
1692  q2_i = - (1 + lambda_tune) * b * Pg_i;
1693 
1694  else
1695  {
1696  if (q[i] >= q_l0_max[i] && q[i] <= q_l1_max[i] )
1697  lambda_l = 1 / (1 + exp(-12 *( (q[i] - q_l0_max[i]) / (q_l1_max[i] - q_l0_max[i]) ) + 6 ) );
1698 
1699  else if (q[i] >= q_l1_min[i] && q[i] <= q_l0_min[i])
1700  lambda_l = 1 / (1 + exp(-12 *( (q[i] - q_l0_min[i]) / (q_l1_min[i] - q_l0_min[i]) ) + 6 ) );
1701 
1702  q2_i = - lambda_l * (1 + lambda_tune)* b * Pg_i;
1703  }
1704  }
1705  }
1706  q2 = q2 + q2_i;
1707  }
1708  return q2;
1709 }
1710 
1724 {
1725  return I_WpW;
1726 }
1727 
1728 
1742 {
1743  return P;
1744 }
1745 
1746 
1760 {
1761  return J1;
1762 }
1781 {
1782  return J1p;
1783 }
1794 unsigned int vpServo::getTaskRank() const
1795 {
1796  return rankJ1;
1797 }
1798 
1815 {
1816  return WpW;
1817 }
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:92
unsigned int getDimension() const
Return the task dimension.
Definition: vpServo.cpp:505
vpServoType servoType
Chosen visual servoing control law.
Definition: vpServo.h:513
void setDeallocate(vpBasicFeatureDeallocatorType d)
bool interactionMatrixComputed
true if the interaction matrix has been computed.
Definition: vpServo.h:571
bool taskWasKilled
Flag to indicate if the task was killed.
Definition: vpServo.h:575
void resize(const unsigned int nrows, const unsigned int ncols, const bool flagNullify=true)
Definition: vpArray2D.h:167
vpMatrix getTaskJacobian() const
Definition: vpServo.cpp:1759
unsigned int rankJ1
Rank of the task Jacobian.
Definition: vpServo.h:516
vpVelocityTwistMatrix cVf
Twist transformation matrix between Rf and Rc.
Definition: vpServo.h:547
double euclideanNorm() const
bool init_cVf
Definition: vpServo.h:548
vpVelocityTwistMatrix fVe
Twist transformation matrix between Re and Rf.
Definition: vpServo.h:550
vpColVector sv
Singular values from the pseudo inverse.
Definition: vpServo.h:604
vpServoType
Definition: vpServo.h:157
#define vpERROR_TRACE
Definition: vpDebug.h:391
vpColVector e1
Primary task .
Definition: vpServo.h:503
bool init_cVe
Definition: vpServo.h:545
void set_eJe(const vpMatrix &eJe_)
Definition: vpServo.h:459
Error that can be emited by the vpServo class and its derivates.
void addFeature(vpBasicFeature &s, vpBasicFeature &s_star, const unsigned int select=vpBasicFeature::FEATURE_ALL)
Definition: vpServo.cpp:446
error that can be emited by ViSP classes.
Definition: vpException.h:73
vpServoInversionType
Definition: vpServo.h:195
vpMatrix fJe
Jacobian expressed in the robot reference frame.
Definition: vpServo.h:561
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:156
virtual vpColVector error(const vpBasicFeature &s_star, const unsigned int select=FEATURE_ALL)
Compute the error between two visual features from a subset of the possible features.
unsigned int getCols() const
Return the number of columns of the 2D array.
Definition: vpArray2D.h:154
vpMatrix getI_WpW() const
Definition: vpServo.cpp:1723
unsigned int dim_task
Dimension of the task updated during computeControlLaw().
Definition: vpServo.h:573
vpServoInversionType inversionType
Definition: vpServo.h:536
static Type abs(const Type &x)
Definition: vpMath.h:162
vpColVector secondaryTask(const vpColVector &de2dt, const bool &useLargeProjectionOperator=false)
Definition: vpServo.cpp:1458
class that defines what is a visual feature
double mu
Definition: vpServo.h:606
vpMatrix computeInteractionMatrix()
Definition: vpServo.cpp:604
std::list< unsigned int > featureSelectionList
Definition: vpServo.h:524
void kill()
Definition: vpServo.cpp:186
vp_deprecated void setIdentity(const double &val=1.0)
Definition: vpMatrix.cpp:209
bool testInitialization()
Definition: vpServo.cpp:809
vpColVector computeError()
Definition: vpServo.cpp:693
int signInteractionMatrix
Definition: vpServo.h:531
vpColVector computeControlLaw()
Definition: vpServo.cpp:899
#define vpTRACE
Definition: vpDebug.h:414
vpMatrix J1
Task Jacobian .
Definition: vpServo.h:491
vpMatrix L
Interaction matrix.
Definition: vpServo.h:485
vpRowVector t() const
bool init_fVe
Definition: vpServo.h:551
vpColVector getCol(const unsigned int j) const
Definition: vpMatrix.cpp:2250
bool forceInteractionMatrixComputation
Force the interaction matrix computation even if it is already done.
Definition: vpServo.h:577
vpMatrix transpose() const
Definition: vpMatrix.cpp:247
vpAdaptiveGain lambda
Gain used in the control law.
Definition: vpServo.h:527
vpVelocityTwistMatrix cVe
Twist transformation matrix between Re and Rc.
Definition: vpServo.h:544
Implementation of a velocity twist matrix and operations on such kind of matrices.
unsigned int getRows() const
Return the number of rows of the 2D array.
Definition: vpArray2D.h:152
vpColVector s
Definition: vpServo.h:497
vpServoIteractionMatrixType
Definition: vpServo.h:183
virtual void init()=0
vpServo()
Definition: vpServo.cpp:68
vpColVector e1_initial
Definition: vpServo.h:608
void setInteractionMatrixType(const vpServoIteractionMatrixType &interactionMatrixType, const vpServoInversionType &interactionMatrixInversion=PSEUDO_INVERSE)
Definition: vpServo.cpp:519
vpColVector e
Task .
Definition: vpServo.h:505
vpColVector secondaryTaskJointLimitAvoidance(const vpColVector &q, const vpColVector &dq, const vpColVector &jointMin, const vpColVector &jointMax, const double &rho=0.1, const double &rho1=0.3, const double &lambda_tune=0.7) const
Definition: vpServo.cpp:1629
vpMatrix getTaskJacobianPseudoInverse() const
Definition: vpServo.cpp:1780
vpMatrix P
Definition: vpServo.h:599
vpMatrix t() const
Definition: vpMatrix.cpp:221
void computeProjectionOperators()
Definition: vpServo.cpp:1356
std::list< vpBasicFeature * > desiredFeatureList
List of desired visual features .
Definition: vpServo.h:521
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
virtual ~vpServo()
Definition: vpServo.cpp:111
void set_cVe(const vpVelocityTwistMatrix &cVe_)
Definition: vpServo.h:434
bool init_fJe
Definition: vpServo.h:562
vpMatrix getLargeP() const
Definition: vpServo.cpp:1741
No degree of freedom is available to achieve the secondary task.
void print(const vpServo::vpServoPrintType display_level=ALL, std::ostream &os=std::cout)
Definition: vpServo.cpp:248
vpMatrix I_WpW
Projection operators .
Definition: vpServo.h:582
vpColVector sStar
Definition: vpServo.h:500
#define vpDEBUG_TRACE
Definition: vpDebug.h:478
bool testUpdated()
Definition: vpServo.cpp:843
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.
Definition: vpMatrix.cpp:1756
virtual vpBasicFeature * duplicate() const =0
bool errorComputed
true if the error has been computed.
Definition: vpServo.h:569
vpMatrix WpW
Projection operators .
Definition: vpServo.h:580
bool init_eJe
Definition: vpServo.h:559
vpMatrix J1p
Pseudo inverse of the task Jacobian.
Definition: vpServo.h:493
vpMatrix getWpW() const
Definition: vpServo.cpp:1814
vpColVector get_s(unsigned int select=FEATURE_ALL) const
Get the feature vector .
std::list< vpBasicFeature * > featureList
List of current visual features .
Definition: vpServo.h:519
void setServo(const vpServoType &servo_type)
Definition: vpServo.cpp:217
vpServoPrintType
Definition: vpServo.h:201
vpColVector error
Definition: vpServo.h:489
void init()
Basic initialization.
Definition: vpServo.cpp:136
void eye()
Definition: vpMatrix.cpp:194
unsigned int getTaskRank() const
Definition: vpServo.cpp:1794
vpServoIteractionMatrixType interactionMatrixType
Type of the interaction matrox (current, mean, desired, user)
Definition: vpServo.h:533
vpMatrix eJe
Jacobian expressed in the end-effector frame.
Definition: vpServo.h:558
Current or desired feature list is empty.
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:217