Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpServo.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  * 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  iscJcIdentity(true), cJc(6,6)
76 {
77  cJc.eye();
78 }
79 
94  : L(), error(), J1(), J1p(), s(), sStar(), e1(), e(), q_dot(), v(), servoType(servo_type),
95  rankJ1(0), featureList(), desiredFeatureList(), featureSelectionList(), lambda(), signInteractionMatrix(1),
96  interactionMatrixType(DESIRED), inversionType(PSEUDO_INVERSE), cVe(), init_cVe(false),
97  cVf(), init_cVf(false), fVe(), init_fVe(false), eJe(), init_eJe(false), fJe(), init_fJe(false),
98  errorComputed(false), interactionMatrixComputed(false), dim_task(0), taskWasKilled(false),
99  forceInteractionMatrixComputation(false), WpW(), I_WpW(), P(), sv(), mu(4), e1_initial(),
100  iscJcIdentity(true), cJc(6,6)
101 {
102  cJc.eye();
103 }
104 
113 // \exception vpServoException::notKilledProperly : Task was not killed
114 // properly. That means that you should explitly call kill().
115 
117 {
118  if (taskWasKilled == false) {
119  vpTRACE("--- Begin Warning Warning Warning Warning Warning ---");
120  vpTRACE("--- You should explicitly call vpServo.kill()... ---");
121  vpTRACE("--- End Warning Warning Warning Warning Warning ---");
122  // throw(vpServoException(vpServoException::notKilledProperly,
123  // "Task was not killed properly"));
124  }
125 }
126 
127 
142 {
143  // type of visual servoing
145 
146  // Twist transformation matrix
147  init_cVe = false ;
148  init_cVf = false ;
149  init_fVe = false ;
150  // Jacobians
151  init_eJe = false ;
152  init_fJe = false ;
153 
154  dim_task = 0 ;
155 
156  featureList.clear() ;
157  desiredFeatureList.clear() ;
158  featureSelectionList.clear();
159 
161 
164 
165  interactionMatrixComputed = false ;
166  errorComputed = false ;
167 
168  taskWasKilled = false;
169 
171 
172  rankJ1 = 0;
173 }
174 
192 {
193  if (taskWasKilled == false) {
194  // kill the current and desired feature lists
195 
196  // current list
197  for(std::list<vpBasicFeature *>::iterator it = featureList.begin(); it != featureList.end(); ++it) {
198  if ((*it)->getDeallocate() == vpBasicFeature::vpServo) {
199  delete (*it) ;
200  (*it) = NULL ;
201  }
202  }
203  //desired list
204  for(std::list<vpBasicFeature *>::iterator it = desiredFeatureList.begin(); it != desiredFeatureList.end(); ++it) {
205  if ((*it)->getDeallocate() == vpBasicFeature::vpServo) {
206  delete (*it) ;
207  (*it) = NULL ;
208  }
209  }
210 
211  featureList.clear() ;
212  desiredFeatureList.clear() ;
213  taskWasKilled = true;
214  }
215 }
216 
222 void vpServo::setServo(const vpServoType &servo_type)
223 {
224  this->servoType = servo_type ;
225 
228  else
229  signInteractionMatrix = -1 ;
230 
231  // when the control is directly compute in the camera frame
232  // we relieve the end-user to initialize cVa and aJe
234  {
235  vpVelocityTwistMatrix _cVe ; set_cVe(_cVe) ;
236 
237  vpMatrix _eJe ;
238  _eJe.eye(6) ;
239  set_eJe(_eJe) ;
240  };
241 }
242 
286 void
288 {
289  if(dof.size() == 6)
290  {
291  iscJcIdentity = true;
292  for(unsigned int i = 0 ; i < 6 ; i++) {
293  if(std::fabs(dof[i]) > std::numeric_limits<double>::epsilon()){
294  cJc[i][i] = 1.0;
295  }
296  else{
297  cJc[i][i] = 0.0;
298  iscJcIdentity = false;
299  }
300  }
301  }
302 }
303 
304 
313 void
314 vpServo::print(const vpServo::vpServoPrintType displayLevel, std::ostream &os)
315 {
316  switch (displayLevel)
317  {
318  case vpServo::ALL:
319  {
320  os << "Visual servoing task: " <<std::endl ;
321 
322  os << "Type of control law " <<std::endl ;
323  switch( servoType )
324  {
325  case NONE :
326  os << "Type of task have not been chosen yet ! " << std::endl ;
327  break ;
328  case EYEINHAND_CAMERA :
329  os << "Eye-in-hand configuration " << std::endl ;
330  os << "Control in the camera frame " << std::endl ;
331  break ;
332  case EYEINHAND_L_cVe_eJe :
333  os << "Eye-in-hand configuration " << std::endl ;
334  os << "Control in the articular frame " << std::endl ;
335  break ;
336  case EYETOHAND_L_cVe_eJe :
337  os << "Eye-to-hand configuration " << std::endl ;
338  os << "s_dot = _L_cVe_eJe q_dot " << std::endl ;
339  break ;
341  os << "Eye-to-hand configuration " << std::endl ;
342  os << "s_dot = _L_cVe_fVe_eJe q_dot " << std::endl ;
343  break ;
344  case EYETOHAND_L_cVf_fJe :
345  os << "Eye-to-hand configuration " << std::endl ;
346  os << "s_dot = _L_cVf_fJe q_dot " << std::endl ;
347  break ;
348  }
349 
350  os << "List of visual features : s" <<std::endl ;
351  std::list<vpBasicFeature *>::const_iterator it_s;
352  std::list<vpBasicFeature *>::const_iterator it_s_star;
353  std::list<unsigned int>::const_iterator it_select;
354 
355  for (it_s = featureList.begin(), it_select = featureSelectionList.begin(); it_s != featureList.end(); ++it_s, ++it_select)
356  {
357  os << "" ;
358  (*it_s)->print( (*it_select) ) ;
359  }
360 
361  os << "List of desired visual features : s*" <<std::endl ;
362  for (it_s_star = desiredFeatureList.begin(), it_select = featureSelectionList.begin(); it_s_star != desiredFeatureList.end(); ++it_s_star, ++it_select)
363  {
364  os << "" ;
365  (*it_s_star)->print( (*it_select) ) ;
366  }
367 
368  os <<"Interaction Matrix Ls "<<std::endl ;
370  {
371  os << L << std::endl;
372  }
373  else
374  {
375  os << "not yet computed "<<std::endl ;
376  }
377 
378  os <<"Error vector (s-s*) "<<std::endl ;
379  if (errorComputed)
380  {
381  os << error.t() << std::endl;
382  }
383  else
384  {
385  os << "not yet computed "<<std::endl ;
386  }
387 
388  os << "Gain : " << lambda <<std::endl ;
389 
390  break;
391  }
392 
393  case vpServo::CONTROLLER:
394  {
395  os << "Type of control law " <<std::endl ;
396  switch( servoType )
397  {
398  case NONE :
399  os << "Type of task have not been chosen yet ! " << std::endl ;
400  break ;
401  case EYEINHAND_CAMERA :
402  os << "Eye-in-hand configuration " << std::endl ;
403  os << "Control in the camera frame " << std::endl ;
404  break ;
405  case EYEINHAND_L_cVe_eJe :
406  os << "Eye-in-hand configuration " << std::endl ;
407  os << "Control in the articular frame " << std::endl ;
408  break ;
409  case EYETOHAND_L_cVe_eJe :
410  os << "Eye-to-hand configuration " << std::endl ;
411  os << "s_dot = _L_cVe_eJe q_dot " << std::endl ;
412  break ;
414  os << "Eye-to-hand configuration " << std::endl ;
415  os << "s_dot = _L_cVe_fVe_eJe q_dot " << std::endl ;
416  break ;
417  case EYETOHAND_L_cVf_fJe :
418  os << "Eye-to-hand configuration " << std::endl ;
419  os << "s_dot = _L_cVf_fJe q_dot " << std::endl ;
420  break ;
421  }
422  break;
423  }
424 
426  {
427  os << "List of visual features : s" <<std::endl ;
428 
429  std::list<vpBasicFeature *>::const_iterator it_s;
430  std::list<unsigned int>::const_iterator it_select;
431 
432  for (it_s = featureList.begin(), it_select = featureSelectionList.begin(); it_s != featureList.end(); ++it_s, ++it_select)
433  {
434  os << "" ;
435  (*it_s)->print( (*it_select) ) ;
436  }
437  break;
438  }
440  {
441  os << "List of desired visual features : s*" <<std::endl ;
442 
443  std::list<vpBasicFeature *>::const_iterator it_s_star;
444  std::list<unsigned int>::const_iterator it_select;
445 
446  for (it_s_star = desiredFeatureList.begin(), it_select = featureSelectionList.begin(); it_s_star != desiredFeatureList.end(); ++it_s_star, ++it_select)
447  {
448  os << "" ;
449  (*it_s_star)->print( (*it_select) ) ;
450  }
451  break;
452  }
453  case vpServo::GAIN:
454  {
455  os << "Gain : " << lambda <<std::endl ;
456  break;
457  }
459  {
460  os <<"Interaction Matrix Ls "<<std::endl ;
462  os << L << std::endl;
463  }
464  else {
465  os << "not yet computed "<<std::endl ;
466  }
467  break;
468  }
469 
471  case vpServo::MINIMUM:
472 
473  {
474  os <<"Error vector (s-s*) "<<std::endl ;
475  if (errorComputed) {
476  os << error.t() << std::endl;
477  }
478  else {
479  os << "not yet computed "<<std::endl ;
480  }
481 
482  break;
483  }
484  }
485 }
486 
512 void vpServo::addFeature(vpBasicFeature& s_cur, vpBasicFeature &s_star, unsigned int select)
513 {
514  featureList.push_back( &s_cur );
515  desiredFeatureList.push_back( &s_star );
516  featureSelectionList.push_back( select );
517 }
518 
542 void vpServo::addFeature(vpBasicFeature& s_cur, unsigned int select)
543 {
544  featureList.push_back( &s_cur );
545 
546  // in fact we have a problem with s_star that is not defined
547  // by the end user.
548 
549  // If the same user want to compute the interaction at the desired position
550  // this "virtual feature" must exist
551 
552  // a solution is then to duplicate the current feature (s* = s)
553  // and reinitialized s* to 0
554 
555  // it remains the deallocation issue therefore a flag that stipulates that
556  // the feature has been allocated in vpServo is set
557 
558  // vpServo must deallocate the memory (see ~vpServo and kill() )
559 
560  vpBasicFeature *s_star ;
561  s_star = s_cur.duplicate() ;
562 
563  s_star->init() ;
565 
566  desiredFeatureList.push_back( s_star );
567  featureSelectionList.push_back( select );
568 }
569 
571 unsigned int vpServo::getDimension() const
572 {
573  unsigned int dim = 0 ;
574  std::list<vpBasicFeature *>::const_iterator it_s;
575  std::list<unsigned int>::const_iterator it_select;
576 
577  for (it_s = featureList.begin(), it_select = featureSelectionList.begin(); it_s != featureList.end(); ++it_s, ++it_select)
578  {
579  dim += (*it_s)->getDimension(*it_select) ;
580  }
581 
582  return dim;
583 }
584 
586  const vpServoInversionType &interactionMatrixInversion)
587 {
588  this->interactionMatrixType = interactionMatrix_type ;
589  this->inversionType = interactionMatrixInversion ;
590 }
591 
592 
593 static void computeInteractionMatrixFromList (const std::list<vpBasicFeature *> & featureList,
594  const std::list<unsigned int> & featureSelectionList,
595  vpMatrix & L)
596 {
597  if (featureList.empty())
598  {
599  vpERROR_TRACE("feature list empty, cannot compute Ls") ;
601  "feature list empty, cannot compute Ls")) ;
602  }
603 
604  /* The matrix dimension is not known before the affectation loop.
605  * It thus should be allocated on the flight, in the loop.
606  * The first assumption is that the size has not changed. A double
607  * reallocation (realloc(dim*2)) is done if necessary. In particular,
608  * [log_2(dim)+1] reallocations are done for the first matrix computation.
609  * If the allocated size is too large, a correction is done after the loop.
610  * The algorithmic cost is linear in affectation, logarithmic in allocation
611  * numbers and linear in allocation size.
612  */
613 
614  /* First assumption: matrix dimensions have not changed. If 0, they are
615  * initialized to dim 1.*/
616  unsigned int rowL = L.getRows();
617  const unsigned int colL = 6;
618  if (0 == rowL) {
619  rowL = 1;
620  L .resize(rowL, colL);
621  }
622 
623  /* vectTmp is used to store the return values of functions get_s() and
624  * error(). */
625  vpMatrix matrixTmp;
626 
627  /* The cursor are the number of the next case of the vector array to
628  * be affected. A memory reallocation should be done when cursor
629  * is out of the vector-array range.*/
630  unsigned int cursorL = 0;
631 
632  std::list<vpBasicFeature *>::const_iterator it;
633  std::list<unsigned int>::const_iterator it_select;
634 
635  for (it = featureList.begin(), it_select = featureSelectionList.begin(); it != featureList.end(); ++it, ++it_select)
636  {
637  /* Get s. */
638  matrixTmp = (*it)->interaction( *it_select );
639  unsigned int rowMatrixTmp = matrixTmp .getRows();
640  unsigned int colMatrixTmp = matrixTmp .getCols();
641 
642  /* Check the matrix L size, and realloc if needed. */
643  while (rowMatrixTmp + cursorL > rowL) {
644  rowL *= 2;
645  L.resize (rowL,colL,false);
646  vpDEBUG_TRACE(15,"Realloc!");
647  }
648 
649  /* Copy the temporarily matrix into L. */
650  for (unsigned int k = 0; k < rowMatrixTmp; ++k, ++cursorL) {
651  for (unsigned int j = 0; j < colMatrixTmp; ++j) {
652  L[cursorL][j] = matrixTmp[k][j];
653  }
654  }
655  }
656 
657  L.resize (cursorL,colL,false);
658 
659  return ;
660 }
661 
662 
670 {
671  try {
672 
673  switch (interactionMatrixType)
674  {
675  case CURRENT:
676  {
677  try
678  {
679  computeInteractionMatrixFromList(this ->featureList,
680  this ->featureSelectionList,
681  L);
682  dim_task = L.getRows() ;
684  }
685 
686  catch(...)
687  {
688  throw ;
689  }
690  }
691  break ;
692  case DESIRED:
693  {
694  try
695  {
697  {
698  computeInteractionMatrixFromList(this ->desiredFeatureList,
699  this ->featureSelectionList, L);
700 
701  dim_task = L.getRows() ;
703  }
704 
705  }
706  catch(...)
707  {
708  throw ;
709  }
710  }
711  break ;
712  case MEAN:
713  {
714  vpMatrix Lstar (L.getRows(), L.getCols());
715  try
716  {
717  computeInteractionMatrixFromList(this ->featureList,
718  this ->featureSelectionList, L);
719  computeInteractionMatrixFromList(this ->desiredFeatureList,
720  this ->featureSelectionList, Lstar);
721  }
722  catch(...)
723  {
724  throw ;
725  }
726  L = (L+Lstar)/2;
727 
728  dim_task = L.getRows() ;
730  }
731  break ;
732  case USER_DEFINED:
733  // dim_task = L.getRows() ;
734  interactionMatrixComputed = false ;
735  break;
736  }
737 
738  }
739  catch(...)
740  {
741  throw ;
742  }
743  return L ;
744 }
745 
755 {
756  if (featureList.empty())
757  {
758  vpERROR_TRACE("feature list empty, cannot compute Ls") ;
760  "feature list empty, cannot compute Ls")) ;
761  }
762  if (desiredFeatureList.empty())
763  {
764  vpERROR_TRACE("feature list empty, cannot compute Ls") ;
766  "feature list empty, cannot compute Ls")) ;
767  }
768 
769  try {
770  vpBasicFeature *current_s ;
771  vpBasicFeature *desired_s ;
772 
773  /* The vector dimensions are not known before the affectation loop.
774  * They thus should be allocated on the flight, in the loop.
775  * The first assumption is that the size has not changed. A double
776  * reallocation (realloc(dim*2)) is done if necessary. In particular,
777  * [log_2(dim)+1] reallocations are done for the first error computation.
778  * If the allocated size is too large, a correction is done after the loop.
779  * The algorithmic cost is linear in affectation, logarithmic in allocation
780  * numbers and linear in allocation size.
781  * No assumptions are made concerning size of each vector: they are
782  * not said equal, and could be different.
783  */
784 
785  /* First assumption: vector dimensions have not changed. If 0, they are
786  * initialized to dim 1.*/
787  unsigned int dimError = error .getRows();
788  unsigned int dimS = s .getRows();
789  unsigned int dimSStar = sStar .getRows();
790  if (0 == dimError) { dimError = 1; error .resize(dimError);}
791  if (0 == dimS) { dimS = 1; s .resize(dimS);}
792  if (0 == dimSStar) { dimSStar = 1; sStar .resize(dimSStar);}
793 
794  /* vectTmp is used to store the return values of functions get_s() and
795  * error(). */
796  vpColVector vectTmp;
797 
798  /* The cursor are the number of the next case of the vector array to
799  * be affected. A memory reallocation should be done when cursor
800  * is out of the vector-array range.*/
801  unsigned int cursorS = 0;
802  unsigned int cursorSStar = 0;
803  unsigned int cursorError = 0;
804 
805  /* For each cell of the list, copy value of s, s_star and error. */
806  std::list<vpBasicFeature *>::const_iterator it_s;
807  std::list<vpBasicFeature *>::const_iterator it_s_star;
808  std::list<unsigned int>::const_iterator it_select;
809 
810  for (it_s = featureList.begin(), it_s_star = desiredFeatureList.begin(), it_select = featureSelectionList.begin();
811  it_s != featureList.end();
812  ++it_s, ++it_s_star, ++it_select)
813  {
814  current_s = (*it_s);
815  desired_s = (*it_s_star);
816  unsigned int select = (*it_select);
817 
818  /* Get s, and store it in the s vector. */
819  vectTmp = current_s->get_s(select);
820  unsigned int dimVectTmp = vectTmp .getRows();
821  while (dimVectTmp + cursorS > dimS)
822  { dimS *= 2; s .resize (dimS,false); vpDEBUG_TRACE(15,"Realloc!"); }
823  for (unsigned int k = 0; k < dimVectTmp; ++k) { s[cursorS++] = vectTmp[k]; }
824 
825  /* Get s_star, and store it in the s vector. */
826  vectTmp = desired_s->get_s(select);
827  dimVectTmp = vectTmp .getRows();
828  while (dimVectTmp + cursorSStar > dimSStar) {
829  dimSStar *= 2;
830  sStar.resize (dimSStar,false);
831  }
832  for (unsigned int k = 0; k < dimVectTmp; ++k) {
833  sStar[cursorSStar++] = vectTmp[k];
834  }
835 
836  /* Get error, and store it in the s vector. */
837  vectTmp = current_s->error(*desired_s, select) ;
838  dimVectTmp = vectTmp .getRows();
839  while (dimVectTmp + cursorError > dimError) {
840  dimError *= 2;
841  error.resize (dimError,false);
842  }
843  for (unsigned int k = 0; k < dimVectTmp; ++k) {
844  error[cursorError++] = vectTmp[k];
845  }
846  }
847 
848  /* If too much memory has been allocated, realloc. */
849  s .resize(cursorS,false);
850  sStar .resize(cursorSStar,false);
851  error .resize(cursorError,false);
852 
853  /* Final modifications. */
854  dim_task = error.getRows() ;
855  errorComputed = true ;
856  }
857  catch(...)
858  {
859  throw ;
860  }
861  return error ;
862 }
863 
865 {
866  switch (servoType)
867  {
868  case NONE:
869  vpERROR_TRACE("No control law have been yet defined") ;
871  "No control law have been yet defined")) ;
872  break ;
873  case EYEINHAND_CAMERA:
874  return true ;
875  break ;
876  case EYEINHAND_L_cVe_eJe:
877  case EYETOHAND_L_cVe_eJe:
878  if (!init_cVe) vpERROR_TRACE("cVe not initialized") ;
879  if (!init_eJe) vpERROR_TRACE("eJe not initialized") ;
880  return (init_cVe && init_eJe) ;
881  break ;
883  if (!init_cVf) vpERROR_TRACE("cVf not initialized") ;
884  if (!init_fVe) vpERROR_TRACE("fVe not initialized") ;
885  if (!init_eJe) vpERROR_TRACE("eJe not initialized") ;
886  return (init_cVf && init_fVe && init_eJe) ;
887  break ;
888 
889  case EYETOHAND_L_cVf_fJe :
890  if (!init_cVf) vpERROR_TRACE("cVf not initialized") ;
891  if (!init_fJe) vpERROR_TRACE("fJe not initialized") ;
892  return (init_cVf && init_fJe) ;
893  break ;
894  }
895 
896  return false ;
897 }
899 {
900  switch (servoType)
901  {
902  case NONE:
903  vpERROR_TRACE("No control law have been yet defined") ;
905  "No control law have been yet defined")) ;
906  break ;
907  case EYEINHAND_CAMERA:
908  return true ;
909  case EYEINHAND_L_cVe_eJe:
910  if (!init_eJe) vpERROR_TRACE("eJe not updated") ;
911  return (init_eJe) ;
912  break ;
913  case EYETOHAND_L_cVe_eJe:
914  if (!init_cVe) vpERROR_TRACE("cVe not updated") ;
915  if (!init_eJe) vpERROR_TRACE("eJe not updated") ;
916  return (init_cVe && init_eJe) ;
917  break ;
919  if (!init_fVe) vpERROR_TRACE("fVe not updated") ;
920  if (!init_eJe) vpERROR_TRACE("eJe not updated") ;
921  return (init_fVe && init_eJe) ;
922  break ;
923 
924  case EYETOHAND_L_cVf_fJe :
925  if (!init_fJe) vpERROR_TRACE("fJe not updated") ;
926  return (init_fJe) ;
927  break ;
928  }
929 
930  return false ;
931 }
955 {
956  static int iteration =0;
957 
958  try
959  {
960  vpVelocityTwistMatrix cVa ; // Twist transformation matrix
961  vpMatrix aJe ; // Jacobian
962 
963  if (iteration==0)
964  {
965  if (testInitialization() == false) {
966  vpERROR_TRACE("All the matrices are not correctly initialized") ;
968  "Cannot compute control law "
969  "All the matrices are not correctly"
970  "initialized")) ;
971  }
972  }
973  if (testUpdated() == false) {
974  vpERROR_TRACE("All the matrices are not correctly updated") ;
975  }
976 
977  // test if all the required initialization have been done
978  switch (servoType)
979  {
980  case NONE :
981  vpERROR_TRACE("No control law have been yet defined") ;
983  "No control law have been yet defined")) ;
984  break ;
985  case EYEINHAND_CAMERA:
986  case EYEINHAND_L_cVe_eJe:
987  case EYETOHAND_L_cVe_eJe:
988 
989  cVa = cVe ;
990  aJe = eJe ;
991 
992  init_cVe = false ;
993  init_eJe = false ;
994  break ;
996  cVa = cVf*fVe ;
997  aJe = eJe ;
998  init_fVe = false ;
999  init_eJe = false ;
1000  break ;
1001  case EYETOHAND_L_cVf_fJe :
1002  cVa = cVf ;
1003  aJe = fJe ;
1004  init_fJe = false ;
1005  break ;
1006  }
1007 
1009  computeError() ;
1010 
1011  // compute task Jacobian
1012  if(iscJcIdentity)
1013  J1 = L*cVa*aJe ;
1014  else
1015  J1 = L*cJc*cVa*aJe ;
1016 
1017  // handle the eye-in-hand eye-to-hand case
1019 
1020  // pseudo inverse of the task Jacobian
1021  // and rank of the task Jacobian
1022  // the image of J1 is also computed to allows the computation
1023  // of the projection operator
1024  vpMatrix imJ1t, imJ1 ;
1025  bool imageComputed = false ;
1026 
1028  {
1029  rankJ1 = J1.pseudoInverse(J1p, sv, 1e-6, imJ1, imJ1t) ;
1030 
1031  imageComputed = true ;
1032  }
1033  else
1034  J1p = J1.t() ;
1035 
1036  if (rankJ1 == J1.getCols())
1037  {
1038  /* if no degrees of freedom remains (rank J1 = ndof)
1039  WpW = I, multiply by WpW is useless
1040  */
1041  e1 = J1p*error ;// primary task
1042 
1043  WpW.eye(J1.getCols(), J1.getCols()) ;
1044  }
1045  else
1046  {
1047  if (imageComputed!=true)
1048  {
1049  vpMatrix Jtmp ;
1050  // image of J1 is computed to allows the computation
1051  // of the projection operator
1052  rankJ1 = J1.pseudoInverse(Jtmp, sv, 1e-6, imJ1, imJ1t) ;
1053  }
1054  WpW = imJ1t*imJ1t.t() ;
1055 
1056 #ifdef DEBUG
1057  std::cout << "rank J1 " << rankJ1 <<std::endl ;
1058  std::cout << "imJ1t"<<std::endl << imJ1t ;
1059  std::cout << "imJ1"<<std::endl << imJ1 ;
1060 
1061  std::cout << "WpW" <<std::endl <<WpW ;
1062  std::cout << "J1" <<std::endl <<J1 ;
1063  std::cout << "J1p" <<std::endl <<J1p ;
1064 #endif
1065  e1 = WpW*J1p*error ;
1066  }
1067  e = - lambda(e1) * e1 ;
1068 
1069  vpMatrix I ;
1070 
1071  I.eye(J1.getCols(),J1.getCols()) ;
1072 
1074 
1075  }
1076  catch(...) {
1077  throw;
1078  }
1079 
1080  iteration++ ;
1081  return e ;
1082 }
1083 
1113 {
1114  static int iteration =0;
1115  //static vpColVector e1_initial;
1116 
1117  try
1118  {
1119  vpVelocityTwistMatrix cVa ; // Twist transformation matrix
1120  vpMatrix aJe ; // Jacobian
1121 
1122  if (iteration==0)
1123  {
1124  if (testInitialization() == false) {
1125  vpERROR_TRACE("All the matrices are not correctly initialized") ;
1127  "Cannot compute control law "
1128  "All the matrices are not correctly"
1129  "initialized")) ;
1130  }
1131  }
1132  if (testUpdated() == false) {
1133  vpERROR_TRACE("All the matrices are not correctly updated") ;
1134  }
1135 
1136  // test if all the required initialization have been done
1137  switch (servoType)
1138  {
1139  case NONE :
1140  vpERROR_TRACE("No control law have been yet defined") ;
1142  "No control law have been yet defined")) ;
1143  break ;
1144  case EYEINHAND_CAMERA:
1145  case EYEINHAND_L_cVe_eJe:
1146  case EYETOHAND_L_cVe_eJe:
1147 
1148  cVa = cVe ;
1149  aJe = eJe ;
1150 
1151  init_cVe = false ;
1152  init_eJe = false ;
1153  break ;
1155  cVa = cVf*fVe ;
1156  aJe = eJe ;
1157  init_fVe = false ;
1158  init_eJe = false ;
1159  break ;
1160  case EYETOHAND_L_cVf_fJe :
1161  cVa = cVf ;
1162  aJe = fJe ;
1163  init_fJe = false ;
1164  break ;
1165  }
1166 
1168  computeError() ;
1169 
1170  // compute task Jacobian
1171  J1 = L*cVa*aJe ;
1172 
1173  // handle the eye-in-hand eye-to-hand case
1175 
1176  // pseudo inverse of the task Jacobian
1177  // and rank of the task Jacobian
1178  // the image of J1 is also computed to allows the computation
1179  // of the projection operator
1180  vpMatrix imJ1t, imJ1 ;
1181  bool imageComputed = false ;
1182 
1184  {
1185  rankJ1 = J1.pseudoInverse(J1p, sv, 1e-6, imJ1, imJ1t) ;
1186 
1187  imageComputed = true ;
1188  }
1189  else
1190  J1p = J1.t() ;
1191 
1192  if (rankJ1 == J1.getCols())
1193  {
1194  /* if no degrees of freedom remains (rank J1 = ndof)
1195  WpW = I, multiply by WpW is useless
1196  */
1197  e1 = J1p*error ;// primary task
1198 
1199  WpW.eye(J1.getCols(), J1.getCols()) ;
1200  }
1201  else
1202  {
1203  if (imageComputed!=true)
1204  {
1205  vpMatrix Jtmp ;
1206  // image of J1 is computed to allows the computation
1207  // of the projection operator
1208  rankJ1 = J1.pseudoInverse(Jtmp, sv, 1e-6, imJ1, imJ1t) ;
1209  }
1210  WpW = imJ1t*imJ1t.t() ;
1211 
1212 #ifdef DEBUG
1213  std::cout << "rank J1 " << rankJ1 <<std::endl ;
1214  std::cout << "imJ1t"<<std::endl << imJ1t ;
1215  std::cout << "imJ1"<<std::endl << imJ1 ;
1216 
1217  std::cout << "WpW" <<std::endl <<WpW ;
1218  std::cout << "J1" <<std::endl <<J1 ;
1219  std::cout << "J1p" <<std::endl <<J1p ;
1220 #endif
1221  e1 = WpW*J1p*error ;
1222  }
1223 
1224  // memorize the initial e1 value if the function is called the first time or if the time given as parameter is equal to 0.
1225  if (iteration==0 || std::fabs(t) < std::numeric_limits<double>::epsilon()) {
1226  e1_initial = e1;
1227  }
1228  // Security check. If size of e1_initial and e1 differ, that means that e1_initial was not set
1229  if (e1_initial.getRows() != e1.getRows())
1230  e1_initial = e1;
1231 
1232  e = - lambda(e1) * e1 + lambda(e1) * e1_initial*exp(-mu*t);
1233 
1234  vpMatrix I ;
1235 
1236  I.eye(J1.getCols(), J1.getCols()) ;
1237 
1239  }
1240  catch(...) {
1241  throw;
1242  }
1243 
1244  iteration++ ;
1245  return e ;
1246 }
1247 
1277 {
1278  static int iteration =0;
1279 
1280  try
1281  {
1282  vpVelocityTwistMatrix cVa ; // Twist transformation matrix
1283  vpMatrix aJe ; // Jacobian
1284 
1285  if (iteration==0)
1286  {
1287  if (testInitialization() == false) {
1288  vpERROR_TRACE("All the matrices are not correctly initialized") ;
1290  "Cannot compute control law "
1291  "All the matrices are not correctly"
1292  "initialized")) ;
1293  }
1294  }
1295  if (testUpdated() == false) {
1296  vpERROR_TRACE("All the matrices are not correctly updated") ;
1297  }
1298 
1299  // test if all the required initialization have been done
1300  switch (servoType)
1301  {
1302  case NONE :
1303  vpERROR_TRACE("No control law have been yet defined") ;
1305  "No control law have been yet defined")) ;
1306  break ;
1307  case EYEINHAND_CAMERA:
1308  case EYEINHAND_L_cVe_eJe:
1309  case EYETOHAND_L_cVe_eJe:
1310 
1311  cVa = cVe ;
1312  aJe = eJe ;
1313 
1314  init_cVe = false ;
1315  init_eJe = false ;
1316  break ;
1318  cVa = cVf*fVe ;
1319  aJe = eJe ;
1320  init_fVe = false ;
1321  init_eJe = false ;
1322  break ;
1323  case EYETOHAND_L_cVf_fJe :
1324  cVa = cVf ;
1325  aJe = fJe ;
1326  init_fJe = false ;
1327  break ;
1328  }
1329 
1331  computeError() ;
1332 
1333  // compute task Jacobian
1334  J1 = L*cVa*aJe ;
1335 
1336  // handle the eye-in-hand eye-to-hand case
1338 
1339  // pseudo inverse of the task Jacobian
1340  // and rank of the task Jacobian
1341  // the image of J1 is also computed to allows the computation
1342  // of the projection operator
1343  vpMatrix imJ1t, imJ1 ;
1344  bool imageComputed = false ;
1345 
1347  {
1348  rankJ1 = J1.pseudoInverse(J1p, sv, 1e-6, imJ1, imJ1t) ;
1349 
1350  imageComputed = true ;
1351  }
1352  else
1353  J1p = J1.t() ;
1354 
1355  if (rankJ1 == J1.getCols())
1356  {
1357  /* if no degrees of freedom remains (rank J1 = ndof)
1358  WpW = I, multiply by WpW is useless
1359  */
1360  e1 = J1p*error ;// primary task
1361 
1362  WpW.eye(J1.getCols(), J1.getCols()) ;
1363  }
1364  else
1365  {
1366  if (imageComputed!=true)
1367  {
1368  vpMatrix Jtmp ;
1369  // image of J1 is computed to allows the computation
1370  // of the projection operator
1371  rankJ1 = J1.pseudoInverse(Jtmp, sv, 1e-6, imJ1, imJ1t) ;
1372  }
1373  WpW = imJ1t*imJ1t.t() ;
1374 
1375 #ifdef DEBUG
1376  std::cout << "rank J1 " << rankJ1 <<std::endl ;
1377  std::cout << "imJ1t"<<std::endl << imJ1t ;
1378  std::cout << "imJ1"<<std::endl << imJ1 ;
1379 
1380  std::cout << "WpW" <<std::endl <<WpW ;
1381  std::cout << "J1" <<std::endl <<J1 ;
1382  std::cout << "J1p" <<std::endl <<J1p ;
1383 #endif
1384  e1 = WpW*J1p*error ;
1385  }
1386 
1387  // memorize the initial e1 value if the function is called the first time or if the time given as parameter is equal to 0.
1388  if (iteration==0 || std::fabs(t) < std::numeric_limits<double>::epsilon()) {
1389  e1_initial = e1;
1390  }
1391  // Security check. If size of e1_initial and e1 differ, that means that e1_initial was not set
1392  if (e1_initial.getRows() != e1.getRows())
1393  e1_initial = e1;
1394 
1395  e = - lambda(e1) * e1 + (e_dot_init + lambda(e1) * e1_initial)*exp(-mu*t);
1396 
1397  vpMatrix I ;
1398 
1399  I.eye(J1.getCols(), J1.getCols()) ;
1400 
1402  }
1403  catch(...) {
1404  throw;
1405  }
1406 
1407  iteration++ ;
1408  return e ;
1409 }
1410 
1412 {
1413  // Initialization
1414  unsigned int n = J1.getCols();
1415  P.resize(n,n);
1416 
1417  vpMatrix I;
1418  I.eye(n);
1419 
1420  //Compute classical projection operator
1421  I_WpW = (I - WpW) ;
1422 
1423  // Compute gain depending by the task error to ensure a smooth change between the operators.
1424  double e0_ = 0.1;
1425  double e1_ = 0.7;
1426  double sig = 0.0;
1427 
1428  double norm_e = error.euclideanNorm() ;
1429  if (norm_e > e1_)
1430  sig = 1.0;
1431  else if (e0_ <= norm_e && norm_e <= e1_ )
1432  sig = 1.0 / (1.0 + exp(-12.0 * ( (norm_e-e0_)/((e1_-e0_))) + 6.0 ) );
1433  else
1434  sig = 0.0;
1435 
1436  vpMatrix J1t = J1.transpose();
1437 
1438  double pp = (error.t() * (J1 * J1t) * error);
1439 
1440  vpMatrix ee_t(n,n);
1441  ee_t = error * error.t();
1442 
1443  vpMatrix P_norm_e(n,n);
1444  P_norm_e = I - (1.0 / pp ) * J1t * ee_t * J1;
1445 
1446  P = sig * P_norm_e + (1 - sig) * I_WpW;
1447 
1448  return;
1449 }
1450 
1513 vpColVector vpServo::secondaryTask(const vpColVector &de2dt, const bool &useLargeProjectionOperator)
1514 {
1515  vpColVector sec ;
1516 
1517  if (!useLargeProjectionOperator)
1518  {
1519  if (rankJ1 == J1.getCols())
1520  {
1521  vpERROR_TRACE("no degree of freedom is free, cannot use secondary task") ;
1523  "no degree of freedom is free, cannot use secondary task")) ;
1524  }
1525  else
1526  {
1527 #if 0
1528  // computed in computeControlLaw()
1529  vpMatrix I ;
1530 
1531  I.resize(J1.getCols(),J1.getCols()) ;
1532  I.setIdentity() ;
1533  I_WpW = (I - WpW) ;
1534 #endif
1535  // std::cout << "I-WpW" << std::endl << I_WpW <<std::endl ;
1536  sec = I_WpW*de2dt ;
1537  }
1538  }
1539 
1540  else
1541  sec = P*de2dt;
1542 
1543  return sec ;
1544 }
1545 
1613 vpColVector vpServo::secondaryTask(const vpColVector &e2, const vpColVector &de2dt, const bool &useLargeProjectionOperator)
1614 {
1615  vpColVector sec ;
1616 
1617  if (!useLargeProjectionOperator)
1618  {
1619  if (rankJ1 == J1.getCols())
1620  {
1621  vpERROR_TRACE("no degree of freedom is free, cannot use secondary task") ;
1623  "no degree of freedom is free, cannot use secondary task")) ;
1624  }
1625  else
1626  {
1627 
1628 #if 0
1629  // computed in computeControlLaw()
1630  vpMatrix I ;
1631 
1632  I.resize(J1.getCols(),J1.getCols()) ;
1633  I.setIdentity() ;
1634 
1635  I_WpW = (I - WpW) ;
1636 #endif
1637 
1638  // To be coherent with the primary task the gain must be the same between
1639  // primary and secondary task.
1640  sec = -lambda(e1) *I_WpW*e2 + I_WpW *de2dt ;
1641 
1642 
1643  }
1644  }
1645  else
1646  sec = -lambda(e1) * P *e2 + P *de2dt ;
1647 
1648 
1649  return sec ;
1650 }
1651 
1685  const vpColVector &qmin, const vpColVector &qmax,
1686  const double &rho, const double &rho1, const double &lambda_tune) const
1687 {
1688  unsigned int const n = J1.getCols();
1689 
1690  if (qmin.size() != n || qmax.size() != n )
1691  {
1692  std::stringstream msg;
1693  msg << "Dimension vector qmin (" << qmin.size() << ") or qmax () does not correspond to the number of jacobian columns";
1694  msg << "qmin size: " << qmin.size() << std::endl;
1696  }
1697  if (q.size() != n || dq.size() != n )
1698  {
1699  vpERROR_TRACE("Dimension vector q or dq does not correspont to the number of jacobian columns") ;
1701  "Dimension vector q or dq does not correspont to the number of jacobian columns")) ;
1702  }
1703 
1704  double lambda_l = 0.0;
1705 
1706  vpColVector q2 (n);
1707 
1708  vpColVector q_l0_min(n);
1709  vpColVector q_l0_max(n);
1710  vpColVector q_l1_min(n);
1711  vpColVector q_l1_max(n);
1712 
1713  // Computation of gi ([nx1] vector) and lambda_l ([nx1] vector)
1714  vpMatrix g(n,n);
1715  vpColVector q2_i(n);
1716 
1717  for(unsigned int i = 0; i < n; i++)
1718  {
1719  q_l0_min[i] = qmin[i] + rho *(qmax[i] - qmin[i]);
1720  q_l0_max[i] = qmax[i] - rho *(qmax[i] - qmin[i]);
1721 
1722  q_l1_min[i] = q_l0_min[i] - rho * rho1 * (qmax[i] - qmin[i]);
1723  q_l1_max[i] = q_l0_max[i] + rho * rho1 * (qmax[i] - qmin[i]);
1724 
1725  if (q[i] < q_l0_min[i] )
1726  g[i][i] = -1;
1727  else if (q[i] > q_l0_max[i] )
1728  g[i][i] = 1;
1729  else
1730  g[i][i]= 0;
1731  }
1732 
1733  for(unsigned int i = 0; i < n; i++)
1734  {
1735  if (q[i] > q_l0_min[i] && q[i] < q_l0_max[i])
1736  q2_i = 0 * q2_i;
1737 
1738  else
1739  {
1740  vpColVector Pg_i(n);
1741  Pg_i = (P * g.getCol(i));
1742  double b = ( vpMath::abs(dq[i]) )/( vpMath::abs( Pg_i[i] ) );
1743 
1744  if (b < 1.) // If the ratio b is big we don't activate the joint avoidance limit for the joint.
1745  {
1746  if (q[i] < q_l1_min[i] || q[i] > q_l1_max[i] )
1747  q2_i = - (1 + lambda_tune) * b * Pg_i;
1748 
1749  else
1750  {
1751  if (q[i] >= q_l0_max[i] && q[i] <= q_l1_max[i] )
1752  lambda_l = 1 / (1 + exp(-12 *( (q[i] - q_l0_max[i]) / (q_l1_max[i] - q_l0_max[i]) ) + 6 ) );
1753 
1754  else if (q[i] >= q_l1_min[i] && q[i] <= q_l0_min[i])
1755  lambda_l = 1 / (1 + exp(-12 *( (q[i] - q_l0_min[i]) / (q_l1_min[i] - q_l0_min[i]) ) + 6 ) );
1756 
1757  q2_i = - lambda_l * (1 + lambda_tune)* b * Pg_i;
1758  }
1759  }
1760  }
1761  q2 = q2 + q2_i;
1762  }
1763  return q2;
1764 }
1765 
1779 {
1780  return I_WpW;
1781 }
1782 
1783 
1797 {
1798  return P;
1799 }
1800 
1801 
1815 {
1816  return J1;
1817 }
1836 {
1837  return J1p;
1838 }
1849 unsigned int vpServo::getTaskRank() const
1850 {
1851  return rankJ1;
1852 }
1853 
1870 {
1871  return WpW;
1872 }
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:97
unsigned int getDimension() const
Return the task dimension.
Definition: vpServo.cpp:571
vpServoType servoType
Chosen visual servoing control law.
Definition: vpServo.h:514
void setDeallocate(vpBasicFeatureDeallocatorType d)
bool interactionMatrixComputed
true if the interaction matrix has been computed.
Definition: vpServo.h:572
bool taskWasKilled
Flag to indicate if the task was killed.
Definition: vpServo.h:576
void resize(const unsigned int nrows, const unsigned int ncols, const bool flagNullify=true)
Definition: vpArray2D.h:167
vpMatrix getTaskJacobian() const
Definition: vpServo.cpp:1814
unsigned int rankJ1
Rank of the task Jacobian.
Definition: vpServo.h:517
vpVelocityTwistMatrix cVf
Twist transformation matrix between Rf and Rc.
Definition: vpServo.h:548
double euclideanNorm() const
bool init_cVf
Definition: vpServo.h:549
vpVelocityTwistMatrix fVe
Twist transformation matrix between Re and Rf.
Definition: vpServo.h:551
vpColVector sv
Singular values from the pseudo inverse.
Definition: vpServo.h:603
vpServoType
Definition: vpServo.h:157
#define vpERROR_TRACE
Definition: vpDebug.h:391
vpColVector e1
Primary task .
Definition: vpServo.h:504
bool init_cVe
Definition: vpServo.h:546
void set_eJe(const vpMatrix &eJe_)
Definition: vpServo.h:460
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:512
vpServoInversionType
Definition: vpServo.h:195
vpMatrix fJe
Jacobian expressed in the robot reference frame.
Definition: vpServo.h:562
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:1778
unsigned int dim_task
Dimension of the task updated during computeControlLaw().
Definition: vpServo.h:574
vpServoInversionType inversionType
Definition: vpServo.h:537
static Type abs(const Type &x)
Definition: vpMath.h:161
vpColVector secondaryTask(const vpColVector &de2dt, const bool &useLargeProjectionOperator=false)
Definition: vpServo.cpp:1513
class that defines what is a visual feature
double mu
Definition: vpServo.h:605
vpMatrix computeInteractionMatrix()
Definition: vpServo.cpp:669
std::list< unsigned int > featureSelectionList
Definition: vpServo.h:525
void kill()
Definition: vpServo.cpp:191
vp_deprecated void setIdentity(const double &val=1.0)
Definition: vpMatrix.cpp:3667
bool iscJcIdentity
Boolean to know if cJc is identity (for fast computation)
Definition: vpServo.h:610
bool testInitialization()
Definition: vpServo.cpp:864
vpColVector computeError()
Definition: vpServo.cpp:754
int signInteractionMatrix
Definition: vpServo.h:532
vpColVector computeControlLaw()
Definition: vpServo.cpp:954
#define vpTRACE
Definition: vpDebug.h:414
vpMatrix J1
Task Jacobian .
Definition: vpServo.h:492
void setCameraDoF(const vpColVector &dof)
Definition: vpServo.cpp:287
vpMatrix L
Interaction matrix.
Definition: vpServo.h:486
vpRowVector t() const
bool init_fVe
Definition: vpServo.h:552
vpColVector getCol(const unsigned int j) const
Definition: vpMatrix.cpp:2235
bool forceInteractionMatrixComputation
Force the interaction matrix computation even if it is already done.
Definition: vpServo.h:578
vpMatrix transpose() const
Definition: vpMatrix.cpp:233
vpAdaptiveGain lambda
Gain used in the control law.
Definition: vpServo.h:528
vpVelocityTwistMatrix cVe
Twist transformation matrix between Re and Rc.
Definition: vpServo.h:545
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:498
vpServoIteractionMatrixType
Definition: vpServo.h:183
virtual void init()=0
vpServo()
Definition: vpServo.cpp:68
vpColVector e1_initial
Definition: vpServo.h:607
void setInteractionMatrixType(const vpServoIteractionMatrixType &interactionMatrixType, const vpServoInversionType &interactionMatrixInversion=PSEUDO_INVERSE)
Definition: vpServo.cpp:585
vpMatrix cJc
A diag matrix used to determine which are the degrees of freedom that are controlled in the camera fr...
Definition: vpServo.h:613
vpColVector e
Task .
Definition: vpServo.h:506
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:1684
vpMatrix getTaskJacobianPseudoInverse() const
Definition: vpServo.cpp:1835
vpMatrix P
Definition: vpServo.h:600
vpMatrix t() const
Definition: vpMatrix.cpp:207
void computeProjectionOperators()
Definition: vpServo.cpp:1411
std::list< vpBasicFeature * > desiredFeatureList
List of desired visual features .
Definition: vpServo.h:522
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
virtual ~vpServo()
Definition: vpServo.cpp:116
void set_cVe(const vpVelocityTwistMatrix &cVe_)
Definition: vpServo.h:435
bool init_fJe
Definition: vpServo.h:563
vpMatrix getLargeP() const
Definition: vpServo.cpp:1796
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:314
vpMatrix I_WpW
Projection operators .
Definition: vpServo.h:583
vpColVector sStar
Definition: vpServo.h:501
#define vpDEBUG_TRACE
Definition: vpDebug.h:478
bool testUpdated()
Definition: vpServo.cpp:898
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.
Definition: vpMatrix.cpp:1741
virtual vpBasicFeature * duplicate() const =0
bool errorComputed
true if the error has been computed.
Definition: vpServo.h:570
vpMatrix WpW
Projection operators .
Definition: vpServo.h:581
bool init_eJe
Definition: vpServo.h:560
vpMatrix J1p
Pseudo inverse of the task Jacobian.
Definition: vpServo.h:494
vpMatrix getWpW() const
Definition: vpServo.cpp:1869
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:520
void setServo(const vpServoType &servo_type)
Definition: vpServo.cpp:222
vpServoPrintType
Definition: vpServo.h:201
vpColVector error
Definition: vpServo.h:490
void init()
Basic initialization.
Definition: vpServo.cpp:141
void eye()
Definition: vpMatrix.cpp:194
unsigned int getTaskRank() const
Definition: vpServo.cpp:1849
vpServoIteractionMatrixType interactionMatrixType
Type of the interaction matrox (current, mean, desired, user)
Definition: vpServo.h:534
vpMatrix eJe
Jacobian expressed in the end-effector frame.
Definition: vpServo.h:559
Current or desired feature list is empty.
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:225