ViSP  2.8.0
vpSimulatorAfma6.cpp
1 /****************************************************************************
2  *
3  * $Id: vpSimulatorAfma6.cpp 2595 2010-06-02 08:50:59Z nmelchio $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2013 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  * Class which provides a simulator for the robot Afma6.
36  *
37  * Authors:
38  * Nicolas Melchior
39  *
40  *****************************************************************************/
41 
42 
43 
44 #include <visp/vpConfig.h>
45 #if defined(WIN32) || defined(VISP_HAVE_PTHREAD)
46 #include <visp/vpSimulatorAfma6.h>
47 #include <visp/vpTime.h>
48 #include <visp/vpImagePoint.h>
49 #include <visp/vpPoint.h>
50 #include <visp/vpMeterPixelConversion.h>
51 #include <visp/vpRobotException.h>
52 #include <visp/vpIoTools.h>
53 #include <cmath> // std::fabs
54 #include <limits> // numeric_limits
55 #include <string>
57 
58 
63 {
64  init();
65  initDisplay();
66 
68 
69  #if defined(WIN32)
70  mutex_fMi = CreateMutex(NULL,FALSE,NULL);
71  mutex_artVel = CreateMutex(NULL,FALSE,NULL);
72  mutex_artCoord = CreateMutex(NULL,FALSE,NULL);
73  mutex_velocity = CreateMutex(NULL,FALSE,NULL);
74  mutex_display = CreateMutex(NULL,FALSE,NULL);
75 
76 
77  DWORD dwThreadIdArray;
78  hThread = CreateThread(
79  NULL, // default security attributes
80  0, // use default stack size
81  launcher, // thread function name
82  this, // argument to thread function
83  0, // use default creation flags
84  &dwThreadIdArray); // returns the thread identifier
85  #elif defined (VISP_HAVE_PTHREAD)
86  pthread_mutex_init(&mutex_fMi, NULL);
87  pthread_mutex_init(&mutex_artVel, NULL);
88  pthread_mutex_init(&mutex_artCoord, NULL);
89  pthread_mutex_init(&mutex_velocity, NULL);
90  pthread_mutex_init(&mutex_display, NULL);
91 
92  pthread_attr_init(&attr);
93  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
94 
95  pthread_create(&thread, NULL, launcher, (void *)this);
96  #endif
97 
98  compute_fMi();
99 }
100 
108 {
109  init();
110  initDisplay();
111 
113 
114  #if defined(WIN32)
115  mutex_fMi = CreateMutex(NULL,FALSE,NULL);
116  mutex_artVel = CreateMutex(NULL,FALSE,NULL);
117  mutex_artCoord = CreateMutex(NULL,FALSE,NULL);
118  mutex_velocity = CreateMutex(NULL,FALSE,NULL);
119  mutex_display = CreateMutex(NULL,FALSE,NULL);
120 
121 
122  DWORD dwThreadIdArray;
123  hThread = CreateThread(
124  NULL, // default security attributes
125  0, // use default stack size
126  launcher, // thread function name
127  this, // argument to thread function
128  0, // use default creation flags
129  &dwThreadIdArray); // returns the thread identifier
130  #elif defined(VISP_HAVE_PTHREAD)
131  pthread_mutex_init(&mutex_fMi, NULL);
132  pthread_mutex_init(&mutex_artVel, NULL);
133  pthread_mutex_init(&mutex_artCoord, NULL);
134  pthread_mutex_init(&mutex_velocity, NULL);
135  pthread_mutex_init(&mutex_display, NULL);
136 
137  pthread_attr_init(&attr);
138  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
139 
140  pthread_create(&thread, NULL, launcher, (void *)this);
141  #endif
142 
143  compute_fMi();
144 }
145 
150 {
151  robotStop = true;
152 
153  #if defined(WIN32)
154  WaitForSingleObject(hThread,INFINITE);
155  CloseHandle(hThread);
156  CloseHandle(mutex_fMi);
157  CloseHandle(mutex_artVel);
158  CloseHandle(mutex_artCoord);
159  CloseHandle(mutex_velocity);
160  CloseHandle(mutex_display);
161  #elif defined(VISP_HAVE_PTHREAD)
162  pthread_attr_destroy(&attr);
163  pthread_join(thread, NULL);
164  pthread_mutex_destroy(&mutex_fMi);
165  pthread_mutex_destroy(&mutex_artVel);
166  pthread_mutex_destroy(&mutex_artCoord);
167  pthread_mutex_destroy(&mutex_velocity);
168  pthread_mutex_destroy(&mutex_display);
169  #endif
170 
171  if (robotArms != NULL)
172  {
173  for(int i = 0; i < 6; i++)
174  free_Bound_scene (&(robotArms[i]));
175  }
176 
177  delete[] robotArms;
178  delete[] fMi;
179 }
180 
189 void
191 {
192  // set arm_dir from #define VISP_ROBOT_ARMS_DIR if it exists
193  if (vpIoTools::checkDirectory(VISP_ROBOT_ARMS_DIR) == true) // directory exists
194  arm_dir = VISP_ROBOT_ARMS_DIR;
195  else {
196  try {
197  arm_dir = vpIoTools::getenv("VISP_ROBOT_ARMS_DIR");
198  std::cout << "The simulator uses data from VISP_ROBOT_ARMS_DIR=" << arm_dir << std::endl;
199  }
200  catch (...) {
201  std::cout << "Cannot get VISP_ROBOT_ARMS_DIR environment variable" << std::endl;
202  }
203  }
204 
205  this->init(vpAfma6::TOOL_CCMOP);
206  toolCustom = false;
207 
208  size_fMi = 8;
209  fMi = new vpHomogeneousMatrix[8];
212 
213  zeroPos.resize(njoint);
214  zeroPos = 0;
215  reposPos.resize(njoint);
216  reposPos = 0;
217  reposPos[1] = -M_PI/2; reposPos[2] = M_PI; reposPos[4] = M_PI/2;
218 
219  artCoord = zeroPos;
220  artVel = 0;
221 
222  q_prev_getdis.resize(njoint);
223  q_prev_getdis = 0;
224  first_time_getdis = true;
225 
226  positioningVelocity = defaultPositioningVelocity ;
227 
230 
231  // Software joint limits in radians
232  //_joint_min.resize(njoint);
233  _joint_min[0] = -0.6501;
234  _joint_min[1] = -0.6001;
235  _joint_min[2] = -0.5001;
236  _joint_min[3] = -2.7301;
237  _joint_min[4] = -0.1001;
238  _joint_min[5] = -1.5901;
239  //_joint_max.resize(njoint);
240  _joint_max[0] = 0.7001;
241  _joint_max[1] = 0.5201;
242  _joint_max[2] = 0.4601;
243  _joint_max[3] = 2.7301;
244  _joint_max[4] = 2.4801;
245  _joint_max[5] = 1.5901;
246 }
247 
251 void
253 {
254  robotArms = NULL;
255  robotArms = new Bound_scene[6];
256  initArms();
258  cameraParam.initPersProjWithoutDistortion (558.5309599, 556.055053, 320, 240);
260  vpCameraParameters tmp;
261  getCameraParameters(tmp,640,480);
262  px_int = tmp.get_px();
263  py_int = tmp.get_py();
264  sceneInitialized = true;
265 }
266 
267 
283 void
286 {
287  this->projModel = projModel;
288 
289  // Use here default values of the robot constant parameters.
290  switch (tool) {
291  case vpAfma6::TOOL_CCMOP: {
292  _erc[0] = vpMath::rad(164.35); // rx
293  _erc[1] = vpMath::rad( 89.64); // ry
294  _erc[2] = vpMath::rad(-73.05); // rz
295  _etc[0] = 0.0117; // tx
296  _etc[1] = 0.0033; // ty
297  _etc[2] = 0.2272; // tz
298 
299  setCameraParameters(vpCameraParameters(1109.5735473989, 1112.1520168160, 320, 240));
300 
301  if (robotArms != NULL)
302  {
303  while (get_displayBusy()) vpTime::wait(2);
304  free_Bound_scene (&(robotArms[5]));
305  char name_arm[FILENAME_MAX];
306  strcpy(name_arm, arm_dir.c_str());
307  strcat(name_arm,"/afma6_tool_ccmop.bnd");
308  set_scene(name_arm, robotArms+5, 1.0);
309  set_displayBusy(false);
310  }
311  break;
312  }
313  case vpAfma6::TOOL_GRIPPER: {
314  _erc[0] = vpMath::rad( 88.33); // rx
315  _erc[1] = vpMath::rad( 72.07); // ry
316  _erc[2] = vpMath::rad( 2.53); // rz
317  _etc[0] = 0.0783; // tx
318  _etc[1] = 0.1234; // ty
319  _etc[2] = 0.1638; // tz
320 
321  setCameraParameters(vpCameraParameters(852.6583228197, 854.8084224761, 320, 240));
322 
323  if (robotArms != NULL)
324  {
325  while (get_displayBusy()) vpTime::wait(2);
326  free_Bound_scene (&(robotArms[5]));
327  char name_arm[FILENAME_MAX];
328  strcpy(name_arm, arm_dir.c_str());
329  strcat(name_arm,"/afma6_tool_gripper.bnd");
330  set_scene(name_arm, robotArms+5, 1.0);
331  set_displayBusy(false);
332  }
333  break;
334  }
335  case vpAfma6::TOOL_VACUUM: {
336  _erc[0] = vpMath::rad( 90.40); // rx
337  _erc[1] = vpMath::rad( 75.11); // ry
338  _erc[2] = vpMath::rad( 0.18); // rz
339  _etc[0] = 0.0038; // tx
340  _etc[1] = 0.1281; // ty
341  _etc[2] = 0.1658; // tz
342 
343  setCameraParameters(vpCameraParameters(853.4876600807, 856.0339170706, 320, 240));
344 
345  if (robotArms != NULL)
346  {
347  while (get_displayBusy()) vpTime::wait(2);
348  free_Bound_scene (&(robotArms[5]));
349  char name_arm[FILENAME_MAX];
350  strcpy(name_arm, arm_dir.c_str());
351  strcat(name_arm,"/afma6_tool_vacuum.bnd");
352  set_scene(name_arm, robotArms+5, 1.0);
353  set_displayBusy(false);
354  }
355  break;
356  }
358  std::cout << "The generic camera is not handled in vpSimulatorAfma6.cpp" << std::endl;
359  }
360  }
361 
362  vpRotationMatrix eRc(_erc);
363  this->_eMc.buildFrom(_etc, eRc);
364 
365  setToolType(tool);
366  return ;
367 }
368 
379 void
381  const unsigned int &image_width,
382  const unsigned int &image_height)
383 {
384  if (toolCustom)
385  {
386  vpCameraParameters(px_int,py_int,image_width/2,image_height/2);
387  }
388  // Set default parameters
389  switch (getToolType()) {
390  case vpAfma6::TOOL_CCMOP: {
391  // Set default intrinsic camera parameters for 640x480 images
392  if (image_width == 640 && image_height == 480)
393  {
394  std::cout << "Get default camera parameters for camera \""
395  << vpAfma6::CONST_CCMOP_CAMERA_NAME << "\"" << std::endl;
396  cam.initPersProjWithoutDistortion(1109.5735473989, 1112.1520168160, 320, 240);
397  }
398  else {
399  vpTRACE("Cannot get default intrinsic camera parameters for this image resolution");
400  }
401  break;
402  }
403  case vpAfma6::TOOL_GRIPPER: {
404  // Set default intrinsic camera parameters for 640x480 images
405  if (image_width == 640 && image_height == 480) {
406  std::cout << "Get default camera parameters for camera \""
407  << vpAfma6::CONST_GRIPPER_CAMERA_NAME << "\"" << std::endl;
408  cam.initPersProjWithoutDistortion(852.6583228197, 854.8084224761, 320, 240);
409  }
410  else {
411  vpTRACE("Cannot get default intrinsic camera parameters for this image resolution");
412  }
413  break;
414  }
415  case vpAfma6::TOOL_VACUUM: {
416  std::cout << "The generic camera is not handled in vpSimulatorAfma6.cpp" << std::endl;
417  break;
418  }
419  default:
420  vpERROR_TRACE ("This error should not occur!");
421  break;
422  }
423  return;
424 }
425 
434 void
436  const vpImage<unsigned char> &I)
437 {
439 }
440 
449 void
451  const vpImage<vpRGBa> &I)
452 {
454 }
455 
456 
462 void
464 {
465  px_int = cam.get_px();
466  py_int = cam.get_py();
467  toolCustom = true;
468 }
469 
470 
474 void
476 {
477  double tcur_1 = tcur;// temporary variable used to store the last time since the last command
478 
479  while (!robotStop)
480  {
481  //Get current time
482  tprev = tcur_1;
484 
486  setVelocityCalled = false;
487 
489 
490  double ellapsedTime = (tcur - tprev) * 1e-3;
491  if(constantSamplingTimeMode){//if we want a constant velocity, we force the ellapsed time to the given samplingTime
492  ellapsedTime = getSamplingTime(); // in second
493  }
494 
495  vpColVector articularCoordinates = get_artCoord();
496  articularCoordinates = get_artCoord();
497  vpColVector articularVelocities = get_artVel();
498 
499  if (jointLimit)
500  {
501  double art = articularCoordinates[jointLimitArt-1] + ellapsedTime*articularVelocities[jointLimitArt-1];
502  if (art <= _joint_min[jointLimitArt-1] || art >= _joint_max[jointLimitArt-1]) {
503  if (verbose_) {
504  std::cout << "Joint " << jointLimitArt-1
505  << " reaches a limit: " << vpMath::deg(_joint_min[jointLimitArt-1]) << " < "
506  << vpMath::deg(art) << " < " << vpMath::deg(_joint_max[jointLimitArt-1]) << std::endl;
507  }
508 
509  articularVelocities = 0.0;
510  }
511  else
512  jointLimit = false;
513  }
514 
515  articularCoordinates[0] = articularCoordinates[0] + ellapsedTime*articularVelocities[0];
516  articularCoordinates[1] = articularCoordinates[1] + ellapsedTime*articularVelocities[1];
517  articularCoordinates[2] = articularCoordinates[2] + ellapsedTime*articularVelocities[2];
518  articularCoordinates[3] = articularCoordinates[3] + ellapsedTime*articularVelocities[3];
519  articularCoordinates[4] = articularCoordinates[4] + ellapsedTime*articularVelocities[4];
520  articularCoordinates[5] = articularCoordinates[5] + ellapsedTime*articularVelocities[5];
521 
522  int jl = isInJointLimit();
523 
524  if (jl != 0 && jointLimit == false)
525  {
526  if (jl < 0)
527  ellapsedTime = (_joint_min[(unsigned int)(-jl-1)] - articularCoordinates[(unsigned int)(-jl-1)])/(articularVelocities[(unsigned int)(-jl-1)]);
528  else
529  ellapsedTime = (_joint_max[(unsigned int)(jl-1)] - articularCoordinates[(unsigned int)(jl-1)])/(articularVelocities[(unsigned int)(jl-1)]);
530 
531  for (unsigned int i = 0; i < 6; i++)
532  articularCoordinates[i] = articularCoordinates[i] + ellapsedTime*articularVelocities[i];
533 
534  jointLimit = true;
535  jointLimitArt = (unsigned int)fabs((double)jl);
536  }
537 
538  set_artCoord(articularCoordinates);
539  set_artVel(articularVelocities);
540 
541  compute_fMi();
542 
543  if (displayAllowed)
544  {
548  }
549 
551  {
552  while (get_displayBusy()) vpTime::wait(2);
554  set_displayBusy(false);
555  }
556 
557 
558  if (0/*displayType == MODEL_DH && displayAllowed*/)
559  {
560  vpHomogeneousMatrix fMit[8];
561  get_fMi(fMit);
562 
563  //vpDisplay::displayFrame(I,getExternalCameraPosition ()*fMi[6],cameraParam,0.2,vpColor::none);
564 
565  vpImagePoint iP, iP_1;
566  vpPoint pt;
567  pt.setWorldCoordinates (0,0,0);
568 
571  pt.track(getExternalCameraPosition ()*fMit[0]);
574  for (unsigned int k = 1; k < 7; k++)
575  {
576  pt.track(getExternalCameraPosition ()*fMit[k-1]);
578 
579  pt.track(getExternalCameraPosition ()*fMit[k]);
581 
583  }
585  }
586 
588 
589 
590  vpTime::wait( tcur, 1000*getSamplingTime() );
591  tcur_1 = tcur;
592  }else{
594  }
595  }
596 }
597 
605 void
607 {
608  //vpColVector q = get_artCoord();
609  vpColVector q(6);//; = get_artCoord();
610  q = get_artCoord();
611 
612  vpHomogeneousMatrix fMit[8];
613 
614  double q1 = q[0];
615  double q2 = q[1];
616  double q3 = q[2];
617  double q4 = q[3];
618  double q5 = q[4];
619  double q6 = q[5];
620 
621  double c4 = cos(q4);
622  double s4 = sin(q4);
623  double c5 = cos(q5);
624  double s5 = sin(q5);
625  double c6 = cos(q6);
626  double s6 = sin(q6);
627 
628  fMit[0][0][0] = 1;
629  fMit[0][1][0] = 0;
630  fMit[0][2][0] = 0;
631  fMit[0][0][1] = 0;
632  fMit[0][1][1] = 1;
633  fMit[0][2][1] = 0;
634  fMit[0][0][2] = 0;
635  fMit[0][1][2] = 0;
636  fMit[0][2][2] = 1;
637  fMit[0][0][3] = q1;
638  fMit[0][1][3] = 0;
639  fMit[0][2][3] = 0;
640 
641  fMit[1][0][0] = 1;
642  fMit[1][1][0] = 0;
643  fMit[1][2][0] = 0;
644  fMit[1][0][1] = 0;
645  fMit[1][1][1] = 1;
646  fMit[1][2][1] = 0;
647  fMit[1][0][2] = 0;
648  fMit[1][1][2] = 0;
649  fMit[1][2][2] = 1;
650  fMit[1][0][3] = q1;
651  fMit[1][1][3] = q2;
652  fMit[1][2][3] = 0;
653 
654  fMit[2][0][0] = 1;
655  fMit[2][1][0] = 0;
656  fMit[2][2][0] = 0;
657  fMit[2][0][1] = 0;
658  fMit[2][1][1] = 1;
659  fMit[2][2][1] = 0;
660  fMit[2][0][2] = 0;
661  fMit[2][1][2] = 0;
662  fMit[2][2][2] = 1;
663  fMit[2][0][3] = q1;
664  fMit[2][1][3] = q2;
665  fMit[2][2][3] = q3;
666 
667  fMit[3][0][0] = s4;
668  fMit[3][1][0] = -c4;
669  fMit[3][2][0] = 0;
670  fMit[3][0][1] = c4;
671  fMit[3][1][1] = s4;
672  fMit[3][2][1] = 0;
673  fMit[3][0][2] = 0;
674  fMit[3][1][2] = 0;
675  fMit[3][2][2] = 1;
676  fMit[3][0][3] = q1;
677  fMit[3][1][3] = q2;
678  fMit[3][2][3] = q3;
679 
680  fMit[4][0][0] = s4*s5;
681  fMit[4][1][0] = -c4*s5;
682  fMit[4][2][0] = c5;
683  fMit[4][0][1] = s4*c5;
684  fMit[4][1][1] = -c4*c5;
685  fMit[4][2][1] = -s5;
686  fMit[4][0][2] = c4;
687  fMit[4][1][2] = s4;
688  fMit[4][2][2] = 0;
689  fMit[4][0][3] = c4*this->_long_56+q1;
690  fMit[4][1][3] = s4*this->_long_56+q2;
691  fMit[4][2][3] = q3;
692 
693  fMit[5][0][0] = s4*s5*c6+c4*s6;
694  fMit[5][1][0] = -c4*s5*c6+s4*s6;
695  fMit[5][2][0] = c5*c6;
696  fMit[5][0][1] = -s4*s5*s6+c4*c6;
697  fMit[5][1][1] = c4*s5*s6+s4*c6;
698  fMit[5][2][1] = -c5*s6;
699  fMit[5][0][2] = -s4*c5;
700  fMit[5][1][2] = c4*c5;
701  fMit[5][2][2] = s5;
702  fMit[5][0][3] = c4*this->_long_56+q1;
703  fMit[5][1][3] = s4*this->_long_56+q2;
704  fMit[5][2][3] = q3;
705 
706  fMit[6][0][0] = fMit[5][0][0];
707  fMit[6][1][0] = fMit[5][1][0];
708  fMit[6][2][0] = fMit[5][2][0];
709  fMit[6][0][1] = fMit[5][0][1];
710  fMit[6][1][1] = fMit[5][1][1];
711  fMit[6][2][1] = fMit[5][2][1];
712  fMit[6][0][2] = fMit[5][0][2];
713  fMit[6][1][2] = fMit[5][1][2];
714  fMit[6][2][2] = fMit[5][2][2];
715  fMit[6][0][3] = fMit[5][0][3];
716  fMit[6][1][3] = fMit[5][1][3];
717  fMit[6][2][3] = fMit[5][2][3];
718 
719 // vpHomogeneousMatrix cMe;
720 // get_cMe(cMe);
721 // cMe = cMe.inverse();
722 // fMit[7] = fMit[6] * cMe;
723  vpAfma6::get_fMc(q,fMit[7]);
724 
725  #if defined(WIN32)
726  WaitForSingleObject(mutex_fMi,INFINITE);
727  for (int i = 0; i < 8; i++)
728  fMi[i] = fMit[i];
729  ReleaseMutex(mutex_fMi);
730  #elif defined(VISP_HAVE_PTHREAD)
731  pthread_mutex_lock (&mutex_fMi);
732  for (int i = 0; i < 8; i++)
733  fMi[i] = fMit[i];
734  pthread_mutex_unlock (&mutex_fMi);
735  #endif
736 }
737 
738 
746 {
747  switch (newState) {
748  case vpRobot::STATE_STOP: {
749  // Start primitive STOP only if the current state is Velocity
751  stopMotion();
752  }
753  break;
754  }
757  std::cout << "Change the control mode from velocity to position control.\n";
758  stopMotion();
759  }
760  else {
761  //std::cout << "Change the control mode from stop to position control.\n";
762  }
763  break;
764  }
767  std::cout << "Change the control mode from stop to velocity control.\n";
768  }
769  break;
770  }
772  default:
773  break ;
774  }
775 
776  return vpRobot::setRobotState (newState);
777 }
778 
848 void
850 {
852  vpERROR_TRACE ("Cannot send a velocity to the robot "
853  "use setRobotState(vpRobot::STATE_VELOCITY_CONTROL) first) ");
855  "Cannot send a velocity to the robot "
856  "use setRobotState(vpRobot::STATE_VELOCITY_CONTROL) first) ");
857  }
858 
859  vpColVector vel_sat(6);
860 
861  double scale_trans_sat = 1;
862  double scale_rot_sat = 1;
863  double scale_sat = 1;
864  double vel_trans_max = getMaxTranslationVelocity();
865  double vel_rot_max = getMaxRotationVelocity();
866 
867  double vel_abs; // Absolute value
868 
869  // Velocity saturation
870  switch(frame)
871  {
872  // saturation in cartesian space
873  case vpRobot::CAMERA_FRAME :
875  {
876  if (vel.getRows() != 6)
877  {
878  vpERROR_TRACE ("The velocity vector must have a size of 6 !!!!");
879  throw;
880  }
881 
882  for (unsigned int i = 0 ; i < 3; ++ i)
883  {
884  vel_abs = fabs (vel[i]);
885  if (vel_abs > vel_trans_max && !jointLimit)
886  {
887  vel_trans_max = vel_abs;
888  vpERROR_TRACE ("Excess velocity %g m/s in TRANSLATION "
889  "(axis nr. %d).", vel[i], i+1);
890  }
891 
892  vel_abs = fabs (vel[i+3]);
893  if (vel_abs > vel_rot_max && !jointLimit) {
894  vel_rot_max = vel_abs;
895  vpERROR_TRACE ("Excess velocity %g rad/s in ROTATION "
896  "(axis nr. %d).", vel[i+3], i+4);
897  }
898  }
899 
900  if (vel_trans_max > getMaxTranslationVelocity())
901  scale_trans_sat = getMaxTranslationVelocity() / vel_trans_max;
902 
903  if (vel_rot_max > getMaxRotationVelocity())
904  scale_rot_sat = getMaxRotationVelocity() / vel_rot_max;
905 
906  if ( (scale_trans_sat < 1) || (scale_rot_sat < 1) )
907  {
908  if (scale_trans_sat < scale_rot_sat)
909  scale_sat = scale_trans_sat;
910  else
911  scale_sat = scale_rot_sat;
912  }
913  break;
914  }
915 
916  // saturation in joint space
918  {
919  if (vel.getRows() != 6)
920  {
921  vpERROR_TRACE ("The velocity vector must have a size of 6 !!!!");
922  throw;
923  }
924  for (unsigned int i = 0 ; i < 6; ++ i)
925  {
926  vel_abs = fabs (vel[i]);
927  if (vel_abs > vel_rot_max && !jointLimit)
928  {
929  vel_rot_max = vel_abs;
930  vpERROR_TRACE ("Excess velocity %g rad/s in ROTATION "
931  "(axis nr. %d).", vel[i], i+1);
932  }
933  }
934  if (vel_rot_max > getMaxRotationVelocity())
935  scale_rot_sat = getMaxRotationVelocity() / vel_rot_max;
936  if ( scale_rot_sat < 1 )
937  scale_sat = scale_rot_sat;
938  break;
939  }
940  case vpRobot::MIXT_FRAME :
941  {
942  break;
943  }
944  }
945 
946  set_velocity (vel * scale_sat);
947  setRobotFrame (frame);
948  setVelocityCalled = true;
949 }
950 
951 
955 void
957 {
959 
960  double scale_rot_sat = 1;
961  double scale_sat = 1;
962  double vel_rot_max = getMaxRotationVelocity();
963  double vel_abs;
964 
965  vpColVector articularCoordinates = get_artCoord();
966  vpColVector velocityframe = get_velocity();
967  vpColVector articularVelocity;
968 
969  switch(frame)
970  {
971  case vpRobot::CAMERA_FRAME :
972  {
973  vpMatrix eJe;
975  vpAfma6::get_eJe(articularCoordinates,eJe);
976  eJe = eJe.pseudoInverse();
978  singularityTest(articularCoordinates,eJe);
979  articularVelocity = eJe*eVc*velocityframe;
980  set_artVel (articularVelocity);
981  break;
982  }
984  {
985  vpMatrix fJe;
986  vpAfma6::get_fJe(articularCoordinates,fJe);
987  fJe = fJe.pseudoInverse();
989  singularityTest(articularCoordinates,fJe);
990  articularVelocity = fJe*velocityframe;
991  set_artVel (articularVelocity);
992  break;
993  }
995  {
996  articularVelocity = velocityframe;
997  set_artVel (articularVelocity);
998  break;
999  }
1000  case vpRobot::MIXT_FRAME :
1001  {
1002  break;
1003  }
1004  }
1005 
1006 
1007 
1008  switch(frame)
1009  {
1010  case vpRobot::CAMERA_FRAME :
1012  {
1013  for (unsigned int i = 0 ; i < 6; ++ i)
1014  {
1015  vel_abs = fabs (articularVelocity[i]);
1016  if (vel_abs > vel_rot_max && !jointLimit)
1017  {
1018  vel_rot_max = vel_abs;
1019  vpERROR_TRACE ("Excess velocity %g rad/s in ROTATION "
1020  "(axis nr. %d).", articularVelocity[i], i+1);
1021  }
1022  }
1023  if (vel_rot_max > getMaxRotationVelocity())
1024  scale_rot_sat = getMaxRotationVelocity() / vel_rot_max;
1025  if ( scale_rot_sat < 1 )
1026  scale_sat = scale_rot_sat;
1027 
1028  set_artVel(articularVelocity * scale_sat);
1029  break;
1030  }
1032  case vpRobot::MIXT_FRAME :
1033  {
1034  break;
1035  }
1036  }
1037 }
1038 
1039 
1086 void
1088 {
1089  vel.resize(6);
1090 
1091  vpColVector articularCoordinates = get_artCoord();
1092  vpColVector articularVelocity = get_artVel();
1093 
1094  switch(frame)
1095  {
1096  case vpRobot::CAMERA_FRAME :
1097  {
1098  vpMatrix eJe;
1100  vpAfma6::get_eJe(articularCoordinates,eJe);
1101  vel = cVe*eJe*articularVelocity;
1102  break ;
1103  }
1104  case vpRobot::ARTICULAR_FRAME :
1105  {
1106  vel = articularVelocity;
1107  break ;
1108  }
1109  case vpRobot::REFERENCE_FRAME :
1110  {
1111  vpMatrix fJe;
1112  vpAfma6::get_fJe(articularCoordinates,fJe);
1113  vel = fJe*articularVelocity;
1114  break ;
1115  }
1116  case vpRobot::MIXT_FRAME :
1117  {
1118  break ;
1119  }
1120  default:
1121  {
1122  vpERROR_TRACE ("Error in spec of vpRobot. "
1123  "Case not taken in account.");
1124  return;
1125  }
1126  }
1127 }
1128 
1173 {
1174  vpColVector velocity(6);
1175  getVelocity (frame, velocity);
1176 
1177  return velocity;
1178 }
1179 
1180 
1181 void
1183 {
1184  double vel_rot_max = getMaxRotationVelocity();
1185  double velmax = fabs(q[0]);
1186  for (unsigned int i = 1; i < 6; i++)
1187  {
1188  if (velmax < fabs(q[i]))
1189  velmax = fabs(q[i]);
1190  }
1191 
1192  double alpha = (getPositioningVelocity() * vel_rot_max) / (velmax*100);
1193  q = q * alpha;
1194 }
1195 
1270 void
1272 {
1274  {
1275  vpERROR_TRACE ("Robot was not in position-based control\n"
1276  "Modification of the robot state");
1277  // setRobotState(vpRobot::STATE_POSITION_CONTROL) ;
1278  }
1279 
1280  vpColVector articularCoordinates = get_artCoord();
1281 
1282  vpColVector error(6);
1283  double errsqr = 0;
1284  switch(frame)
1285  {
1286  case vpRobot::CAMERA_FRAME :
1287  {
1288  int nbSol;
1289  vpColVector qdes(6);
1290 
1291  vpTranslationVector txyz;
1292  vpRxyzVector rxyz;
1293  for (unsigned int i=0; i < 3; i++)
1294  {
1295  txyz[i] = q[i];
1296  rxyz[i] = q[i+3];
1297  }
1298 
1299  vpRotationMatrix cRc2(rxyz);
1300  vpHomogeneousMatrix cMc2(txyz, cRc2);
1301 
1303  vpAfma6::get_fMc(articularCoordinates, fMc);
1304 
1305  vpHomogeneousMatrix fMc2 = fMc * cMc2;
1306 
1307  do
1308  {
1309  articularCoordinates = get_artCoord();
1310  qdes = articularCoordinates;
1311  nbSol = getInverseKinematics(fMc2, qdes, true, verbose_);
1312  setVelocityCalled = true;
1313  if (nbSol > 0)
1314  {
1315  error = qdes - articularCoordinates;
1316  errsqr = error.sumSquare();
1317  //findHighestPositioningSpeed(error);
1318  set_artVel(error);
1319  if (errsqr < 1e-4)
1320  {
1321  set_artCoord (qdes);
1322  error = 0;
1323  set_artVel(error);
1324  set_velocity(error);
1325  break;
1326  }
1327  }
1328  else
1329  {
1330  vpERROR_TRACE ("Positionning error.");
1332  "Position out of range.");
1333  }
1334  }while (errsqr > 1e-8 && nbSol > 0);
1335 
1336  break ;
1337  }
1338 
1340  {
1341  do
1342  {
1343  articularCoordinates = get_artCoord();
1344  error = q - articularCoordinates;
1345  errsqr = error.sumSquare();
1346  //findHighestPositioningSpeed(error);
1347  set_artVel(error);
1348  setVelocityCalled = true;
1349  if (errsqr < 1e-4)
1350  {
1351  set_artCoord (q);
1352  error = 0;
1353  set_artVel(error);
1354  set_velocity(error);
1355  break;
1356  }
1357  }while (errsqr > 1e-8);
1358  break ;
1359  }
1360 
1362  {
1363  int nbSol;
1364  vpColVector qdes(6);
1365 
1366  vpTranslationVector txyz;
1367  vpRxyzVector rxyz;
1368  for (unsigned int i=0; i < 3; i++)
1369  {
1370  txyz[i] = q[i];
1371  rxyz[i] = q[i+3];
1372  }
1373 
1374  vpRotationMatrix fRc(rxyz);
1375  vpHomogeneousMatrix fMc(txyz, fRc);
1376 
1377  do
1378  {
1379  articularCoordinates = get_artCoord();
1380  qdes = articularCoordinates;
1381  nbSol = getInverseKinematics(fMc, qdes, true, verbose_);
1382  setVelocityCalled = true;
1383  if (nbSol > 0)
1384  {
1385  error = qdes - articularCoordinates;
1386  errsqr = error.sumSquare();
1387  //findHighestPositioningSpeed(error);
1388  set_artVel(error);
1389  if (errsqr < 1e-4)
1390  {
1391  set_artCoord (qdes);
1392  error = 0;
1393  set_artVel(error);
1394  set_velocity(error);
1395  break;
1396  }
1397  }
1398  else
1399  vpERROR_TRACE ("Positionning error. Position unreachable");
1400  }while (errsqr > 1e-8 && nbSol > 0);
1401  break ;
1402  }
1403  case vpRobot::MIXT_FRAME:
1404  {
1405  vpERROR_TRACE ("Positionning error. Mixt frame not implemented");
1407  "Positionning error: "
1408  "Mixt frame not implemented.");
1409  break ;
1410  }
1411  }
1412 }
1413 
1478  const double pos1,
1479  const double pos2,
1480  const double pos3,
1481  const double pos4,
1482  const double pos5,
1483  const double pos6)
1484 {
1485  try{
1486  vpColVector position(6) ;
1487  position[0] = pos1 ;
1488  position[1] = pos2 ;
1489  position[2] = pos3 ;
1490  position[3] = pos4 ;
1491  position[4] = pos5 ;
1492  position[5] = pos6 ;
1493 
1494  setPosition(frame, position) ;
1495  }
1496  catch(...)
1497  {
1498  vpERROR_TRACE("Error caught");
1499  throw ;
1500  }
1501 }
1502 
1538 void vpSimulatorAfma6::setPosition(const char *filename)
1539 {
1540  vpColVector q;
1541  bool ret;
1542 
1543  ret = this->readPosFile(filename, q);
1544 
1545  if (ret == false) {
1546  vpERROR_TRACE ("Bad position in \"%s\"", filename);
1548  "Bad position in filename.");
1549  }
1552 }
1553 
1613 void
1615 {
1616  q.resize(6);
1617 
1618  switch(frame)
1619  {
1620  case vpRobot::CAMERA_FRAME :
1621  {
1622  q = 0;
1623  break ;
1624  }
1625 
1627  {
1628  q = get_artCoord();
1629  break ;
1630  }
1631 
1633  {
1635  vpAfma6::get_fMc (get_artCoord(), fMc);
1636 
1637  vpRotationMatrix fRc;
1638  fMc.extract(fRc);
1639  vpRxyzVector rxyz(fRc);
1640 
1641  vpTranslationVector txyz;
1642  fMc.extract(txyz);
1643 
1644  for (unsigned int i=0; i <3; i++)
1645  {
1646  q[i] = txyz[i];
1647  q[i+3] = rxyz[i];
1648  }
1649  break ;
1650  }
1651 
1652  case vpRobot::MIXT_FRAME:
1653  {
1654  vpERROR_TRACE ("Positionning error. Mixt frame not implemented");
1656  "Positionning error: "
1657  "Mixt frame not implemented.");
1658  break ;
1659  }
1660  }
1661 }
1662 
1663 
1674 void
1676  vpPoseVector &position)
1677 {
1678  vpColVector posRxyz;
1679  //recupere position en Rxyz
1680  this->getPosition(frame,posRxyz);
1681 
1682  //recupere le vecteur thetaU correspondant
1683  vpThetaUVector RtuVect(posRxyz[3],posRxyz[4],posRxyz[5]);
1684 
1685  //remplit le vpPoseVector avec translation et rotation ThetaU
1686  for(unsigned int j=0;j<3;j++)
1687  {
1688  position[j]=posRxyz[j];
1689  position[j+3]=RtuVect[j];
1690  }
1691 }
1692 
1699 void
1701 {
1702  if (limitMin.getRows() != 6 || limitMax.getRows() != 6)
1703  {
1704  vpTRACE("Joint limit vector has not a size of 6 !");
1705  return;
1706  }
1707 
1708  _joint_min[0] = limitMin[0];
1709  _joint_min[1] = limitMin[1];
1710  _joint_min[2] = limitMin[2];
1711  _joint_min[3] = limitMin[3];
1712  _joint_min[4] = limitMin[4];
1713  _joint_min[5] = limitMin[5];
1714 
1715  _joint_max[0] = limitMax[0];
1716  _joint_max[1] = limitMax[1];
1717  _joint_max[2] = limitMax[2];
1718  _joint_max[3] = limitMax[3];
1719  _joint_max[4] = limitMax[4];
1720  _joint_max[5] = limitMax[5];
1721 
1722 }
1723 
1729 bool
1731 {
1732  double q5 = q[4];
1733 
1734  bool cond = fabs(q5-M_PI/2) < 1e-1;
1735 
1736  if(cond)
1737  {
1738  J[0][3] = 0;
1739  J[0][4] = 0;
1740  J[1][3] = 0;
1741  J[1][4] = 0;
1742  J[3][3] = 0;
1743  J[3][4] = 0;
1744  J[5][3] = 0;
1745  J[5][4] = 0;
1746  return true;
1747  }
1748 
1749  return false;
1750 }
1751 
1755 int
1757 {
1758  int artNumb = 0;
1759  double diff = 0;
1760  double difft = 0;
1761 
1762  vpColVector articularCoordinates = get_artCoord();
1763 
1764  for (unsigned int i = 0; i < 6; i++)
1765  {
1766  if (articularCoordinates[i] <= _joint_min[i])
1767  {
1768  difft = _joint_min[i] - articularCoordinates[i];
1769  if (difft > diff)
1770  {
1771  diff = difft;
1772  artNumb = -(int)i-1;
1773  }
1774  }
1775  }
1776 
1777  for (unsigned int i = 0; i < 6; i++)
1778  {
1779  if (articularCoordinates[i] >= _joint_max[i])
1780  {
1781  difft = articularCoordinates[i] - _joint_max[i];
1782  if (difft > diff)
1783  {
1784  diff = difft;
1785  artNumb = (int)(i+1);
1786  }
1787  }
1788  }
1789 
1790  if (artNumb != 0)
1791  std::cout << "\nWarning: Velocity control stopped: axis " << fabs((float)artNumb) << " on joint limit!" <<std::endl;
1792 
1793  return artNumb;
1794 }
1795 
1807 void
1808 vpSimulatorAfma6::getCameraDisplacement(vpColVector &displacement)
1809 {
1810  getDisplacement(vpRobot::CAMERA_FRAME, displacement);
1811 }
1812 
1822 void
1823 vpSimulatorAfma6::getArticularDisplacement(vpColVector &displacement)
1824 {
1826 }
1827 
1846 void
1848  vpColVector &displacement)
1849 {
1850  displacement.resize (6);
1851  displacement = 0;
1852  vpColVector q_cur(6);
1853 
1854  q_cur = get_artCoord();
1855 
1856  if ( ! first_time_getdis )
1857  {
1858  switch (frame)
1859  {
1860  case vpRobot::CAMERA_FRAME:
1861  {
1862  std::cout << "getDisplacement() CAMERA_FRAME not implemented\n";
1863  return;
1864  break ;
1865  }
1866 
1868  {
1869  displacement = q_cur - q_prev_getdis;
1870  break ;
1871  }
1872 
1874  {
1875  std::cout << "getDisplacement() REFERENCE_FRAME not implemented\n";
1876  return;
1877  break ;
1878  }
1879 
1880  case vpRobot::MIXT_FRAME:
1881  {
1882  std::cout << "getDisplacement() MIXT_FRAME not implemented\n";
1883  return;
1884  break ;
1885  }
1886  }
1887  }
1888  else
1889  {
1890  first_time_getdis = false;
1891  }
1892 
1893  // Memorize the joint position for the next call
1894  q_prev_getdis = q_cur;
1895 }
1896 
1943 bool
1945 {
1946 
1947  FILE * fd ;
1948  fd = fopen(filename, "r") ;
1949  if (fd == NULL)
1950  return false;
1951 
1952  char line[FILENAME_MAX];
1953  char dummy[FILENAME_MAX];
1954  char head[] = "R:";
1955  bool sortie = false;
1956 
1957  do {
1958  // Saut des lignes commencant par #
1959  if (fgets (line, FILENAME_MAX, fd) != NULL) {
1960  if ( strncmp (line, "#", 1) != 0) {
1961  // La ligne n'est pas un commentaire
1962  if ( strncmp (line, head, sizeof(head)-1) == 0) {
1963  sortie = true; // Position robot trouvee.
1964  }
1965 // else
1966 // return (false); // fin fichier sans position robot.
1967  }
1968  }
1969  else {
1970  return (false); /* fin fichier */
1971  }
1972 
1973  }
1974  while ( sortie != true );
1975 
1976  // Lecture des positions
1977  q.resize(njoint);
1978  sscanf(line, "%s %lf %lf %lf %lf %lf %lf",
1979  dummy,
1980  &q[0], &q[1], &q[2],
1981  &q[3], &q[4], &q[5]);
1982 
1983  // converts rotations from degrees into radians
1984  //q.deg2rad();
1985 
1986  q[3] = vpMath::rad(q[3]);
1987  q[4] = vpMath::rad(q[4]);
1988  q[5] = vpMath::rad(q[5]);
1989 
1990  fclose(fd) ;
1991  return (true);
1992 }
1993 
2016 bool
2017 vpSimulatorAfma6::savePosFile(const char *filename, const vpColVector &q)
2018 {
2019 
2020  FILE * fd ;
2021  fd = fopen(filename, "w") ;
2022  if (fd == NULL)
2023  return false;
2024 
2025  fprintf(fd, "\
2026 #AFMA6 - Position - Version 2.01\n\
2027 #\n\
2028 # R: X Y Z A B C\n\
2029 # Joint position: X, Y, Z: translations in meters\n\
2030 # A, B, C: rotations in degrees\n\
2031 #\n\
2032 #\n\n");
2033 
2034  // Save positions in mm and deg
2035  fprintf(fd, "R: %lf %lf %lf %lf %lf %lf\n",
2036  q[0],
2037  q[1],
2038  q[2],
2039  vpMath::deg(q[3]),
2040  vpMath::deg(q[4]),
2041  vpMath::deg(q[5]));
2042 
2043  fclose(fd) ;
2044  return (true);
2045 }
2046 
2054 void
2055 vpSimulatorAfma6::move(const char *filename)
2056 {
2057  vpColVector q;
2058 
2059  try
2060  {
2061  this->readPosFile(filename, q);
2064  }
2065  catch(...)
2066  {
2067  throw;
2068  }
2069 }
2070 
2080 void
2082 {
2083  vpAfma6::get_cMe(cMe) ;
2084 }
2085 
2093 void
2095 {
2096  vpHomogeneousMatrix cMe ;
2097  vpAfma6::get_cMe(cMe) ;
2098 
2099  cVe.buildFrom(cMe) ;
2100 }
2101 
2111 void
2113 {
2114  try
2115  {
2116  vpAfma6::get_eJe(get_artCoord(), eJe) ;
2117  }
2118  catch(...)
2119  {
2120  vpERROR_TRACE("catch exception ") ;
2121  throw ;
2122  }
2123 }
2124 
2135 void
2137 {
2138  try
2139  {
2140  vpColVector articularCoordinates = get_artCoord();
2141  vpAfma6::get_fJe(articularCoordinates, fJe) ;
2142  }
2143  catch(...)
2144  {
2145  vpERROR_TRACE("Error caught");
2146  throw ;
2147  }
2148 }
2149 
2153 void
2155 {
2157  return;
2158 
2159  vpColVector stop(6);
2160  stop = 0;
2161  set_artVel(stop);
2162  set_velocity(stop);
2164 }
2165 
2166 
2167 
2168 /**********************************************************************************/
2169 /**********************************************************************************/
2170 /**********************************************************************************/
2171 /**********************************************************************************/
2172 
2181 void
2183 {
2184  // set scene_dir from #define VISP_SCENE_DIR if it exists
2185  std::string scene_dir;
2186  if (vpIoTools::checkDirectory(VISP_SCENES_DIR) == true) // directory exists
2187  scene_dir = VISP_SCENES_DIR;
2188  else {
2189  try {
2190  scene_dir = vpIoTools::getenv("VISP_SCENES_DIR");
2191  std::cout << "The simulator uses data from VISP_SCENES_DIR=" << scene_dir << std::endl;
2192  }
2193  catch (...) {
2194  std::cout << "Cannot get VISP_SCENES_DIR environment variable" << std::endl;
2195  }
2196  }
2197 
2198  char name_cam[FILENAME_MAX];
2199 
2200  strcpy(name_cam, scene_dir.c_str());
2201  strcat(name_cam,"/camera.bnd");
2202  set_scene(name_cam,&camera,cameraFactor);
2203 
2204  char name_arm[FILENAME_MAX];
2205  strcpy(name_arm, arm_dir.c_str());
2206  strcat(name_arm,"/afma6_gate.bnd");
2207  set_scene(name_arm, robotArms, 1.0);
2208  strcpy(name_arm, arm_dir.c_str());
2209  strcat(name_arm,"/afma6_arm1.bnd");
2210  set_scene(name_arm, robotArms+1, 1.0);
2211  strcpy(name_arm, arm_dir.c_str());
2212  strcat(name_arm,"/afma6_arm2.bnd");
2213  set_scene(name_arm, robotArms+2, 1.0);
2214  strcpy(name_arm, arm_dir.c_str());
2215  strcat(name_arm,"/afma6_arm3.bnd");
2216  set_scene(name_arm, robotArms+3, 1.0);
2217  strcpy(name_arm, arm_dir.c_str());
2218  strcat(name_arm,"/afma6_arm4.bnd");
2219  set_scene(name_arm, robotArms+4, 1.0);
2220 
2222  tool = getToolType();
2223  strcpy(name_arm, arm_dir.c_str());
2224  switch (tool) {
2225  case vpAfma6::TOOL_CCMOP: {
2226  strcat(name_arm,"/afma6_tool_ccmop.bnd");
2227  break;
2228  }
2229  case vpAfma6::TOOL_GRIPPER: {
2230  strcat(name_arm,"/afma6_tool_gripper.bnd");
2231  break;
2232  }
2233  case vpAfma6::TOOL_VACUUM: {
2234  strcat(name_arm,"/afma6_tool_vacuum.bnd");
2235  break;
2236  }
2238  std::cout << "The generic camera is not handled in vpSimulatorAfma6.cpp" << std::endl;
2239  break;
2240  }
2241  }
2242  set_scene(name_arm, robotArms+5, 1.0);
2243 
2244  add_rfstack(IS_BACK);
2245 
2246  add_vwstack ("start","depth", 0.0, 100.0);
2247  add_vwstack ("start","window", -0.1,0.1,-0.1,0.1);
2248  add_vwstack ("start","type", PERSPECTIVE);
2249 //
2250 // sceneInitialized = true;
2251 // displayObject = true;
2252  displayCamera = true;
2253 }
2254 
2255 
2256 void
2258 {
2259  bool changed = false;
2260  vpHomogeneousMatrix displacement = navigation(I,changed);
2261 
2262  //if (displacement[2][3] != 0)
2263  if (std::fabs(displacement[2][3]) > std::numeric_limits<double>::epsilon())
2264  camMf2 = camMf2*displacement;
2265 
2266  f2Mf = camMf2.inverse()*camMf;
2267 
2268  camMf = camMf2* displacement * f2Mf;
2269 
2270  double u;
2271  double v;
2272  //if(px_ext != 1 && py_ext != 1)
2273  // we assume px_ext and py_ext > 0
2274  if( (std::fabs(px_ext-1.) > vpMath::maximum(px_ext,1.)*std::numeric_limits<double>::epsilon())
2275  && (std::fabs(py_ext-1) > vpMath::maximum(py_ext,1.)*std::numeric_limits<double>::epsilon()))
2276  {
2277  u = (double)I.getWidth()/(2*px_ext);
2278  v = (double)I.getHeight()/(2*py_ext);
2279  }
2280  else
2281  {
2282  u = (double)I.getWidth()/(vpMath::minimum(I.getWidth(),I.getHeight()));
2283  v = (double)I.getHeight()/(vpMath::minimum(I.getWidth(),I.getHeight()));
2284  }
2285 
2286  float w44o[4][4],w44cext[4][4],x,y,z;
2287 
2288  vp2jlc_matrix(camMf.inverse(),w44cext);
2289 
2290  add_vwstack ("start","cop", w44cext[3][0],w44cext[3][1],w44cext[3][2]);
2291  x = w44cext[2][0] + w44cext[3][0];
2292  y = w44cext[2][1] + w44cext[3][1];
2293  z = w44cext[2][2] + w44cext[3][2];
2294  add_vwstack ("start","vrp", x,y,z);
2295  add_vwstack ("start","vpn", w44cext[2][0],w44cext[2][1],w44cext[2][2]);
2296  add_vwstack ("start","vup", w44cext[1][0],w44cext[1][1],w44cext[1][2]);
2297  add_vwstack ("start","window", -u, u, -v, v);
2298 
2299  vpHomogeneousMatrix fMit[8];
2300  get_fMi(fMit);
2301 
2302  vp2jlc_matrix(vpHomogeneousMatrix(0,0,0,0,0,0),w44o);
2303  display_scene(w44o,robotArms[0],I, curColor);
2304 
2305  vp2jlc_matrix(fMit[0],w44o);
2306  display_scene(w44o,robotArms[1],I, curColor);
2307 
2308  vp2jlc_matrix(fMit[2],w44o);
2309  display_scene(w44o,robotArms[2],I, curColor);
2310 
2311  vp2jlc_matrix(fMit[3],w44o);
2312  display_scene(w44o,robotArms[3],I, curColor);
2313 
2314  vp2jlc_matrix(fMit[4],w44o);
2315  display_scene(w44o,robotArms[4],I, curColor);
2316 
2317  vp2jlc_matrix(fMit[5],w44o);
2318  display_scene(w44o,robotArms[5],I, curColor);
2319 
2320  if (displayCamera)
2321  {
2322  vpHomogeneousMatrix cMe;
2323  get_cMe(cMe);
2324  cMe = cMe.inverse();
2325  cMe = fMit[6] * cMe;
2326  vp2jlc_matrix(cMe,w44o);
2327  display_scene(w44o,camera, I, camColor);
2328  }
2329 
2330  if (displayObject)
2331  {
2332  vp2jlc_matrix(fMo,w44o);
2333  display_scene(w44o,scene,I, curColor);
2334  }
2335 }
2336 
2353 bool
2355 {
2356  vpColVector stop(6);
2357  bool status = true;
2358  stop = 0;
2359  set_artVel(stop);
2360  set_velocity(stop);
2362  fMc = fMo * cMo.inverse();
2363 
2364  vpColVector articularCoordinates = get_artCoord();
2365  int nbSol = getInverseKinematics(fMc, articularCoordinates, true, verbose_);
2366 
2367  if (nbSol == 0) {
2368  status = false;
2369  vpERROR_TRACE ("Positionning error. Position unreachable");
2370  }
2371 
2372  if (verbose_)
2373  std::cout << "Used joint coordinates (rad): " << articularCoordinates.t() << std::endl;
2374 
2375  set_artCoord(articularCoordinates);
2376 
2377  compute_fMi();
2378 
2379  return status;
2380 }
2381 
2394 void
2396 {
2397  vpColVector stop(6);
2398  stop = 0;
2399  set_artVel(stop);
2400  set_velocity(stop);
2401  vpHomogeneousMatrix fMit[8];
2402  get_fMi(fMit);
2403  fMo = fMit[7] * cMo;
2404 }
2405 
2416 bool
2418 {
2419  // get rid of max velocity
2420  double vMax = getMaxTranslationVelocity();
2421  double wMax = getMaxRotationVelocity();
2422  setMaxTranslationVelocity(10.*vMax);
2423  setMaxRotationVelocity(10.*wMax);
2424 
2425  vpColVector v(3),w(3),vel(6);
2426  vpHomogeneousMatrix cdMc;
2428  vpColVector err(6);err=1.;
2429  const double lambda = 5.;
2430  double t;
2431 
2433  vpMatrix eJe;
2434 
2435  unsigned int i,iter=0;
2436  while((iter++<300) & (err.euclideanNorm()>errMax))
2437  {
2438  t = vpTime::measureTimeMs();
2439 
2440  // update image
2441  if(Iint != NULL)
2442  {
2443  vpDisplay::display(*Iint);
2444  getInternalView(*Iint);
2445  vpDisplay::flush(*Iint);
2446  }
2447 
2448  // update pose error
2449  cdMc = cdMo*get_cMo().inverse();
2450  cdMc.extract(cdRc);
2451  cdMc.extract(cdTc);
2452  cdTUc.buildFrom(cdRc);
2453 
2454  // compute v,w and velocity
2455  v = -lambda*cdRc.t()*cdTc;
2456  w = -lambda*cdTUc;
2457  for(i=0;i<3;++i)
2458  {
2459  vel[i] = v[i];
2460  vel[i+3] = w[i];
2461  err[i] = cdTc[i];
2462  err[i+3] = cdTUc[i];
2463  }
2464 
2465  // update feat
2467 
2468  // wait for it
2469  vpTime::wait(t,10);
2470  }
2471  vel=0.;
2472  set_velocity(vel);
2473  set_artVel(vel);
2475  setMaxRotationVelocity(wMax);
2476 
2477  //std::cout << "setPosition: final error " << err.t() << std::endl;
2478  return(err.euclideanNorm()<= errMax);
2479 }
2480 
2481 #endif
static void displayCamera(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double size, const vpColor &color, unsigned int thickness)
Definition: vpDisplay.cpp:506
Modelisation of Irisa's gantry robot named Afma6.
Definition: vpAfma6.h:69
Definition of the vpMatrix class.
Definition: vpMatrix.h:96
vpRxyzVector _erc
Definition: vpAfma6.h:188
vpTranslationVector _etc
Definition: vpAfma6.h:187
static const unsigned int njoint
Number of joint.
Definition: vpAfma6.h:174
Error that can be emited by the vpRobot class and its derivates.
static bool checkDirectory(const char *dirname)
Definition: vpIoTools.cpp:335
unsigned int getWidth() const
Definition: vpImage.h:159
void setMaxTranslationVelocity(const double maxVt)
Definition: vpRobot.cpp:191
void get_eJe(vpMatrix &eJe)
double getSamplingTime() const
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
#define vpTRACE
Definition: vpDebug.h:401
void get_cVe(vpVelocityTwistMatrix &cVe)
void move(const char *filename)
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
Point coordinates conversion from normalized coordinates in meter to pixel coordinates ...
vpHomogeneousMatrix get_fMc(const vpColVector &q)
Definition: vpAfma6.cpp:738
virtual vpRobotStateType getRobotState(void)
Definition: vpRobot.h:139
bool constantSamplingTimeMode
Flag used to force the sampling time in the thread computing the robot's displacement to a constant v...
static std::string getenv(const char *env)
Definition: vpIoTools.cpp:208
double getMaxTranslationVelocity(void) const
Definition: vpRobot.cpp:203
static const vpColor none
Definition: vpColor.h:179
Initialize the position controller.
Definition: vpRobot.h:71
vpAfma6ToolType
List of possible tools that can be attached to the robot end-effector.
Definition: vpAfma6.h:108
void setJointLimit(const vpColVector &limitMin, const vpColVector &limitMax)
void track(const vpHomogeneousMatrix &cMo)
static const double defaultPositioningVelocity
vpRotationMatrix t() const
transpose
vpControlFrameType
Definition: vpRobot.h:78
double get_py() const
void getExternalImage(vpImage< vpRGBa > &I)
vpCameraParameters::vpCameraParametersProjType projModel
Definition: vpAfma6.h:196
static double measureTimeMs()
Definition: vpTime.cpp:86
double get_y() const
Get the point y coordinate in the image plane.
Definition: vpPoint.h:138
static int wait(double t0, double t)
Definition: vpTime.cpp:149
double sumSquare() const
return sum of the Aij^2 (for all i, for all j)
Definition: vpMatrix.cpp:760
static const vpColor green
Definition: vpColor.h:170
vpHomogeneousMatrix fMo
static void flush(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:1991
double getMaxRotationVelocity(void) const
Definition: vpRobot.cpp:228
vpThetaUVector buildFrom(const vpHomogeneousMatrix &M)
void setPosition(const vpRobot::vpControlFrameType frame, const vpColVector &q)
vpAfma6ToolType getToolType()
Get the current tool type.
Definition: vpAfma6.h:147
vpRobot::vpRobotStateType setRobotState(const vpRobot::vpRobotStateType newState)
static bool readPosFile(const char *filename, vpColVector &q)
virtual vpRobotStateType setRobotState(const vpRobot::vpRobotStateType newState)
Definition: vpRobot.cpp:154
Class that defines what is a point.
Definition: vpPoint.h:65
void setToolType(vpAfma6::vpAfma6ToolType tool)
Set the current tool type.
Definition: vpAfma6.h:172
bool initialiseCameraRelativeToObject(const vpHomogeneousMatrix &cMo)
static const char *const CONST_GRIPPER_CAMERA_NAME
Definition: vpAfma6.h:95
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:137
The vpRotationMatrix considers the particular case of a rotation matrix.
void initPersProjWithoutDistortion(const double px, const double py, const double u0, const double v0)
void get_cMe(vpHomogeneousMatrix &cMe)
Definition: vpAfma6.cpp:854
void getDisplacement(const vpRobot::vpControlFrameType frame, vpColVector &displacement)
vpControlFrameType getRobotFrame(void)
Definition: vpRobot.h:159
bool singularityTest(const vpColVector q, vpMatrix &J)
Initialize the velocity controller.
Definition: vpRobot.h:70
void get_eJe(const vpColVector &q, vpMatrix &eJe)
Definition: vpAfma6.cpp:892
vpRobotStateType
Definition: vpRobot.h:66
void initialiseObjectRelativeToCamera(const vpHomogeneousMatrix &cMo)
Initialize the acceleration controller.
Definition: vpRobot.h:72
vpVelocityTwistMatrix buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
vpHomogeneousMatrix f2Mf
void set_displayBusy(const bool &status)
int getInverseKinematics(const vpHomogeneousMatrix &fMc, vpColVector &q, const bool &nearest=true, const bool &verbose=false)
Definition: vpAfma6.cpp:557
static void display(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:203
vpRowVector t() const
transpose of Vector
void getInternalView(vpImage< vpRGBa > &I)
void setVelocity(const vpRobot::vpControlFrameType frame, const vpColVector &velocity)
Generic class defining intrinsic camera parameters.
vpHomogeneousMatrix getExternalCameraPosition() const
void getPosition(const vpRobot::vpControlFrameType frame, vpColVector &q)
vpHomogeneousMatrix cMo
void extract(vpRotationMatrix &R) const
double get_x() const
Get the point x coordinate in the image plane.
Definition: vpPoint.h:136
static Type minimum(const Type &a, const Type &b)
Definition: vpMath.h:148
void setCameraParameters(const vpCameraParameters &cam)
Class that consider the particular case of twist transformation matrix that allows to transform a vel...
void set_velocity(const vpColVector &vel)
void getVelocity(const vpRobot::vpControlFrameType frame, vpColVector &q)
static void displayFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double size, const vpColor &color, unsigned int thickness=1)
Definition: vpDisplay.cpp:368
void buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
Construction from translation vector and rotation matrix.
double get_px() const
static double rad(double deg)
Definition: vpMath.h:100
void setExternalCameraParameters(const vpCameraParameters &cam)
This class aims to be a basis used to create all the simulators of robots.
void setMaxRotationVelocity(const double maxVr)
Definition: vpRobot.cpp:215
bool setVelocityCalled
Flag used to specify to the thread managing the robot displacements that the setVelocity() method has...
void display_scene(Matrix mat, Bound_scene &sc, const vpImage< vpRGBa > &I, const vpColor &color)
double getPositioningVelocity(void)
void setExternalCameraPosition(const vpHomogeneousMatrix camMf)
double _long_56
Definition: vpAfma6.h:183
vpHomogeneousMatrix camMf
vpHomogeneousMatrix navigation(const vpImage< vpRGBa > &I, bool &changed)
vpHomogeneousMatrix fMc
static double deg(double rad)
Definition: vpMath.h:93
vpMatrix eJe
robot Jacobian expressed in the end-effector frame
Definition: vpRobot.h:103
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
double euclideanNorm() const
Definition: vpMatrix.cpp:2816
void get_fJe(vpMatrix &fJe)
The pose is a complete representation of every rigid motion in the euclidian space.
Definition: vpPoseVector.h:92
vpHomogeneousMatrix inverse() const
vpHomogeneousMatrix _eMc
Definition: vpAfma6.h:190
void get_fJe(const vpColVector &q, vpMatrix &fJe)
Definition: vpAfma6.cpp:959
unsigned int getHeight() const
Definition: vpImage.h:150
Class that consider the case of the Euler angle using the x-y-z convention, where are respectively ...
Definition: vpRxyzVector.h:152
void getCameraParameters(vpCameraParameters &cam, const unsigned int &image_width, const unsigned int &image_height)
vpControlFrameType setRobotFrame(vpRobot::vpControlFrameType newFrame)
Definition: vpRobot.cpp:161
void get_cMe(vpHomogeneousMatrix &cMe)
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.
Definition: vpMatrix.cpp:1812
double _joint_max[6]
Definition: vpAfma6.h:184
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:92
void set_artCoord(const vpColVector &coord)
virtual void displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)=0
void set_artVel(const vpColVector &vel)
static DWORD WINAPI launcher(LPVOID lpParam)
void get_fMi(vpHomogeneousMatrix *fMit)
unsigned int getRows() const
Return the number of rows of the matrix.
Definition: vpMatrix.h:157
static const char *const CONST_CCMOP_CAMERA_NAME
Definition: vpAfma6.h:90
vpMatrix fJe
robot Jacobian expressed in the robot reference frame available
Definition: vpRobot.h:107
Class that consider the case of a translation vector.
Class that consider the case of the parameterization for the rotation.
static double minTimeForUsleepCall
Definition: vpTime.h:81
vpHomogeneousMatrix camMf2
static bool savePosFile(const char *filename, const vpColVector &q)
double _joint_min[6]
Definition: vpAfma6.h:185
void findHighestPositioningSpeed(vpColVector &q)
void setWorldCoordinates(const double ox, const double oy, const double oz)
Set the point world coordinates. We mean here the coordinates of the point in the object frame...
Definition: vpPoint.cpp:74
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:94