ViSP  2.6.2
vpRobotViper850.cpp
1 /****************************************************************************
2  *
3  * $Id: vpRobotViper850.cpp 3697 2012-05-03 08:41:33Z 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 Viper S850 robot.
36  *
37  * Authors:
38  * Fabien Spindler
39  *
40  *****************************************************************************/
41 
42 #include <visp/vpConfig.h>
43 
44 #ifdef VISP_HAVE_VIPER850
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/vpRobot.h>
55 #include <visp/vpRobotViper850.h>
56 
57 /* ---------------------------------------------------------------------- */
58 /* --- STATIC ----------------------------------------------------------- */
59 /* ---------------------------------------------------------------------- */
60 
61 bool vpRobotViper850::robotAlreadyCreated = false;
62 
71 
72 /* ---------------------------------------------------------------------- */
73 /* --- EMERGENCY STOP --------------------------------------------------- */
74 /* ---------------------------------------------------------------------- */
75 
83 void emergencyStopViper850(int signo)
84 {
85  std::cout << "Stop the Viper850 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_Viper850();
104  PrimitiveSTOP_Viper850();
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 /* --- CONSTRUCTOR ------------------------------------------------------ */
118 /* ---------------------------------------------------------------------- */
119 
176  :
177  vpViper850 (),
178  vpRobot ()
179 {
180 
181  /*
182  #define SIGHUP 1 // hangup
183  #define SIGINT 2 // interrupt (rubout)
184  #define SIGQUIT 3 // quit (ASCII FS)
185  #define SIGILL 4 // illegal instruction (not reset when caught)
186  #define SIGTRAP 5 // trace trap (not reset when caught)
187  #define SIGIOT 6 // IOT instruction
188  #define SIGABRT 6 // used by abort, replace SIGIOT in the future
189  #define SIGEMT 7 // EMT instruction
190  #define SIGFPE 8 // floating point exception
191  #define SIGKILL 9 // kill (cannot be caught or ignored)
192  #define SIGBUS 10 // bus error
193  #define SIGSEGV 11 // segmentation violation
194  #define SIGSYS 12 // bad argument to system call
195  #define SIGPIPE 13 // write on a pipe with no one to read it
196  #define SIGALRM 14 // alarm clock
197  #define SIGTERM 15 // software termination signal from kill
198  */
199 
200  signal(SIGINT, emergencyStopViper850);
201  signal(SIGBUS, emergencyStopViper850) ;
202  signal(SIGSEGV, emergencyStopViper850) ;
203  signal(SIGKILL, emergencyStopViper850);
204  signal(SIGQUIT, emergencyStopViper850);
205 
206  std::cout << "Open communication with MotionBlox.\n";
207  try {
208  this->init();
210  }
211  catch(...) {
212  // vpERROR_TRACE("Error caught") ;
213  throw ;
214  }
215  positioningVelocity = defaultPositioningVelocity ;
216 
217  vpRobotViper850::robotAlreadyCreated = true;
218 
219  return ;
220 }
221 
222 
223 /* ------------------------------------------------------------------------ */
224 /* --- INITIALISATION ----------------------------------------------------- */
225 /* ------------------------------------------------------------------------ */
226 
246 void
248 {
249  InitTry;
250 
251  // Initialise private variables used to compute the measured velocities
252  q_prev_getvel.resize(6);
253  q_prev_getvel = 0;
254  time_prev_getvel = 0;
255  first_time_getvel = true;
256 
257  // Initialise private variables used to compute the measured displacement
258  q_prev_getdis.resize(6);
259  q_prev_getdis = 0;
260  first_time_getdis = true;
261 
262 
263  // Initialize the firewire connection
264  Try( InitializeConnection() );
265 
266  // Connect to the servoboard using the servo board GUID
267  Try( InitializeNode_Viper850() );
268 
269  Try( PrimitiveRESET_Viper850() );
270 
271  // Update the eMc matrix in the low level controller
273 
274  // Look if the power is on or off
275  UInt32 HIPowerStatus;
276  UInt32 EStopStatus;
277  Try( PrimitiveSTATUS_Viper850(NULL, NULL, &EStopStatus, NULL, NULL, NULL,
278  &HIPowerStatus));
279  CAL_Wait(0.1);
280 
281  // Print the robot status
282  std::cout << "Robot status: ";
283  switch(EStopStatus) {
284  case ESTOP_AUTO:
285  controlMode = AUTO;
286  if (HIPowerStatus == 0)
287  std::cout << "Power is OFF" << std::endl;
288  else
289  std::cout << "Power is ON" << std::endl;
290  break;
291 
292  case ESTOP_MANUAL:
293  controlMode = MANUAL;
294  if (HIPowerStatus == 0)
295  std::cout << "Power is OFF" << std::endl;
296  else
297  std::cout << "Power is ON" << std::endl;
298  break;
299  case ESTOP_ACTIVATED:
300  controlMode = ESTOP;
301  std::cout << "Emergency stop is activated" << std::endl;
302  break;
303  default:
304  std::cout << "Sorry there is an error on the emergency chain." << std::endl;
305  std::cout << "You have to call Adept for maintenance..." << std::endl;
306  // Free allocated ressources
307  }
308  std::cout << std::endl;
309 
310  // get real joint min/max from the MotionBlox
311  Try( PrimitiveJOINT_MINMAX_Viper850(joint_min.data, joint_max.data) );
312  // Convert units from degrees to radians
313  joint_min.deg2rad();
314  joint_max.deg2rad();
315 
316 // for (unsigned int i=0; i < njoint; i++) {
317 // printf("axis %d: joint min %lf, max %lf\n", i, joint_min[i], joint_max[i]);
318 // }
319 
320  // If an error occur in the low level controller, goto here
321  //CatchPrint();
322  Catch();
323 
324  // Test if an error occurs
325  if (TryStt == -20001)
326  printf("No connection detected. Check if the robot is powered on \n"
327  "and if the firewire link exist between the MotionBlox and this computer.\n");
328  else if (TryStt == -675)
329  printf(" Timeout enabling power...\n");
330 
331  if (TryStt < 0) {
332  // Power off the robot
333  PrimitivePOWEROFF_Viper850();
334  // Free allocated ressources
335  ShutDownConnection();
336 
337  std::cout << "Cannot open connexion with the motionblox..." << std::endl;
339  "Cannot open connexion with the motionblox");
340  }
341  return ;
342 }
343 
400 void
403 {
404 
405  InitTry;
406  // Read the robot constants from files
407  // - joint [min,max], coupl_56, long_56
408  // - camera extrinsic parameters relative to eMc
409  vpViper850::init(tool, projModel);
410 
411  // Set the camera constant (eMc pose) in the MotionBlox
412  double eMc_pose[6];
413  for (unsigned int i=0; i < 3; i ++) {
414  eMc_pose[i] = etc[i]; // translation in meters
415  eMc_pose[i+3] = erc[i]; // rotation in rad
416  }
417  // Update the eMc pose in the low level controller
418  Try( PrimitiveCONST_Viper850(eMc_pose) );
419 
420  // get real joint min/max from the MotionBlox
421  Try( PrimitiveJOINT_MINMAX_Viper850(joint_min.data, joint_max.data) );
422  // Convert units from degrees to radians
423  joint_min.deg2rad();
424  joint_max.deg2rad();
425 
426 // for (unsigned int i=0; i < njoint; i++) {
427 // printf("axis %d: joint min %lf, max %lf\n", i, joint_min[i], joint_max[i]);
428 // }
429 
430  setToolType(tool);
431 
432  CatchPrint();
433  return ;
434 }
435 
436 /* ------------------------------------------------------------------------ */
437 /* --- DESTRUCTOR --------------------------------------------------------- */
438 /* ------------------------------------------------------------------------ */
439 
447 {
448  InitTry;
449 
451 
452  // Look if the power is on or off
453  UInt32 HIPowerStatus;
454  Try( PrimitiveSTATUS_Viper850(NULL, NULL, NULL, NULL, NULL, NULL,
455  &HIPowerStatus));
456  CAL_Wait(0.1);
457 
458 // if (HIPowerStatus == 1) {
459 // fprintf(stdout, "Power OFF the robot\n");
460 // fflush(stdout);
461 
462 // Try( PrimitivePOWEROFF_Viper850() );
463 // }
464 
465  // Free allocated ressources
466  ShutDownConnection();
467 
468  vpRobotViper850::robotAlreadyCreated = false;
469 
470  CatchPrint();
471  return;
472 }
473 
474 
475 
476 
485 {
486  InitTry;
487 
488  switch (newState) {
489  case vpRobot::STATE_STOP: {
490  // Start primitive STOP only if the current state is Velocity
492  Try( PrimitiveSTOP_Viper850() );
493  }
494  break;
495  }
498  std::cout << "Change the control mode from velocity to position control.\n";
499  Try( PrimitiveSTOP_Viper850() );
500  }
501  else {
502  //std::cout << "Change the control mode from stop to position control.\n";
503  }
504  this->powerOn();
505  break;
506  }
509  std::cout << "Change the control mode from stop to velocity control.\n";
510  }
511  this->powerOn();
512  break;
513  }
514  default:
515  break ;
516  }
517 
518  CatchPrint();
519 
520  return vpRobot::setRobotState (newState);
521 }
522 
523 
524 /* ------------------------------------------------------------------------ */
525 /* --- STOP --------------------------------------------------------------- */
526 /* ------------------------------------------------------------------------ */
527 
535 void
537 {
539  return;
540 
541  InitTry;
542  Try( PrimitiveSTOP_Viper850() );
544 
545  CatchPrint();
546  if (TryStt < 0) {
547  vpERROR_TRACE ("Cannot stop robot motion");
549  "Cannot stop robot motion.");
550  }
551 }
552 
562 void
564 {
565  InitTry;
566 
567  // Look if the power is on or off
568  UInt32 HIPowerStatus;
569  UInt32 EStopStatus;
570  bool firsttime = true;
571  unsigned int nitermax = 10;
572 
573  for (unsigned int i=0; i<nitermax; i++) {
574  Try( PrimitiveSTATUS_Viper850(NULL, NULL, &EStopStatus, NULL, NULL, NULL,
575  &HIPowerStatus));
576  switch(EStopStatus) {
577  case ESTOP_AUTO: controlMode = AUTO; break;
578  case ESTOP_MANUAL: controlMode = MANUAL; break;
579  case ESTOP_ACTIVATED:
580  controlMode = ESTOP;
581  if (firsttime) {
582  std::cout << "Emergency stop is activated! \n"
583  << "Check the emergency stop button and push the yellow button before continuing." << std::endl;
584  firsttime = false;
585  }
586  fprintf(stdout, "Remaining time %ds \r", nitermax-i);
587  fflush(stdout);
588  CAL_Wait(1);
589  break;
590  default:
591  std::cout << "Sorry there is an error on the emergency chain." << std::endl;
592  std::cout << "You have to call Adept for maintenance..." << std::endl;
593  // Free allocated ressources
594  ShutDownConnection();
595  exit(0);
596  }
597  }
598 
599  std::cout << std::endl;
600 
601  if (EStopStatus == ESTOP_ACTIVATED) {
602  std::cout << "Sorry, cannot power on the robot." << std::endl;
604  "Cannot power on the robot.");
605  }
606 
607  if (HIPowerStatus == 0) {
608  fprintf(stdout, "Power ON the Viper850 robot\n");
609  fflush(stdout);
610 
611  Try( PrimitivePOWERON_Viper850() );
612  }
613 
614  CatchPrint();
615  if (TryStt < 0) {
616  vpERROR_TRACE ("Cannot power on the robot");
618  "Cannot power off the robot.");
619  }
620 }
621 
631 void
633 {
634  InitTry;
635 
636  // Look if the power is on or off
637  UInt32 HIPowerStatus;
638  Try( PrimitiveSTATUS_Viper850(NULL, NULL, NULL, NULL, NULL, NULL,
639  &HIPowerStatus));
640  CAL_Wait(0.1);
641 
642  if (HIPowerStatus == 1) {
643  fprintf(stdout, "Power OFF the Viper850 robot\n");
644  fflush(stdout);
645 
646  Try( PrimitivePOWEROFF_Viper850() );
647  }
648 
649  CatchPrint();
650  if (TryStt < 0) {
651  vpERROR_TRACE ("Cannot power off the robot");
653  "Cannot power off the robot.");
654  }
655 }
656 
668 bool
670 {
671  InitTry;
672  bool status = false;
673  // Look if the power is on or off
674  UInt32 HIPowerStatus;
675  Try( PrimitiveSTATUS_Viper850(NULL, NULL, NULL, NULL, NULL, NULL,
676  &HIPowerStatus));
677  CAL_Wait(0.1);
678 
679  if (HIPowerStatus == 1) {
680  status = true;
681  }
682 
683  CatchPrint();
684  if (TryStt < 0) {
685  vpERROR_TRACE ("Cannot get the power status");
687  "Cannot get the power status.");
688  }
689  return status;
690 }
691 
701 void
703 {
704  vpHomogeneousMatrix cMe ;
705  vpViper850::get_cMe(cMe) ;
706 
707  cVe.buildFrom(cMe) ;
708 }
709 
721 void
723 {
724  vpViper850::get_cMe(cMe) ;
725 }
726 
727 
739 void
741 {
742 
743  double position[6];
744 
745  InitTry;
746  Try( PrimitiveACQ_POS_J_Viper850(position) );
747  CatchPrint();
748 
749  vpColVector q(6);
750  for (unsigned int i=0; i < njoint; i++)
751  q[i] = vpMath::rad(position[i]);
752 
753  try
754  {
755  vpViper850::get_eJe(q, eJe) ;
756  }
757  catch(...)
758  {
759  vpERROR_TRACE("catch exception ") ;
760  throw ;
761  }
762 }
775  void
777 {
778 
779  double position[6];
780 
781  InitTry;
782  Try( PrimitiveACQ_POS_Viper850(position) );
783  CatchPrint();
784 
785  vpColVector q(6);
786  for (unsigned int i=0; i < njoint; i++)
787  q[i] = position[i];
788 
789  try
790  {
791  vpViper850::get_fJe(q, fJe) ;
792  }
793  catch(...)
794  {
795  vpERROR_TRACE("Error caught");
796  throw ;
797  }
798 }
799 
837 void
839 {
840  positioningVelocity = velocity;
841 }
842 
848 double
850 {
851  return positioningVelocity;
852 }
853 
854 
932 void
934  const vpColVector & position )
935 {
936 
938  {
939  vpERROR_TRACE ("Robot was not in position-based control\n"
940  "Modification of the robot state");
942  }
943 
944  vpColVector destination(njoint);
945  int error = 0;
946 
947  InitTry;
948  switch(frame) {
949  case vpRobot::CAMERA_FRAME : {
950  vpColVector q(njoint);
951  Try( PrimitiveACQ_POS_Viper850(q.data) );
952 
953  // Convert degrees into rad
954  q.deg2rad();
955 
956  // Get fMc from the inverse kinematics
958  vpViper850::get_fMc(q, fMc);
959 
960  // Set cMc from the input position
961  vpTranslationVector txyz;
962  vpRxyzVector rxyz;
963  for (unsigned int i=0; i < 3; i++) {
964  txyz[i] = position[i];
965  rxyz[i] = position[i+3];
966  }
967 
968  // Compute cMc2
969  vpRotationMatrix cRc2(rxyz);
970  vpHomogeneousMatrix cMc2(txyz, cRc2);
971 
972  // Compute the new position to reach: fMc*cMc2
973  vpHomogeneousMatrix fMc2 = fMc * cMc2;
974 
975  // Compute the corresponding joint position from the inverse kinematics
976  unsigned int solution = this->getInverseKinematics(fMc2, q);
977  if (solution) { // Position is reachable
978  destination = q;
979  // convert rad to deg requested for the low level controller
980  destination.rad2deg();
981  Try( PrimitiveMOVE_J_Viper850(destination.data, positioningVelocity) );
982  Try( WaitState_Viper850(ETAT_ATTENTE_AFMA6, 1000) );
983  }
984  else {
985  // Cartesian position is out of range
986  error = -1;
987  }
988 
989  break ;
990  }
992  destination = position;
993  // convert rad to deg requested for the low level controller
994  destination.rad2deg();
995 
996  //std::cout << "Joint destination (deg): " << destination.t() << std::endl;
997  Try( PrimitiveMOVE_J_Viper850(destination.data, positioningVelocity) );
998  Try( WaitState_Viper850(ETAT_ATTENTE_AFMA6, 1000) );
999  break ;
1000 
1001  }
1002  case vpRobot::REFERENCE_FRAME: {
1003  // Convert angles from Rxyz representation to Rzyz representation
1004  vpRxyzVector rxyz(position[3],position[4],position[5]);
1005  vpRotationMatrix R(rxyz);
1006  vpRzyzVector rzyz(R);
1007 
1008  for (unsigned int i=0; i <3; i++) {
1009  destination[i] = position[i];
1010  destination[i+3] = vpMath::deg(rzyz[i]); // convert also angles in deg
1011  }
1012  int configuration = 0; // keep the actual configuration
1013 
1014  //std::cout << "Base frame destination Rzyz (deg): " << destination.t() << std::endl;
1015  Try( PrimitiveMOVE_C_Viper850(destination.data, configuration,
1016  positioningVelocity) );
1017  Try( WaitState_Viper850(ETAT_ATTENTE_AFMA6, 1000) );
1018 
1019  break ;
1020  }
1021  case vpRobot::MIXT_FRAME:
1022  {
1023  vpERROR_TRACE ("Positionning error. Mixt frame not implemented");
1025  "Positionning error: "
1026  "Mixt frame not implemented.");
1027  break ;
1028  }
1029  }
1030 
1031  CatchPrint();
1032  if (TryStt == InvalidPosition || TryStt == -1023)
1033  std::cout << " : Position out of range.\n";
1034  else if (TryStt == -3019) {
1035  if (frame == vpRobot::ARTICULAR_FRAME)
1036  std::cout << " : Joint position out of range.\n";
1037  else
1038  std::cout << " : Cartesian position leads to a joint position out of range.\n";
1039  }
1040  else if (TryStt < 0)
1041  std::cout << " : Unknown error (see Fabien).\n";
1042  else if (error == -1)
1043  std::cout << "Position out of range.\n";
1044 
1045  if (TryStt < 0 || error < 0) {
1046  vpERROR_TRACE ("Positionning error.");
1048  "Position out of range.");
1049  }
1050 
1051  return ;
1052 }
1053 
1120  const double pos1,
1121  const double pos2,
1122  const double pos3,
1123  const double pos4,
1124  const double pos5,
1125  const double pos6)
1126 {
1127  try{
1128  vpColVector position(6) ;
1129  position[0] = pos1 ;
1130  position[1] = pos2 ;
1131  position[2] = pos3 ;
1132  position[3] = pos4 ;
1133  position[4] = pos5 ;
1134  position[5] = pos6 ;
1135 
1136  setPosition(frame, position) ;
1137  }
1138  catch(...)
1139  {
1140  vpERROR_TRACE("Error caught");
1141  throw ;
1142  }
1143 }
1144 
1184 void vpRobotViper850::setPosition(const char *filename)
1185 {
1186  vpColVector q;
1187  bool ret;
1188 
1189  ret = this->readPosFile(filename, q);
1190 
1191  if (ret == false) {
1192  vpERROR_TRACE ("Bad position in \"%s\"", filename);
1194  "Bad position in filename.");
1195  }
1198 }
1199 
1265 void
1267  vpColVector & position)
1268 {
1269 
1270  InitTry;
1271 
1272  position.resize (6);
1273 
1274  switch (frame) {
1275  case vpRobot::CAMERA_FRAME : {
1276  position = 0;
1277  return;
1278  }
1279  case vpRobot::ARTICULAR_FRAME : {
1280  Try( PrimitiveACQ_POS_J_Viper850(position.data) );
1281  //vpCTRACE << "Get joint position (deg)" << position.t() << std::endl;
1282  position.deg2rad();
1283 
1284  return;
1285  }
1286  case vpRobot::REFERENCE_FRAME : {
1287  Try( PrimitiveACQ_POS_C_Viper850(position.data) );
1288  // vpCTRACE << "Get cartesian position " << position.t() << std::endl;
1289  // 1=tx, 2=ty, 3=tz in meters; 4=Rz 5=Ry 6=Rz in deg
1290  // Convert Euler Rzyz angles from deg to rad
1291  for (unsigned int i=3; i <6; i++)
1292  position[i] = vpMath::rad(position[i]);
1293  // Convert Rzyz angles into Rxyz representation
1294  vpRzyzVector rzyz(position[3], position[4], position[5]);
1295  vpRotationMatrix R(rzyz);
1296  vpRxyzVector rxyz(R);
1297 
1298  // Update the position using Rxyz representation
1299  for (unsigned int i=0; i <3; i++)
1300  position[i+3] = rxyz[i];
1301 // vpCTRACE << "Cartesian position Rxyz (deg)"
1302 // << position[0] << " " << position[1] << " " << position[2] << " "
1303 // << vpMath::deg(position[3]) << " "
1304 // << vpMath::deg(position[4]) << " "
1305 // << vpMath::deg(position[5]) << std::endl;
1306 
1307  break ;
1308  }
1309  case vpRobot::MIXT_FRAME: {
1310  vpERROR_TRACE ("Cannot get position in mixt frame: not implemented");
1312  "Cannot get position in mixt frame: "
1313  "not implemented");
1314  break ;
1315  }
1316  }
1317 
1318  CatchPrint();
1319  if (TryStt < 0) {
1320  vpERROR_TRACE ("Cannot get position.");
1322  "Cannot get position.");
1323  }
1324 
1325  return;
1326 }
1338 void
1340  vpPoseVector &position)
1341 {
1342  vpColVector posRxyz;
1343  //recupere position en Rxyz
1344  this->getPosition(frame,posRxyz);
1345  vpRxyzVector RxyzVect;
1346  for (unsigned int j=0;j<3;j++)
1347  RxyzVect[j]=posRxyz[j+3];
1348  //recupere le vecteur thetaU correspondant
1349  vpThetaUVector RtuVect(RxyzVect);
1350 
1351  //remplit le vpPoseVector avec translation et rotation ThetaU
1352  for (unsigned int j=0;j<3;j++)
1353  {
1354  position[j]=posRxyz[j];
1355  position[j+3]=RtuVect[j];
1356  }
1357 }
1358 
1431 void
1433  const vpColVector & vel)
1434 {
1436  vpERROR_TRACE ("Cannot send a velocity to the robot "
1437  "use setRobotState(vpRobot::STATE_VELOCITY_CONTROL) first) ");
1439  "Cannot send a velocity to the robot "
1440  "use setRobotState(vpRobot::STATE_VELOCITY_CONTROL) first) ");
1441  }
1442 
1443  vpColVector vel_sat(6);
1444 
1445  // Velocity saturation
1446  switch(frame) {
1447  // saturation in cartesian space
1448  case vpRobot::CAMERA_FRAME :
1450  case vpRobot::MIXT_FRAME : {
1451  vpColVector vel_max(6);
1452 
1453  for (int i=0; i<3; i++)
1454  vel_max[i] = getMaxTranslationVelocity();
1455  for (int i=3; i<6; i++)
1456  vel_max[i] = getMaxRotationVelocity();
1457 
1458  vel_sat = vpRobot::saturateVelocities(vel, vel_max, true);
1459 
1460  break;
1461  }
1462  // saturation in joint space
1463  case vpRobot::ARTICULAR_FRAME : {
1464  vpColVector vel_max(6);
1465 
1466  for (int i=0; i<6; i++)
1467  vel_max[i] = getMaxRotationVelocity();
1468 
1469  vel_sat = vpRobot::saturateVelocities(vel, vel_max, true);
1470  }
1471  }
1472 
1473  InitTry;
1474 
1475  switch(frame) {
1476  case vpRobot::CAMERA_FRAME : {
1477  // Send velocities in m/s and rad/s
1478  // std::cout << "Vitesse cam appliquee: " << vel_sat.t();
1479  Try( PrimitiveMOVESPEED_CART_Viper850(vel_sat.data, REPCAM) );
1480  break ;
1481  }
1482  case vpRobot::ARTICULAR_FRAME : {
1483  // Convert all the velocities from rad/s into deg/s
1484  vel_sat.rad2deg();
1485  //std::cout << "Vitesse appliquee: " << vel_sat.t();
1486  //Try( PrimitiveMOVESPEED_CART(vel_sat.data, REPART) );
1487  Try( PrimitiveMOVESPEED_Viper850(vel_sat.data) );
1488  break ;
1489  }
1490  case vpRobot::REFERENCE_FRAME : {
1491  // Send velocities in m/s and rad/s
1492  std::cout << "Vitesse ref appliquee: " << vel_sat.t();
1493  Try( PrimitiveMOVESPEED_CART_Viper850(vel_sat.data, REPFIX) );
1494  break ;
1495  }
1496  case vpRobot::MIXT_FRAME : {
1497  //Try( PrimitiveMOVESPEED_CART_Viper850(vel_sat.data, REPMIX) );
1498  break ;
1499  }
1500  default: {
1501  vpERROR_TRACE ("Error in spec of vpRobot. "
1502  "Case not taken in account.");
1503  return;
1504  }
1505  }
1506 
1507  Catch();
1508  if (TryStt < 0) {
1509  if (TryStt == VelStopOnJoint) {
1510  UInt32 axisInJoint[njoint];
1511  PrimitiveSTATUS_Viper850(NULL, NULL, NULL, NULL, NULL, axisInJoint, NULL);
1512  for (unsigned int i=0; i < njoint; i ++) {
1513  if (axisInJoint[i])
1514  std::cout << "\nWarning: Velocity control stopped: axis "
1515  << i+1 << " on joint limit!" <<std::endl;
1516  }
1517  }
1518  else {
1519  printf("\n%s(%d): Error %d", __FUNCTION__, TryLine, TryStt);
1520  if (TryString != NULL) {
1521  // The statement is in TryString, but we need to check the validity
1522  printf(" Error sentence %s\n", TryString); // Print the TryString
1523  }
1524  else {
1525  printf("\n");
1526  }
1527  }
1528  }
1529 
1530  return;
1531 }
1532 
1533 
1534 
1535 
1536 
1537 
1538 /* ------------------------------------------------------------------------ */
1539 /* --- GET ---------------------------------------------------------------- */
1540 /* ------------------------------------------------------------------------ */
1541 
1542 
1597 void
1599  vpColVector & velocity)
1600 {
1601 
1602  velocity.resize (6);
1603  velocity = 0;
1604 
1605  vpColVector q_cur(6);
1606  vpHomogeneousMatrix fMc_cur;
1607  vpHomogeneousMatrix cMc; // camera displacement
1608 
1609  InitTry;
1610 
1611  // Get the actual time
1612  double time_cur = vpTime::measureTimeSecond();
1613 
1614  // Get the current joint position
1615  Try( PrimitiveACQ_POS_J_Viper850(q_cur.data) );
1616  q_cur.deg2rad();
1617 
1618  // Get the camera pose from the direct kinematics
1619  vpViper850::get_fMc(q_cur, fMc_cur);
1620 
1621  if ( ! first_time_getvel ) {
1622 
1623  switch (frame) {
1624  case vpRobot::CAMERA_FRAME: {
1625  // Compute the displacement of the camera since the previous call
1626  cMc = fMc_prev_getvel.inverse() * fMc_cur;
1627 
1628  // Compute the velocity of the camera from this displacement
1629  velocity = vpExponentialMap::inverse(cMc, time_cur - time_prev_getvel);
1630 
1631  break ;
1632  }
1633 
1634  case vpRobot::ARTICULAR_FRAME: {
1635  velocity = (q_cur - q_prev_getvel)
1636  / (time_cur - time_prev_getvel);
1637  break ;
1638  }
1639 
1640  case vpRobot::REFERENCE_FRAME: {
1641  // Compute the displacement of the camera since the previous call
1642  cMc = fMc_prev_getvel.inverse() * fMc_cur;
1643 
1644  // Compute the velocity of the camera from this displacement
1645  vpColVector v;
1646  v = vpExponentialMap::inverse(cMc, time_cur - time_prev_getvel);
1647 
1648  // Express this velocity in the reference frame
1649  vpVelocityTwistMatrix fVc(fMc_cur);
1650  velocity = fVc * v;
1651 
1652  break ;
1653  }
1654 
1655  case vpRobot::MIXT_FRAME: {
1656  // Compute the displacement of the camera since the previous call
1657  cMc = fMc_prev_getvel.inverse() * fMc_cur;
1658 
1659  // Compute the ThetaU representation for the rotation
1660  vpRotationMatrix cRc;
1661  cMc.extract(cRc);
1662  vpThetaUVector thetaU;
1663  thetaU.buildFrom(cRc);
1664 
1665  for (unsigned int i=0; i < 3; i++) {
1666  // Compute the translation displacement in the reference frame
1667  velocity[i] = fMc_prev_getvel[i][3] - fMc_cur[i][3];
1668  // Update the rotation displacement in the camera frame
1669  velocity[i+3] = thetaU[i];
1670  }
1671 
1672  // Compute the velocity
1673  velocity /= (time_cur - time_prev_getvel);
1674  break ;
1675  }
1676  }
1677  }
1678  else {
1679  first_time_getvel = false;
1680  }
1681 
1682  // Memorize the camera pose for the next call
1683  fMc_prev_getvel = fMc_cur;
1684 
1685  // Memorize the joint position for the next call
1686  q_prev_getvel = q_cur;
1687 
1688  // Memorize the time associated to the joint position for the next call
1689  time_prev_getvel = time_cur;
1690 
1691 
1692  CatchPrint();
1693  if (TryStt < 0) {
1694  vpERROR_TRACE ("Cannot get velocity.");
1696  "Cannot get velocity.");
1697  }
1698 }
1699 
1700 
1701 
1702 
1752 {
1753  vpColVector velocity;
1754  getVelocity (frame, velocity);
1755 
1756  return velocity;
1757 }
1758 
1824 bool
1826 {
1827 
1828  FILE * fd ;
1829  fd = fopen(filename, "r") ;
1830  if (fd == NULL)
1831  return false;
1832 
1833  char line[FILENAME_MAX];
1834  char dummy[FILENAME_MAX];
1835  char head[] = "R:";
1836  bool sortie = false;
1837 
1838  do {
1839  // Saut des lignes commencant par #
1840  if (fgets (line, FILENAME_MAX, fd) != NULL) {
1841  if ( strncmp (line, "#", 1) != 0) {
1842  // La ligne n'est pas un commentaire
1843  if ( strncmp (line, head, sizeof(head)-1) == 0) {
1844  sortie = true; // Position robot trouvee.
1845  }
1846 // else
1847 // return (false); // fin fichier sans position robot.
1848  }
1849  }
1850  else {
1851  return (false); /* fin fichier */
1852  }
1853 
1854  }
1855  while ( sortie != true );
1856 
1857  // Lecture des positions
1858  q.resize(njoint);
1859  sscanf(line, "%s %lf %lf %lf %lf %lf %lf",
1860  dummy,
1861  &q[0], &q[1], &q[2],
1862  &q[3], &q[4], &q[5]);
1863 
1864  // converts rotations from degrees into radians
1865  q.deg2rad();
1866 
1867  fclose(fd) ;
1868  return (true);
1869 }
1870 
1894 bool
1895 vpRobotViper850::savePosFile(const char *filename, const vpColVector &q)
1896 {
1897 
1898  FILE * fd ;
1899  fd = fopen(filename, "w") ;
1900  if (fd == NULL)
1901  return false;
1902 
1903  fprintf(fd, "\
1904 #Viper - Position - Version 1.0\n\
1905 #\n\
1906 # R: A B C D E F\n\
1907 # Joint position in degrees\n\
1908 #\n\
1909 #\n\n");
1910 
1911  // Save positions in mm and deg
1912  fprintf(fd, "R: %lf %lf %lf %lf %lf %lf\n",
1913  vpMath::deg(q[0]),
1914  vpMath::deg(q[1]),
1915  vpMath::deg(q[2]),
1916  vpMath::deg(q[3]),
1917  vpMath::deg(q[4]),
1918  vpMath::deg(q[5]));
1919 
1920  fclose(fd) ;
1921  return (true);
1922 }
1923 
1934 void
1935 vpRobotViper850::move(const char *filename)
1936 {
1937  vpColVector q;
1938 
1939  try {
1940  this->readPosFile(filename, q) ;
1942  this->setPositioningVelocity(10);
1944  }
1945  catch(...) {
1946  throw;
1947  }
1948 }
1949 
1963 void
1965 {
1966  getDisplacement(vpRobot::CAMERA_FRAME, displacement);
1967 }
1979 void
1981 {
1983 }
1984 
2005 void
2007  vpColVector &displacement)
2008 {
2009  displacement.resize (6);
2010  displacement = 0;
2011 
2012  double q[6];
2013  vpColVector q_cur(6);
2014 
2015  InitTry;
2016 
2017  // Get the current joint position
2018  Try( PrimitiveACQ_POS_Viper850(q) );
2019  for (unsigned int i=0; i < njoint; i ++) {
2020  q_cur[i] = q[i];
2021  }
2022 
2023  if ( ! first_time_getdis ) {
2024  switch (frame) {
2025  case vpRobot::CAMERA_FRAME: {
2026  std::cout << "getDisplacement() CAMERA_FRAME not implemented\n";
2027  return;
2028  break ;
2029  }
2030 
2031  case vpRobot::ARTICULAR_FRAME: {
2032  displacement = q_cur - q_prev_getdis;
2033  break ;
2034  }
2035 
2036  case vpRobot::REFERENCE_FRAME: {
2037  std::cout << "getDisplacement() REFERENCE_FRAME not implemented\n";
2038  return;
2039  break ;
2040  }
2041 
2042  case vpRobot::MIXT_FRAME: {
2043  std::cout << "getDisplacement() MIXT_FRAME not implemented\n";
2044  return;
2045  break ;
2046  }
2047  }
2048  }
2049  else {
2050  first_time_getdis = false;
2051  }
2052 
2053  // Memorize the joint position for the next call
2054  q_prev_getdis = q_cur;
2055 
2056  CatchPrint();
2057  if (TryStt < 0) {
2058  vpERROR_TRACE ("Cannot get velocity.");
2060  "Cannot get velocity.");
2061  }
2062 }
2063 
2077 void
2079 {
2080  InitTry;
2081 
2082  Try( PrimitiveTFS_BIAS_Viper850() );
2083 
2084  // Wait 500 ms to be sure the next measures take into account the bias
2085  vpTime::wait(500);
2086 
2087  CatchPrint();
2088  if (TryStt < 0) {
2089  vpERROR_TRACE ("Cannot bias the force/torque sensor.");
2091  "Cannot bias the force/torque sensor.");
2092  }
2093 }
2094 
2134 void
2136 {
2137  InitTry;
2138 
2139  H.resize (6);
2140 
2141  Try( PrimitiveTFS_ACQ_Viper850(H.data) );
2142 
2143  CatchPrint();
2144  if (TryStt < 0) {
2145  vpERROR_TRACE ("Cannot get the force/torque measures.");
2147  "Cannot get force/torque measures.");
2148  }
2149 }
2156 void
2158 {
2159  InitTry;
2160  Try( PrimitiveGripper_Viper850(1) );
2161  std::cout << "Open the gripper..." << std::endl;
2162  CatchPrint();
2163  if (TryStt < 0) {
2164  vpERROR_TRACE ("Cannot open the gripper");
2166  "Cannot open the gripper.");
2167  }
2168 }
2169 
2177 void
2179 {
2180  InitTry;
2181  Try( PrimitiveGripper_Viper850(0) );
2182  std::cout << "Close the gripper..." << std::endl;
2183  CatchPrint();
2184  if (TryStt < 0) {
2185  vpERROR_TRACE ("Cannot close the gripper");
2187  "Cannot close the gripper.");
2188  }
2189 }
2190 
2191 
2192 /*
2193  * Local variables:
2194  * c-basic-offset: 2
2195  * End:
2196  */
2197 
2198 #endif
2199 
void getPosition(const vpRobot::vpControlFrameType frame, vpColVector &position)
static vpColVector inverse(const vpHomogeneousMatrix &M)
Definition of the vpMatrix class.
Definition: vpMatrix.h:96
double getPositioningVelocity(void)
Error that can be emited by the vpRobot class and its derivates.
static const vpToolType defaultTool
Default tool attached to the robot end effector.
Definition: vpViper850.h:99
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
void get_eJe(const vpColVector &q, vpMatrix &eJe)
Definition: vpViper.cpp:968
void getCameraDisplacement(vpColVector &displacement)
virtual vpRobotStateType getRobotState(void)
Definition: vpRobot.h:148
void setPositioningVelocity(const double velocity)
double getMaxTranslationVelocity(void) const
Definition: vpRobot.cpp:208
Initialize the position controller.
Definition: vpRobot.h:71
vpRobot::vpRobotStateType setRobotState(vpRobot::vpRobotStateType newState)
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
vpRxyzVector erc
Definition: vpViper.h:150
void get_eJe(vpMatrix &eJe)
static int wait(double t0, double t)
Definition: vpTime.cpp:149
static bool savePosFile(const char *filename, const vpColVector &q)
double getMaxRotationVelocity(void) const
Definition: vpRobot.cpp:233
vpThetaUVector buildFrom(const vpHomogeneousMatrix &M)
virtual vpRobotStateType setRobotState(const vpRobot::vpRobotStateType newState)
Definition: vpRobot.cpp:152
void deg2rad()
Definition: vpColVector.h:186
unsigned int getInverseKinematics(const vpHomogeneousMatrix &fMc, vpColVector &q)
Definition: vpViper.cpp:559
The vpRotationMatrix considers the particular case of a rotation matrix.
void getDisplacement(vpRobot::vpControlFrameType frame, vpColVector &displacement)
double * data
address of the first element of the data array
Definition: vpMatrix.h:116
static bool readPosFile(const char *filename, vpColVector &q)
Initialize the velocity controller.
Definition: vpRobot.h:70
vpRobotStateType
Definition: vpRobot.h:66
void setToolType(vpViper850::vpToolType tool)
Set the current tool type.
Definition: vpViper850.h:136
vpTranslationVector etc
Definition: vpViper.h:149
vpVelocityTwistMatrix buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
void getForceTorque(vpColVector &H)
vpRowVector t() const
transpose of Vector
vpColVector joint_max
Definition: vpViper.h:161
vpToolType
List of possible tools that can be attached to the robot end-effector.
Definition: vpViper850.h:91
Modelisation of the ADEPT Viper 850 robot.
Definition: vpViper850.h:66
void extract(vpRotationMatrix &R) const
void getArticularDisplacement(vpColVector &displacement)
Class that consider the particular case of twist transformation matrix that allows to transform a vel...
void get_fJe(vpMatrix &fJe)
static double rad(double deg)
Definition: vpMath.h:100
void get_fJe(const vpColVector &q, vpMatrix &fJe)
Definition: vpViper.cpp:1160
void setVelocity(const vpRobot::vpControlFrameType frame, const vpColVector &velocity)
static double deg(double rad)
Definition: vpMath.h:93
void getVelocity(const vpRobot::vpControlFrameType frame, vpColVector &velocity)
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
Manual control mode activated when the dead man switch is in use.
static const double defaultPositioningVelocity
void setPosition(const vpRobot::vpControlFrameType frame, const vpColVector &position)
void get_cVe(vpVelocityTwistMatrix &cVe)
The pose is a complete representation of every rigid motion in the euclidian space.
Definition: vpPoseVector.h:92
vpHomogeneousMatrix inverse() const
void get_cMe(vpHomogeneousMatrix &cMe)
Definition: vpViper.cpp:914
Class that consider the case of the Euler angle using the x-y-z convention, where are respectively ...
Definition: vpRxyzVector.h:152
static double measureTimeSecond()
Definition: vpTime.cpp:225
Emergency stop activated.
Class that consider the case of the Euler angles using the z-y-z convention, where are respectively...
Definition: vpRzyzVector.h:150
virtual ~vpRobotViper850(void)
void init(void)
Definition: vpViper850.cpp:174
Automatic control mode (default).
Class that consider the case of a translation vector.
Class that consider the case of the parameterization for the rotation.
void rad2deg()
Definition: vpColVector.h:176
void move(const char *filename)
void get_cMe(vpHomogeneousMatrix &cMe)
static const unsigned int njoint
Number of joint.
Definition: vpViper.h:144
vpHomogeneousMatrix get_fMc(const vpColVector &q)
Definition: vpViper.cpp:597
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:94
vpColVector joint_min
Definition: vpViper.h:162