ViSP  2.6.2
vpRobotAfma4.cpp
1 /****************************************************************************
2  *
3  * $Id: vpRobotAfma4.cpp 3808 2012-06-25 16:37:59Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2012 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  * Interface for the Irisa's Afma4 robot.
36  *
37  * Authors:
38  * Fabien Spindler
39  *
40  *****************************************************************************/
41 
42 #include <visp/vpConfig.h>
43 
44 #ifdef VISP_HAVE_AFMA4
45 
46 #include <signal.h>
47 #include <stdlib.h>
48 
49 #include <visp/vpRobotException.h>
50 #include <visp/vpExponentialMap.h>
51 #include <visp/vpDebug.h>
52 #include <visp/vpVelocityTwistMatrix.h>
53 #include <visp/vpThetaUVector.h>
54 #include <visp/vpRobotAfma4.h>
55 
56 /* ---------------------------------------------------------------------- */
57 /* --- STATIC ----------------------------------------------------------- */
58 /* ---------------------------------------------------------------------- */
59 
60 bool vpRobotAfma4::robotAlreadyCreated = false;
61 
70 
71 
72 /* ---------------------------------------------------------------------- */
73 /* --- EMERGENCY STOP --------------------------------------------------- */
74 /* ---------------------------------------------------------------------- */
75 
83 void emergencyStopAfma4(int signo)
84 {
85  std::cout << "Stop the Afma4 application by signal ("
86  << signo << "): " << (char)7 ;
87  switch(signo)
88  {
89  case SIGINT:
90  std::cout << "SIGINT (stop by ^C) " << std::endl ; break ;
91  case SIGBUS:
92  std::cout <<"SIGBUS (stop due to a bus error) " << std::endl ; break ;
93  case SIGSEGV:
94  std::cout <<"SIGSEGV (stop due to a segmentation fault) " << std::endl ; break ;
95  case SIGKILL:
96  std::cout <<"SIGKILL (stop by CTRL \\) " << std::endl ; break ;
97  case SIGQUIT:
98  std::cout <<"SIGQUIT " << std::endl ; break ;
99  default :
100  std::cout << signo << std::endl ;
101  }
102  // std::cout << "Emergency stop called\n";
103  // PrimitiveESTOP_Afma4();
104  PrimitiveSTOP_Afma4();
105  std::cout << "Robot was stopped\n";
106 
107  // Free allocated ressources
108  // ShutDownConnection(); // Some times cannot exit here when Ctrl-C
109 
110  fprintf(stdout, "Application ");
111  fflush(stdout);
112  kill(getpid(), SIGKILL);
113  exit(1) ;
114 }
115 
116 
117 /* ---------------------------------------------------------------------- */
118 /* --- CONSTRUCTOR ------------------------------------------------------ */
119 /* ---------------------------------------------------------------------- */
120 
133  :
134  vpAfma4 (),
135  vpRobot ()
136 {
137 
138  /*
139  #define SIGHUP 1 // hangup
140  #define SIGINT 2 // interrupt (rubout)
141  #define SIGQUIT 3 // quit (ASCII FS)
142  #define SIGILL 4 // illegal instruction (not reset when caught)
143  #define SIGTRAP 5 // trace trap (not reset when caught)
144  #define SIGIOT 6 // IOT instruction
145  #define SIGABRT 6 // used by abort, replace SIGIOT in the future
146  #define SIGEMT 7 // EMT instruction
147  #define SIGFPE 8 // floating point exception
148  #define SIGKILL 9 // kill (cannot be caught or ignored)
149  #define SIGBUS 10 // bus error
150  #define SIGSEGV 11 // segmentation violation
151  #define SIGSYS 12 // bad argument to system call
152  #define SIGPIPE 13 // write on a pipe with no one to read it
153  #define SIGALRM 14 // alarm clock
154  #define SIGTERM 15 // software termination signal from kill
155  */
156 
157  signal(SIGINT, emergencyStopAfma4);
158  signal(SIGBUS, emergencyStopAfma4) ;
159  signal(SIGSEGV, emergencyStopAfma4) ;
160  signal(SIGKILL, emergencyStopAfma4);
161  signal(SIGQUIT, emergencyStopAfma4);
162 
163  std::cout << "Open communication with MotionBlox.\n";
164  try {
165  this->init();
167  }
168  catch(...) {
169  // vpERROR_TRACE("Error caught") ;
170  throw ;
171  }
172  positioningVelocity = defaultPositioningVelocity ;
173 
174  vpRobotAfma4::robotAlreadyCreated = true;
175 
176  return ;
177 }
178 
179 
180 /* ------------------------------------------------------------------------ */
181 /* --- INITIALISATION ----------------------------------------------------- */
182 /* ------------------------------------------------------------------------ */
183 
192 void
194 {
195  int stt;
196  InitTry;
197 
198  // Initialise private variables used to compute the measured velocities
199  q_prev_getvel.resize(4);
200  q_prev_getvel = 0;
201  time_prev_getvel = 0;
202  first_time_getvel = true;
203 
204  // Initialise private variables used to compute the measured displacement
205  q_prev_getdis.resize(4);
206  q_prev_getdis = 0;
207  first_time_getdis = true;
208 
209  // Initialize the firewire connection
210  Try( stt = InitializeConnection() );
211 
212  if (stt != SUCCESS) {
213  vpERROR_TRACE ("Cannot open connexion with the motionblox.");
215  "Cannot open connexion with the motionblox");
216  }
217 
218  // Connect to the servoboard using the servo board GUID
219  Try( stt = InitializeNode_Afma4() );
220 
221  if (stt != SUCCESS) {
222  vpERROR_TRACE ("Cannot open connexion with the motionblox.");
224  "Cannot open connexion with the motionblox");
225  }
226  Try( PrimitiveRESET_Afma4() );
227 
228  // Look if the power is on or off
229  UInt32 HIPowerStatus;
230  UInt32 EStopStatus;
231  Try( PrimitiveSTATUS_Afma4(NULL, NULL, &EStopStatus, NULL, NULL, NULL,
232  &HIPowerStatus));
233  CAL_Wait(0.1);
234 
235  // Print the robot status
236  std::cout << "Robot status: ";
237  switch(EStopStatus) {
238  case ESTOP_AUTO:
239  case ESTOP_MANUAL:
240  if (HIPowerStatus == 0)
241  std::cout << "Power is OFF" << std::endl;
242  else
243  std::cout << "Power is ON" << std::endl;
244  break;
245  case ESTOP_ACTIVATED:
246  std::cout << "Emergency stop is activated" << std::endl;
247  break;
248  default:
249  std::cout << "Sorry there is an error on the emergency chain." << std::endl;
250  std::cout << "You have to call Adept for maintenance..." << std::endl;
251  // Free allocated ressources
252  }
253  std::cout << std::endl;
254 
255  // get real joint min/max from the MotionBlox
256  Try( PrimitiveJOINT_MINMAX_Afma4(_joint_min, _joint_max) );
257 // for (unsigned int i=0; i < njoint; i++) {
258 // printf("axis %d: joint min %lf, max %lf\n", i, _joint_min[i], _joint_max[i]);
259 // }
260 
261  // If an error occur in the low level controller, goto here
262  // CatchPrint();
263  Catch();
264 
265  // Test if an error occurs
266  if (TryStt == -20001)
267  printf("No connection detected. Check if the robot is powered on \n"
268  "and if the firewire link exist between the MotionBlox and this computer.\n");
269  else if (TryStt == -675)
270  printf(" Timeout enabling power...\n");
271 
272  if (TryStt < 0) {
273  // Power off the robot
274  PrimitivePOWEROFF_Afma4();
275  // Free allocated ressources
276  ShutDownConnection();
277 
278  std::cout << "Cannot open connexion with the motionblox..." << std::endl;
280  "Cannot open connexion with the motionblox");
281  }
282  return ;
283 }
284 
285 
286 /* ------------------------------------------------------------------------ */
287 /* --- DESTRUCTOR --------------------------------------------------------- */
288 /* ------------------------------------------------------------------------ */
289 
297 {
298  InitTry;
299 
301 
302  // Look if the power is on or off
303  UInt32 HIPowerStatus;
304  Try( PrimitiveSTATUS_Afma4(NULL, NULL, NULL, NULL, NULL, NULL,
305  &HIPowerStatus));
306  CAL_Wait(0.1);
307 
308 // if (HIPowerStatus == 1) {
309 // fprintf(stdout, "Power OFF the robot\n");
310 // fflush(stdout);
311 
312 // Try( PrimitivePOWEROFF_Afma4() );
313 // }
314 
315  // Free allocated ressources
316  ShutDownConnection();
317 
318  vpRobotAfma4::robotAlreadyCreated = false;
319 
320  CatchPrint();
321  return;
322 }
323 
324 
325 
326 
327 
336 {
337  InitTry;
338 
339  switch (newState) {
340  case vpRobot::STATE_STOP: {
342  Try( PrimitiveSTOP_Afma4() );
343  }
344  break;
345  }
348  std::cout << "Change the control mode from velocity to position control.\n";
349  Try( PrimitiveSTOP_Afma4() );
350  }
351  else {
352  //std::cout << "Change the control mode from stop to position control.\n";
353  }
354  this->powerOn();
355  break;
356  }
359  std::cout << "Change the control mode from stop to velocity control.\n";
360  }
361  this->powerOn();
362  break;
363  }
364  default:
365  break ;
366  }
367 
368  CatchPrint();
369 
370  return vpRobot::setRobotState (newState);
371 }
372 
373 /* ------------------------------------------------------------------------ */
374 /* --- STOP --------------------------------------------------------------- */
375 /* ------------------------------------------------------------------------ */
376 
384 void
386 {
387  InitTry;
388  Try( PrimitiveSTOP_Afma4() );
390 
391  CatchPrint();
392  if (TryStt < 0) {
393  vpERROR_TRACE ("Cannot stop robot motion");
395  "Cannot stop robot motion.");
396  }
397 }
398 
399 
409 void
411 {
412  InitTry;
413 
414  // Look if the power is on or off
415  UInt32 HIPowerStatus;
416  UInt32 EStopStatus;
417  bool firsttime = true;
418  int nitermax = 10;
419 
420  for (int i=0; i<nitermax; i++) {
421  Try( PrimitiveSTATUS_Afma4(NULL, NULL, &EStopStatus, NULL, NULL, NULL,
422  &HIPowerStatus));
423  switch(EStopStatus) {
424  case ESTOP_AUTO: break;
425  case ESTOP_MANUAL: break;
426  case ESTOP_ACTIVATED:
427  if (firsttime) {
428  std::cout << "Emergency stop is activated! \n"
429  << "Check the emergency stop button and push the yellow button before continuing." << std::endl;
430  firsttime = false;
431  }
432  fprintf(stdout, "Remaining time %ds \r", nitermax-i);
433  fflush(stdout);
434  CAL_Wait(1);
435  break;
436  default:
437  std::cout << "Sorry there is an error on the emergency chain." << std::endl;
438  std::cout << "You have to call Adept for maintenance..." << std::endl;
439  // Free allocated ressources
440  ShutDownConnection();
441  exit(0);
442  }
443  }
444 
445  std::cout << std::endl;
446 
447  if (EStopStatus == ESTOP_ACTIVATED) {
448  std::cout << "Sorry, cannot power on the robot." << std::endl;
450  "Cannot power on the robot.");
451  }
452 
453  if (HIPowerStatus == 0) {
454  fprintf(stdout, "Power ON the Afma4 robot\n");
455  fflush(stdout);
456 
457  Try( PrimitivePOWERON_Afma4() );
458  }
459 
460  CatchPrint();
461  if (TryStt < 0) {
462  vpERROR_TRACE ("Cannot power on the robot");
464  "Cannot power off the robot.");
465  }
466 }
467 
477 void
479 {
480  InitTry;
481 
482  // Look if the power is on or off
483  UInt32 HIPowerStatus;
484  Try( PrimitiveSTATUS_Afma4(NULL, NULL, NULL, NULL, NULL, NULL,
485  &HIPowerStatus));
486  CAL_Wait(0.1);
487 
488  if (HIPowerStatus == 1) {
489  fprintf(stdout, "Power OFF the Afma4 robot\n");
490  fflush(stdout);
491 
492  Try( PrimitivePOWEROFF_Afma4() );
493  }
494 
495  CatchPrint();
496  if (TryStt < 0) {
497  vpERROR_TRACE ("Cannot power off the robot");
499  "Cannot power off the robot.");
500  }
501 }
502 
514 bool
516 {
517  InitTry;
518  bool status = false;
519  // Look if the power is on or off
520  UInt32 HIPowerStatus;
521  Try( PrimitiveSTATUS_Afma4(NULL, NULL, NULL, NULL, NULL, NULL,
522  &HIPowerStatus));
523  CAL_Wait(0.1);
524 
525  if (HIPowerStatus == 1) {
526  status = true;
527  }
528 
529  CatchPrint();
530  if (TryStt < 0) {
531  vpERROR_TRACE ("Cannot get the power status");
533  "Cannot get the power status.");
534  }
535  return status;
536 }
537 
547 void
549 {
550  vpHomogeneousMatrix cMe ;
551  vpAfma4::get_cMe(cMe) ;
552 
553  cVe.buildFrom(cMe) ;
554 }
555 
565 void
567 {
568  double position[this->njoint];
569 
570  InitTry;
571  Try( PrimitiveACQ_POS_Afma4(position) );
572  CatchPrint();
573 
574  vpColVector q(this->njoint);
575  for (unsigned int i=0; i < njoint; i++)
576  q[i] = position[i];
577 
578  try {
579  vpAfma4::get_cVf(q, cVf) ;
580  }
581  catch(...) {
582  vpERROR_TRACE("catch exception ") ;
583  throw ;
584  }}
585 
596 void
598 {
599  vpAfma4::get_cMe(cMe) ;
600 }
601 
614 void
616 {
617 
618  double position[this->njoint];
619 
620  InitTry;
621  Try( PrimitiveACQ_POS_Afma4(position) );
622  CatchPrint();
623 
624  vpColVector q(this->njoint);
625  for (unsigned int i=0; i < njoint; i++)
626  q[i] = position[i];
627 
628  try {
629  vpAfma4::get_eJe(q, eJe) ;
630  }
631  catch(...) {
632  vpERROR_TRACE("catch exception ") ;
633  throw ;
634  }
635 }
636 
651  void
653 {
654 
655  double position[6];
656 
657  InitTry;
658  Try( PrimitiveACQ_POS_Afma4(position) );
659  CatchPrint();
660 
661  vpColVector q(6);
662  for (unsigned int i=0; i < njoint; i++)
663  q[i] = position[i];
664 
665  try {
666  vpAfma4::get_fJe(q, fJe) ;
667  }
668  catch(...) {
669  vpERROR_TRACE("Error caught");
670  throw ;
671  }
672 }
701 void
703 {
704  positioningVelocity = velocity;
705 }
706 
712 double
714 {
715  return positioningVelocity;
716 }
717 
718 
790 void
792  const vpColVector & position )
793 {
794 
796  vpERROR_TRACE ("Robot was not in position-based control\n"
797  "Modification of the robot state");
799  }
800 
801  int error = 0;
802 
803  switch(frame) {
805  vpERROR_TRACE ("Positionning error. Reference frame not implemented");
807  "Positionning error: "
808  "Reference frame not implemented.");
809  break ;
810  case vpRobot::CAMERA_FRAME :
811  vpERROR_TRACE ("Positionning error. Camera frame not implemented");
813  "Positionning error: "
814  "Camera frame not implemented.");
815  break ;
816  case vpRobot::MIXT_FRAME:
817  vpERROR_TRACE ("Positionning error. Mixt frame not implemented");
819  "Positionning error: "
820  "Mixt frame not implemented.");
821  break ;
822 
824  break ;
825 
826  }
827  }
828  if (position.getRows() != this->njoint) {
829  vpERROR_TRACE ("Positionning error: bad vector dimension.");
831  "Positionning error: bad vector dimension.");
832  }
833 
834  InitTry;
835 
836  Try( PrimitiveMOVE_Afma4(position.data, positioningVelocity) );
837  Try( WaitState_Afma4(ETAT_ATTENTE_AFMA4, 1000) );
838 
839  CatchPrint();
840  if (TryStt == InvalidPosition || TryStt == -1023)
841  std::cout << " : Position out of range.\n";
842  else if (TryStt < 0)
843  std::cout << " : Unknown error (see Fabien).\n";
844  else if (error == -1)
845  std::cout << "Position out of range.\n";
846 
847  if (TryStt < 0 || error < 0) {
848  vpERROR_TRACE ("Positionning error.");
850  "Position out of range.");
851  }
852 
853  return ;
854 }
855 
856 
908  const double q1,
909  const double q2,
910  const double q4,
911  const double q5)
912 {
913  try {
914  vpColVector position(this->njoint) ;
915  position[0] = q1 ;
916  position[1] = q2 ;
917  position[2] = q4 ;
918  position[3] = q5 ;
919 
920  setPosition(frame, position) ;
921  }
922  catch(...) {
923  vpERROR_TRACE("Error caught");
924  throw ;
925  }
926 }
927 
928 
929 
930 
960 void vpRobotAfma4::setPosition(const char *filename)
961 {
962  vpColVector q;
963  bool ret;
964 
965  ret = this->readPosFile(filename, q);
966 
967  if (ret == false) {
968  vpERROR_TRACE ("Bad position in \"%s\"", filename);
970  "Bad position in filename.");
971  }
974 }
975 
1033 void
1035  vpColVector & position)
1036 {
1037 
1038  InitTry;
1039 
1040  position.resize (this->njoint);
1041 
1042  switch (frame) {
1043  case vpRobot::CAMERA_FRAME : {
1044  position = 0;
1045  return;
1046  }
1047  case vpRobot::ARTICULAR_FRAME : {
1048  double _q[njoint];
1049  Try( PrimitiveACQ_POS_Afma4(_q) );
1050  for (unsigned int i=0; i < this->njoint; i ++) {
1051  position[i] = _q[i];
1052  }
1053 
1054  return;
1055  }
1056  case vpRobot::REFERENCE_FRAME : {
1057  double _q[njoint];
1058  Try( PrimitiveACQ_POS_Afma4(_q) );
1059 
1060  vpColVector q(this->njoint);
1061  for (unsigned int i=0; i < this->njoint; i++)
1062  q[i] = _q[i];
1063 
1064  // Compute fMc
1065  vpHomogeneousMatrix fMc;
1066  vpAfma4::get_fMc(q, fMc);
1067 
1068  // From fMc extract the pose
1069  vpRotationMatrix fRc;
1070  fMc.extract(fRc);
1071  vpRxyzVector rxyz;
1072  rxyz.buildFrom(fRc);
1073 
1074  for (unsigned int i=0; i < 3; i++) {
1075  position[i] = fMc[i][3]; // translation x,y,z
1076  position[i+3] = rxyz[i]; // Euler rotation x,y,z
1077  }
1078  break ;
1079  }
1080  case vpRobot::MIXT_FRAME: {
1081  vpERROR_TRACE ("Cannot get position in mixt frame: not implemented");
1083  "Cannot get position in mixt frame: "
1084  "not implemented");
1085  break ;
1086  }
1087  }
1088 
1089  CatchPrint();
1090  if (TryStt < 0) {
1091  vpERROR_TRACE ("Cannot get position.");
1093  "Cannot get position.");
1094  }
1095 
1096  return;
1097 }
1098 
1145 void
1147  const vpColVector & vel)
1148 {
1149 
1151  {
1152  vpERROR_TRACE ("Cannot send a velocity to the robot "
1153  "use setRobotState(vpRobot::STATE_VELOCITY_CONTROL) first) ");
1155  "Cannot send a velocity to the robot "
1156  "use setRobotState(vpRobot::STATE_VELOCITY_CONTROL) first) ");
1157  }
1158 
1159  // Check the dimension of the velocity vector to see if it is
1160  // compatible with the requested frame
1161  switch(frame) {
1162  case vpRobot::CAMERA_FRAME : {
1163  //if (vel.getRows() != 2) {
1164  if (vel.getRows() != 6) {
1165  vpERROR_TRACE ("Bad dimension of the velocity vector in camera frame");
1167  "Bad dimension of the velocity vector "
1168  "in camera frame");
1169  }
1170  break ;
1171  }
1172  case vpRobot::ARTICULAR_FRAME : {
1173  if (vel.getRows() != this->njoint) {
1174  vpERROR_TRACE ("Bad dimension of the articular velocity vector");
1176  "Bad dimension of the articular "
1177  "velocity vector ");
1178  }
1179  break ;
1180  }
1181  case vpRobot::REFERENCE_FRAME : {
1182  vpERROR_TRACE ("Cannot send a velocity to the robot "
1183  "in the reference frame: "
1184  "functionality not implemented");
1186  "Cannot send a velocity to the robot "
1187  "in the reference frame:"
1188  "functionality not implemented");
1189  break ;
1190  }
1191  case vpRobot::MIXT_FRAME : {
1192  vpERROR_TRACE ("Cannot send a velocity to the robot "
1193  "in the mixt frame: "
1194  "functionality not implemented");
1196  "Cannot send a velocity to the robot "
1197  "in the mixt frame:"
1198  "functionality not implemented");
1199  break ;
1200  }
1201  default: {
1202  vpERROR_TRACE ("Error in spec of vpRobot. "
1203  "Case not taken in account.");
1205  "Cannot send a velocity to the robot ");
1206  }
1207  }
1208 
1209 
1210  //
1211  // Velocities saturation with normalization
1212  //
1213  vpColVector joint_vel(this->njoint);
1214 
1215  // Case of the camera frame where we control only 2 dof
1216  if (frame == vpRobot::CAMERA_FRAME) {
1217  vpColVector vel_max(6);
1218 
1219  for (int i=0; i<3; i++) {
1220  vel_max[i] = getMaxTranslationVelocity();
1221  vel_max[i+3] = getMaxRotationVelocity();
1222  }
1223 
1224  vpColVector velocity = vpRobot::saturateVelocities(vel, vel_max, true);
1225 
1226 #if 0 // ok
1227  vpMatrix eJe(4,6);
1228  eJe = 0;
1229  eJe[2][4] = -1;
1230  eJe[3][3] = 1;
1231 
1232  joint_vel = eJe * velocity; // Compute the articular velocity
1233 #endif
1234  vpColVector q;
1236  vpMatrix fJe_inverse;
1237  get_fJe_inverse(q, fJe_inverse);
1238  vpHomogeneousMatrix fMe;
1239  get_fMe(q, fMe);
1241  t=0;
1242  vpRotationMatrix fRe;
1243  fMe.extract(fRe);
1244  vpVelocityTwistMatrix fVe(t, fRe);
1245  // compute the inverse jacobian in the end-effector frame
1246  vpMatrix eJe_inverse = fJe_inverse * fVe;
1247 
1248  // Transform the velocities from camera to end-effector frame
1250  eVc.buildFrom(this->_eMc);
1251  joint_vel = eJe_inverse * eVc * velocity;
1252 
1253  // printf("Vitesse art: %f %f %f %f\n", joint_vel[0], joint_vel[1],
1254  // joint_vel[2], joint_vel[3]);
1255  }
1256 
1257  // Case of the joint control where we control all the joints
1258  else if (frame == vpRobot::ARTICULAR_FRAME) {
1259 
1260  vpColVector vel_max(4);
1261 
1262  vel_max[0] = getMaxRotationVelocity();
1263  vel_max[1] = getMaxTranslationVelocity();
1264  vel_max[2] = getMaxRotationVelocity();
1265  vel_max[3] = getMaxRotationVelocity();
1266 
1267  joint_vel = vpRobot::saturateVelocities(vel, vel_max, true);
1268  }
1269 
1270  InitTry;
1271 
1272  // Send a joint velocity to the low level controller
1273  Try( PrimitiveMOVESPEED_Afma4(joint_vel.data) );
1274 
1275  Catch();
1276  if (TryStt < 0) {
1277  if (TryStt == VelStopOnJoint) {
1278  UInt32 axisInJoint[njoint];
1279  PrimitiveSTATUS_Afma4(NULL, NULL, NULL, NULL, NULL, axisInJoint, NULL);
1280  for (unsigned int i=0; i < njoint; i ++) {
1281  if (axisInJoint[i])
1282  std::cout << "\nWarning: Velocity control stopped: axis "
1283  << i+1 << " on joint limit!" <<std::endl;
1284  }
1285  }
1286  else {
1287  printf("\n%s(%d): Error %d", __FUNCTION__, TryLine, TryStt);
1288  if (TryString != NULL) {
1289  // The statement is in TryString, but we need to check the validity
1290  printf(" Error sentence %s\n", TryString); // Print the TryString
1291  }
1292  else {
1293  printf("\n");
1294  }
1295  }
1296  }
1297 
1298  return;
1299 }
1300 
1301 /* ------------------------------------------------------------------------ */
1302 /* --- GET ---------------------------------------------------------------- */
1303 /* ------------------------------------------------------------------------ */
1304 
1305 
1350 void
1352  vpColVector & velocity)
1353 {
1354 
1355  switch (frame) {
1357  velocity.resize (this->njoint);
1358  default:
1359  velocity.resize (6);
1360  }
1361 
1362  velocity = 0;
1363 
1364 
1365  double q[4];
1366  vpColVector q_cur(4);
1367  vpHomogeneousMatrix fMc_cur;
1368  vpHomogeneousMatrix cMc; // camera displacement
1369 
1370 
1371  InitTry;
1372 
1373  // Get the actual time
1374  double time_cur = vpTime::measureTimeSecond();
1375 
1376  // Get the current joint position
1377  Try( PrimitiveACQ_POS_Afma4(q) );
1378  for (unsigned int i=0; i < this->njoint; i ++) {
1379  q_cur[i] = q[i];
1380  }
1381 
1382  // Get the camera pose from the direct kinematics
1383  vpAfma4::get_fMc(q_cur, fMc_cur);
1384 
1385  if ( ! first_time_getvel ) {
1386 
1387  switch (frame) {
1388  case vpRobot::CAMERA_FRAME: {
1389  // Compute the displacement of the camera since the previous call
1390  cMc = fMc_prev_getvel.inverse() * fMc_cur;
1391 
1392  // Compute the velocity of the camera from this displacement
1393  velocity = vpExponentialMap::inverse(cMc, time_cur - time_prev_getvel);
1394 
1395  break ;
1396  }
1397 
1398  case vpRobot::ARTICULAR_FRAME: {
1399  velocity = (q_cur - q_prev_getvel)
1400  / (time_cur - time_prev_getvel);
1401  break ;
1402  }
1403 
1404  case vpRobot::REFERENCE_FRAME: {
1405  // Compute the displacement of the camera since the previous call
1406  cMc = fMc_prev_getvel.inverse() * fMc_cur;
1407 
1408  // Compute the velocity of the camera from this displacement
1409  vpColVector v;
1410  v = vpExponentialMap::inverse(cMc, time_cur - time_prev_getvel);
1411 
1412  // Express this velocity in the reference frame
1413  vpVelocityTwistMatrix fVc(fMc_cur);
1414  velocity = fVc * v;
1415 
1416  break ;
1417  }
1418 
1419  case vpRobot::MIXT_FRAME: {
1420  vpERROR_TRACE ("Cannot get a velocity in the mixt frame: "
1421  "functionality not implemented");
1423  "Cannot get a displacement in the mixt frame:"
1424  "functionality not implemented");
1425 
1426  break ;
1427  }
1428  }
1429  }
1430  else {
1431  first_time_getvel = false;
1432  }
1433 
1434  // Memorize the camera pose for the next call
1435  fMc_prev_getvel = fMc_cur;
1436 
1437  // Memorize the joint position for the next call
1438  q_prev_getvel = q_cur;
1439 
1440  // Memorize the time associated to the joint position for the next call
1441  time_prev_getvel = time_cur;
1442 
1443 
1444  CatchPrint();
1445  if (TryStt < 0) {
1446  vpERROR_TRACE ("Cannot get velocity.");
1448  "Cannot get velocity.");
1449  }
1450 }
1451 
1452 
1453 
1454 
1493 {
1494  vpColVector velocity;
1495  getVelocity (frame, velocity);
1496 
1497  return velocity;
1498 }
1499 
1550 bool
1551 vpRobotAfma4::readPosFile(const char *filename, vpColVector &q)
1552 {
1553 
1554  FILE * fd ;
1555  fd = fopen(filename, "r") ;
1556  if (fd == NULL)
1557  return false;
1558 
1559  char line[FILENAME_MAX];
1560  char dummy[FILENAME_MAX];
1561  char head[] = "R:";
1562  bool sortie = false;
1563 
1564  do {
1565  // Saut des lignes commencant par #
1566  if (fgets (line, FILENAME_MAX, fd) != NULL) {
1567  if ( strncmp (line, "#", 1) != 0) {
1568  // La ligne n'est pas un commentaire
1569  if ( strncmp (line, head, sizeof(head)-1) == 0) {
1570  sortie = true; // Position robot trouvee.
1571  }
1572 // else
1573 // return (false); // fin fichier sans position robot.
1574  }
1575  }
1576  else {
1577  return (false); /* fin fichier */
1578  }
1579 
1580  }
1581  while ( sortie != true );
1582 
1583  // Lecture des positions
1584  q.resize(4);
1585  sscanf(line, "%s %lf %lf %lf %lf",
1586  dummy,
1587  &q[0], &q[1], &q[2], &q[3]);
1588 
1589  // converts rotations from degrees into radians
1590  q[0] = vpMath::rad(q[0]);
1591  q[2] = vpMath::rad(q[2]);
1592  q[3] = vpMath::rad(q[3]);
1593 
1594 
1595  fclose(fd) ;
1596  return (true);
1597 }
1598 
1622 bool
1623 vpRobotAfma4::savePosFile(const char *filename, const vpColVector &q)
1624 {
1625 
1626  FILE * fd ;
1627  fd = fopen(filename, "w") ;
1628  if (fd == NULL)
1629  return false;
1630 
1631  fprintf(fd, "\
1632 #AFMA4 - Position - Version 2.01\n\
1633 #\n\
1634 # R: X Y A B\n\
1635 # Joint position: X : rotation of the turret in degrees (joint 1)\n\
1636 # Y : vertical translation in meters (joint 2)\n\
1637 # A : pan rotation of the camera in degrees (joint 4)\n\
1638 # B : tilt rotation of the camera in degrees (joint 5)\n\
1639 #\n\n");
1640 
1641  // Save positions in mm and deg
1642  fprintf(fd, "R: %lf %lf %lf %lf\n",
1643  vpMath::deg(q[0]),
1644  q[1],
1645  vpMath::deg(q[2]),
1646  vpMath::deg(q[3]));
1647 
1648  fclose(fd) ;
1649  return (true);
1650 }
1651 
1662 void
1663 vpRobotAfma4::move(const char *filename)
1664 {
1665  vpColVector q;
1666 
1667  this->readPosFile(filename, q) ;
1669  this->setPositioningVelocity(10);
1671 }
1672 
1686 void
1688 {
1689  getDisplacement(vpRobot::CAMERA_FRAME, displacement);
1690 }
1702 void
1704 {
1706 }
1707 
1728 void
1730  vpColVector &displacement)
1731 {
1732  displacement.resize (6);
1733  displacement = 0;
1734 
1735  double q[6];
1736  vpColVector q_cur(6);
1737 
1738  InitTry;
1739 
1740  // Get the current joint position
1741  Try( PrimitiveACQ_POS_Afma4(q) );
1742  for (unsigned int i=0; i < njoint; i ++) {
1743  q_cur[i] = q[i];
1744  }
1745 
1746  if ( ! first_time_getdis ) {
1747  switch (frame) {
1748  case vpRobot::CAMERA_FRAME: {
1749  std::cout << "getDisplacement() CAMERA_FRAME not implemented\n";
1750  return;
1751  break ;
1752  }
1753 
1754  case vpRobot::ARTICULAR_FRAME: {
1755  displacement = q_cur - q_prev_getdis;
1756  break ;
1757  }
1758 
1759  case vpRobot::REFERENCE_FRAME: {
1760  std::cout << "getDisplacement() REFERENCE_FRAME not implemented\n";
1761  return;
1762  break ;
1763  }
1764 
1765  case vpRobot::MIXT_FRAME: {
1766  std::cout << "getDisplacement() MIXT_FRAME not implemented\n";
1767  return;
1768  break ;
1769  }
1770  }
1771  }
1772  else {
1773  first_time_getdis = false;
1774  }
1775 
1776  // Memorize the joint position for the next call
1777  q_prev_getdis = q_cur;
1778 
1779  CatchPrint();
1780  if (TryStt < 0) {
1781  vpERROR_TRACE ("Cannot get velocity.");
1783  "Cannot get velocity.");
1784  }
1785 }
1786 
1787 
1788 /*
1789  * Local variables:
1790  * c-basic-offset: 2
1791  * End:
1792  */
1793 
1794 #endif
1795 
static vpColVector inverse(const vpHomogeneousMatrix &M)
Definition of the vpMatrix class.
Definition: vpMatrix.h:96
void get_eJe(const vpColVector &q, vpMatrix &eJe)
Definition: vpAfma4.cpp:417
void get_cVf(vpVelocityTwistMatrix &cVf)
void get_fMe(const vpColVector &q, vpHomogeneousMatrix &fMe)
Definition: vpAfma4.cpp:272
Error that can be emited by the vpRobot class and its derivates.
static bool savePosFile(const char *filename, const vpColVector &q)
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
#define vpERROR_TRACE
Definition: vpDebug.h:379
virtual ~vpRobotAfma4(void)
virtual vpRobotStateType getRobotState(void)
Definition: vpRobot.h:148
void init(void)
void setVelocity(const vpRobot::vpControlFrameType frame, const vpColVector &velocity)
vpHomogeneousMatrix _eMc
Definition: vpAfma4.h:155
double getMaxTranslationVelocity(void) const
Definition: vpRobot.cpp:208
void get_cMe(vpHomogeneousMatrix &cMe)
Initialize the position controller.
Definition: vpRobot.h:71
class that defines a generic virtual robot
Definition: vpRobot.h:60
static vpColVector saturateVelocities(const vpColVector &v_in, const vpColVector &v_max, bool verbose=false)
Definition: vpRobot.cpp:114
vpControlFrameType
Definition: vpRobot.h:83
void get_fJe_inverse(const vpColVector &q, vpMatrix &fJe_inverse)
Definition: vpAfma4.cpp:527
double getMaxRotationVelocity(void) const
Definition: vpRobot.cpp:233
void move(const char *filename)
virtual vpRobotStateType setRobotState(const vpRobot::vpRobotStateType newState)
Definition: vpRobot.cpp:152
The vpRotationMatrix considers the particular case of a rotation matrix.
double * data
address of the first element of the data array
Definition: vpMatrix.h:116
void setPosition(const vpRobot::vpControlFrameType frame, const vpColVector &position)
double _joint_max[4]
Definition: vpAfma4.h:148
Initialize the velocity controller.
Definition: vpRobot.h:70
vpRobotStateType
Definition: vpRobot.h:66
void get_cVe(vpVelocityTwistMatrix &cVe)
void getPosition(const vpRobot::vpControlFrameType frame, vpColVector &position)
void getCameraDisplacement(vpColVector &displacement)
void setPositioningVelocity(const double velocity)
vpVelocityTwistMatrix buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
void getArticularDisplacement(vpColVector &displacement)
double _joint_min[4]
Definition: vpAfma4.h:149
void get_fJe(const vpColVector &q, vpMatrix &fJe)
Definition: vpAfma4.cpp:471
static const unsigned int njoint
Number of joint.
Definition: vpAfma4.h:141
Modelisation of Irisa's cylindrical robot named Afma4.
Definition: vpAfma4.h:112
void extract(vpRotationMatrix &R) const
Class that consider the particular case of twist transformation matrix that allows to transform a vel...
static double rad(double deg)
Definition: vpMath.h:100
vpHomogeneousMatrix get_fMc(const vpColVector &q)
Definition: vpAfma4.cpp:189
void get_eJe(vpMatrix &eJe)
static bool readPosFile(const char *filename, vpColVector &q)
vpRobot::vpRobotStateType setRobotState(vpRobot::vpRobotStateType newState)
static double deg(double rad)
Definition: vpMath.h:93
vpMatrix eJe
robot Jacobian expressed in the end-effector frame
Definition: vpRobot.h:113
void getDisplacement(vpRobot::vpControlFrameType frame, vpColVector &displacement)
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
void get_cVf(const vpColVector &q, vpVelocityTwistMatrix &cVf)
Definition: vpAfma4.cpp:367
vpHomogeneousMatrix inverse() const
void getVelocity(const vpRobot::vpControlFrameType frame, vpColVector &velocity)
void get_fJe(vpMatrix &fJe)
Class that consider the case of the Euler angle using the x-y-z convention, where are respectively ...
Definition: vpRxyzVector.h:152
bool getPowerState()
double getPositioningVelocity(void)
static double measureTimeSecond()
Definition: vpTime.cpp:225
unsigned int getRows() const
Return the number of rows of the matrix.
Definition: vpMatrix.h:157
static const double defaultPositioningVelocity
Definition: vpRobotAfma4.h:227
void buildFrom(const double phi, const double theta, const double psi)
Definition: vpRxyzVector.h:188
Class that consider the case of a translation vector.
void get_cMe(vpHomogeneousMatrix &cMe)
Definition: vpAfma4.cpp:323
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:94