Visual Servoing Platform  version 3.0.0
vpSimulatorAfma6.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Class which provides a simulator for the robot Afma6.
32  *
33  * Authors:
34  * Nicolas Melchior
35  *
36  *****************************************************************************/
37 
38 
39 
40 #include <visp3/core/vpConfig.h>
41 #if defined(VISP_HAVE_MODULE_GUI) && (defined(_WIN32) || defined(VISP_HAVE_PTHREAD))
42 #include <visp3/robot/vpSimulatorAfma6.h>
43 #include <visp3/core/vpTime.h>
44 #include <visp3/core/vpImagePoint.h>
45 #include <visp3/core/vpPoint.h>
46 #include <visp3/core/vpMeterPixelConversion.h>
47 #include <visp3/robot/vpRobotException.h>
48 #include <visp3/core/vpIoTools.h>
49 #include <cmath> // std::fabs
50 #include <limits> // numeric_limits
51 #include <string>
53 
54 
60  q_prev_getdis(), first_time_getdis(true), positioningVelocity(defaultPositioningVelocity),
61  zeroPos(), reposPos(), toolCustom(false), arm_dir()
62 {
63  init();
64  initDisplay();
65 
67 
68  #if defined(_WIN32)
69  mutex_fMi = CreateMutex(NULL,FALSE,NULL);
70  mutex_artVel = CreateMutex(NULL,FALSE,NULL);
71  mutex_artCoord = CreateMutex(NULL,FALSE,NULL);
72  mutex_velocity = CreateMutex(NULL,FALSE,NULL);
73  mutex_display = CreateMutex(NULL,FALSE,NULL);
74 
75 
76  DWORD dwThreadIdArray;
77  hThread = CreateThread(
78  NULL, // default security attributes
79  0, // use default stack size
80  launcher, // thread function name
81  this, // argument to thread function
82  0, // use default creation flags
83  &dwThreadIdArray); // returns the thread identifier
84  #elif defined (VISP_HAVE_PTHREAD)
85  pthread_mutex_init(&mutex_fMi, NULL);
86  pthread_mutex_init(&mutex_artVel, NULL);
87  pthread_mutex_init(&mutex_artCoord, NULL);
88  pthread_mutex_init(&mutex_velocity, NULL);
89  pthread_mutex_init(&mutex_display, NULL);
90 
91  pthread_attr_init(&attr);
92  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
93 
94  pthread_create(&thread, NULL, launcher, (void *)this);
95  #endif
96 
97  compute_fMi();
98 }
99 
107  : vpRobotWireFrameSimulator(do_display),
108  q_prev_getdis(), first_time_getdis(true), positioningVelocity(defaultPositioningVelocity),
109  zeroPos(), reposPos(), toolCustom(false), arm_dir()
110 {
111  init();
112  initDisplay();
113 
115 
116  #if defined(_WIN32)
117  mutex_fMi = CreateMutex(NULL,FALSE,NULL);
118  mutex_artVel = CreateMutex(NULL,FALSE,NULL);
119  mutex_artCoord = CreateMutex(NULL,FALSE,NULL);
120  mutex_velocity = CreateMutex(NULL,FALSE,NULL);
121  mutex_display = CreateMutex(NULL,FALSE,NULL);
122 
123 
124  DWORD dwThreadIdArray;
125  hThread = CreateThread(
126  NULL, // default security attributes
127  0, // use default stack size
128  launcher, // thread function name
129  this, // argument to thread function
130  0, // use default creation flags
131  &dwThreadIdArray); // returns the thread identifier
132  #elif defined(VISP_HAVE_PTHREAD)
133  pthread_mutex_init(&mutex_fMi, NULL);
134  pthread_mutex_init(&mutex_artVel, NULL);
135  pthread_mutex_init(&mutex_artCoord, NULL);
136  pthread_mutex_init(&mutex_velocity, NULL);
137  pthread_mutex_init(&mutex_display, NULL);
138 
139  pthread_attr_init(&attr);
140  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
141 
142  pthread_create(&thread, NULL, launcher, (void *)this);
143  #endif
144 
145  compute_fMi();
146 }
147 
152 {
153  robotStop = true;
154 
155  #if defined(_WIN32)
156  WaitForSingleObject(hThread,INFINITE);
157  CloseHandle(hThread);
158  CloseHandle(mutex_fMi);
159  CloseHandle(mutex_artVel);
160  CloseHandle(mutex_artCoord);
161  CloseHandle(mutex_velocity);
162  CloseHandle(mutex_display);
163  #elif defined(VISP_HAVE_PTHREAD)
164  pthread_attr_destroy(&attr);
165  pthread_join(thread, NULL);
166  pthread_mutex_destroy(&mutex_fMi);
167  pthread_mutex_destroy(&mutex_artVel);
168  pthread_mutex_destroy(&mutex_artCoord);
169  pthread_mutex_destroy(&mutex_velocity);
170  pthread_mutex_destroy(&mutex_display);
171  #endif
172 
173  if (robotArms != NULL)
174  {
175  for(int i = 0; i < 6; i++)
176  free_Bound_scene (&(robotArms[i]));
177  }
178 
179  delete[] robotArms;
180  delete[] fMi;
181 }
182 
191 void
193 {
194  // set arm_dir from #define VISP_ROBOT_ARMS_DIR if it exists
195  // VISP_ROBOT_ARMS_DIR may contain multiple locations separated by ";"
196  std::vector<std::string> arm_dirs = vpIoTools::splitChain(std::string(VISP_ROBOT_ARMS_DIR), std::string(";"));
197  bool armDirExists = false;
198  for(size_t i=0; i < arm_dirs.size(); i++)
199  if (vpIoTools::checkDirectory(arm_dirs[i]) == true) { // directory exists
200  arm_dir = arm_dirs[i];
201  armDirExists = true;
202  break;
203  }
204  if (! armDirExists) {
205  try {
206  arm_dir = vpIoTools::getenv("VISP_ROBOT_ARMS_DIR");
207  std::cout << "The simulator uses data from VISP_ROBOT_ARMS_DIR=" << arm_dir << std::endl;
208  }
209  catch (...) {
210  std::cout << "Cannot get VISP_ROBOT_ARMS_DIR environment variable" << std::endl;
211  }
212  }
213 
214  this->init(vpAfma6::TOOL_CCMOP);
215  toolCustom = false;
216 
217  size_fMi = 8;
218  fMi = new vpHomogeneousMatrix[8];
221 
222  zeroPos.resize(njoint);
223  zeroPos = 0;
224  reposPos.resize(njoint);
225  reposPos = 0;
226  reposPos[1] = -M_PI/2; reposPos[2] = M_PI; reposPos[4] = M_PI/2;
227 
228  artCoord = zeroPos;
229  artVel = 0;
230 
231  q_prev_getdis.resize(njoint);
232  q_prev_getdis = 0;
233  first_time_getdis = true;
234 
235  positioningVelocity = defaultPositioningVelocity ;
236 
239 
240  // Software joint limits in radians
241  //_joint_min.resize(njoint);
242  _joint_min[0] = -0.6501;
243  _joint_min[1] = -0.6001;
244  _joint_min[2] = -0.5001;
245  _joint_min[3] = -2.7301;
246  _joint_min[4] = -0.1001;
247  _joint_min[5] = -1.5901;
248  //_joint_max.resize(njoint);
249  _joint_max[0] = 0.7001;
250  _joint_max[1] = 0.5201;
251  _joint_max[2] = 0.4601;
252  _joint_max[3] = 2.7301;
253  _joint_max[4] = 2.4801;
254  _joint_max[5] = 1.5901;
255 }
256 
260 void
262 {
263  robotArms = NULL;
264  robotArms = new Bound_scene[6];
265  initArms();
267  cameraParam.initPersProjWithoutDistortion (558.5309599, 556.055053, 320, 240);
269  vpCameraParameters tmp;
270  getCameraParameters(tmp,640,480);
271  px_int = tmp.get_px();
272  py_int = tmp.get_py();
273  sceneInitialized = true;
274 }
275 
276 
292 void
295 {
296  this->projModel = proj_model;
297  unsigned int name_length = 30; // the size of this kind of string "/afma6_tool_vacuum.bnd"
298  if (arm_dir.size() > FILENAME_MAX)
299  throw vpException (vpException::dimensionError, "Cannot initialize Afma6 simulator");
300  unsigned int full_length = (unsigned int)arm_dir.size() + name_length;
301  if (full_length > FILENAME_MAX)
302  throw vpException (vpException::dimensionError, "Cannot initialize Afma6 simulator");
303 
304  // Use here default values of the robot constant parameters.
305  switch (tool) {
306  case vpAfma6::TOOL_CCMOP: {
307  _erc[0] = vpMath::rad(164.35); // rx
308  _erc[1] = vpMath::rad( 89.64); // ry
309  _erc[2] = vpMath::rad(-73.05); // rz
310  _etc[0] = 0.0117; // tx
311  _etc[1] = 0.0033; // ty
312  _etc[2] = 0.2272; // tz
313 
314  setCameraParameters(vpCameraParameters(1109.5735473989, 1112.1520168160, 320, 240));
315 
316  if (robotArms != NULL)
317  {
318  while (get_displayBusy()) vpTime::wait(2);
319  free_Bound_scene (&(robotArms[5]));
320  char *name_arm = new char [full_length];
321  strcpy(name_arm, arm_dir.c_str());
322  strcat(name_arm,"/afma6_tool_ccmop.bnd");
323  set_scene(name_arm, robotArms+5, 1.0);
324  set_displayBusy(false);
325  delete [] name_arm;
326  }
327  break;
328  }
329  case vpAfma6::TOOL_GRIPPER: {
330  _erc[0] = vpMath::rad( 88.33); // rx
331  _erc[1] = vpMath::rad( 72.07); // ry
332  _erc[2] = vpMath::rad( 2.53); // rz
333  _etc[0] = 0.0783; // tx
334  _etc[1] = 0.1234; // ty
335  _etc[2] = 0.1638; // tz
336 
337  setCameraParameters(vpCameraParameters(852.6583228197, 854.8084224761, 320, 240));
338 
339  if (robotArms != NULL)
340  {
341  while (get_displayBusy()) vpTime::wait(2);
342  free_Bound_scene (&(robotArms[5]));
343  char *name_arm = new char [full_length];
344  strcpy(name_arm, arm_dir.c_str());
345  strcat(name_arm,"/afma6_tool_gripper.bnd");
346  set_scene(name_arm, robotArms+5, 1.0);
347  set_displayBusy(false);
348  delete [] name_arm;
349  }
350  break;
351  }
352  case vpAfma6::TOOL_VACUUM: {
353  _erc[0] = vpMath::rad( 90.40); // rx
354  _erc[1] = vpMath::rad( 75.11); // ry
355  _erc[2] = vpMath::rad( 0.18); // rz
356  _etc[0] = 0.0038; // tx
357  _etc[1] = 0.1281; // ty
358  _etc[2] = 0.1658; // tz
359 
360  setCameraParameters(vpCameraParameters(853.4876600807, 856.0339170706, 320, 240));
361 
362  if (robotArms != NULL)
363  {
364  while (get_displayBusy()) vpTime::wait(2);
365  free_Bound_scene (&(robotArms[5]));
366 
367  char *name_arm = new char [full_length];
368 
369  strcpy(name_arm, arm_dir.c_str());
370  strcat(name_arm,"/afma6_tool_vacuum.bnd");
371  set_scene(name_arm, robotArms+5, 1.0);
372  set_displayBusy(false);
373  delete [] name_arm;
374  }
375  break;
376  }
378  std::cout << "The generic camera is not handled in vpSimulatorAfma6.cpp" << std::endl;
379  }
380  }
381 
382  vpRotationMatrix eRc(_erc);
383  this->_eMc.buildFrom(_etc, eRc);
384 
385  setToolType(tool);
386  return ;
387 }
388 
399 void
401  const unsigned int &image_width,
402  const unsigned int &image_height)
403 {
404  if (toolCustom)
405  {
406  vpCameraParameters(px_int,py_int,image_width/2,image_height/2);
407  }
408  // Set default parameters
409  switch (getToolType()) {
410  case vpAfma6::TOOL_CCMOP: {
411  // Set default intrinsic camera parameters for 640x480 images
412  if (image_width == 640 && image_height == 480)
413  {
414  std::cout << "Get default camera parameters for camera \""
415  << vpAfma6::CONST_CCMOP_CAMERA_NAME << "\"" << std::endl;
416  cam.initPersProjWithoutDistortion(1109.5735473989, 1112.1520168160, 320, 240);
417  }
418  else {
419  vpTRACE("Cannot get default intrinsic camera parameters for this image resolution");
420  }
421  break;
422  }
423  case vpAfma6::TOOL_GRIPPER: {
424  // Set default intrinsic camera parameters for 640x480 images
425  if (image_width == 640 && image_height == 480) {
426  std::cout << "Get default camera parameters for camera \""
427  << vpAfma6::CONST_GRIPPER_CAMERA_NAME << "\"" << std::endl;
428  cam.initPersProjWithoutDistortion(852.6583228197, 854.8084224761, 320, 240);
429  }
430  else {
431  vpTRACE("Cannot get default intrinsic camera parameters for this image resolution");
432  }
433  break;
434  }
436  case vpAfma6::TOOL_VACUUM: {
437  std::cout << "The generic camera is not handled in vpSimulatorAfma6.cpp" << std::endl;
438  break;
439  }
440  default:
441  vpERROR_TRACE ("This error should not occur!");
442  break;
443  }
444  return;
445 }
446 
455 void
457  const vpImage<unsigned char> &I_)
458 {
459  getCameraParameters(cam,I_.getWidth(),I_.getHeight());
460 }
461 
470 void
472  const vpImage<vpRGBa> &I_)
473 {
474  getCameraParameters(cam,I_.getWidth(),I_.getHeight());
475 }
476 
477 
483 void
485 {
486  px_int = cam.get_px();
487  py_int = cam.get_py();
488  toolCustom = true;
489 }
490 
491 
495 void
497 {
498  double tcur_1 = tcur;// temporary variable used to store the last time since the last command
499 
500  while (!robotStop)
501  {
502  //Get current time
503  tprev = tcur_1;
505 
507  setVelocityCalled = false;
508 
510 
511  double ellapsedTime = (tcur - tprev) * 1e-3;
512  if(constantSamplingTimeMode){//if we want a constant velocity, we force the ellapsed time to the given samplingTime
513  ellapsedTime = getSamplingTime(); // in second
514  }
515 
516  vpColVector articularCoordinates = get_artCoord();
517  articularCoordinates = get_artCoord();
518  vpColVector articularVelocities = get_artVel();
519 
520  if (jointLimit)
521  {
522  double art = articularCoordinates[jointLimitArt-1] + ellapsedTime*articularVelocities[jointLimitArt-1];
523  if (art <= _joint_min[jointLimitArt-1] || art >= _joint_max[jointLimitArt-1]) {
524  if (verbose_) {
525  std::cout << "Joint " << jointLimitArt-1
526  << " reaches a limit: " << vpMath::deg(_joint_min[jointLimitArt-1]) << " < "
527  << vpMath::deg(art) << " < " << vpMath::deg(_joint_max[jointLimitArt-1]) << std::endl;
528  }
529 
530  articularVelocities = 0.0;
531  }
532  else
533  jointLimit = false;
534  }
535 
536  articularCoordinates[0] = articularCoordinates[0] + ellapsedTime*articularVelocities[0];
537  articularCoordinates[1] = articularCoordinates[1] + ellapsedTime*articularVelocities[1];
538  articularCoordinates[2] = articularCoordinates[2] + ellapsedTime*articularVelocities[2];
539  articularCoordinates[3] = articularCoordinates[3] + ellapsedTime*articularVelocities[3];
540  articularCoordinates[4] = articularCoordinates[4] + ellapsedTime*articularVelocities[4];
541  articularCoordinates[5] = articularCoordinates[5] + ellapsedTime*articularVelocities[5];
542 
543  int jl = isInJointLimit();
544 
545  if (jl != 0 && jointLimit == false)
546  {
547  if (jl < 0)
548  ellapsedTime = (_joint_min[(unsigned int)(-jl-1)] - articularCoordinates[(unsigned int)(-jl-1)])/(articularVelocities[(unsigned int)(-jl-1)]);
549  else
550  ellapsedTime = (_joint_max[(unsigned int)(jl-1)] - articularCoordinates[(unsigned int)(jl-1)])/(articularVelocities[(unsigned int)(jl-1)]);
551 
552  for (unsigned int i = 0; i < 6; i++)
553  articularCoordinates[i] = articularCoordinates[i] + ellapsedTime*articularVelocities[i];
554 
555  jointLimit = true;
556  jointLimitArt = (unsigned int)fabs((double)jl);
557  }
558 
559  set_artCoord(articularCoordinates);
560  set_artVel(articularVelocities);
561 
562  compute_fMi();
563 
564  if (displayAllowed)
565  {
569  }
570 
572  {
573  while (get_displayBusy()) vpTime::wait(2);
575  set_displayBusy(false);
576  }
577 
578 
579  if (0/*displayType == MODEL_DH && displayAllowed*/)
580  {
581  vpHomogeneousMatrix fMit[8];
582  get_fMi(fMit);
583 
584  //vpDisplay::displayFrame(I,getExternalCameraPosition ()*fMi[6],cameraParam,0.2,vpColor::none);
585 
586  vpImagePoint iP, iP_1;
587  vpPoint pt(0,0,0);
588 
591  pt.track(getExternalCameraPosition ()*fMit[0]);
594  for (unsigned int k = 1; k < 7; k++)
595  {
596  pt.track(getExternalCameraPosition ()*fMit[k-1]);
598 
599  pt.track(getExternalCameraPosition ()*fMit[k]);
601 
603  }
605  }
606 
608 
609 
610  vpTime::wait( tcur, 1000*getSamplingTime() );
611  tcur_1 = tcur;
612  }else{
614  }
615  }
616 }
617 
625 void
627 {
628  //vpColVector q = get_artCoord();
629  vpColVector q(6);//; = get_artCoord();
630  q = get_artCoord();
631 
632  vpHomogeneousMatrix fMit[8];
633 
634  double q1 = q[0];
635  double q2 = q[1];
636  double q3 = q[2];
637  double q4 = q[3];
638  double q5 = q[4];
639  double q6 = q[5];
640 
641  double c4 = cos(q4);
642  double s4 = sin(q4);
643  double c5 = cos(q5);
644  double s5 = sin(q5);
645  double c6 = cos(q6);
646  double s6 = sin(q6);
647 
648  fMit[0][0][0] = 1;
649  fMit[0][1][0] = 0;
650  fMit[0][2][0] = 0;
651  fMit[0][0][1] = 0;
652  fMit[0][1][1] = 1;
653  fMit[0][2][1] = 0;
654  fMit[0][0][2] = 0;
655  fMit[0][1][2] = 0;
656  fMit[0][2][2] = 1;
657  fMit[0][0][3] = q1;
658  fMit[0][1][3] = 0;
659  fMit[0][2][3] = 0;
660 
661  fMit[1][0][0] = 1;
662  fMit[1][1][0] = 0;
663  fMit[1][2][0] = 0;
664  fMit[1][0][1] = 0;
665  fMit[1][1][1] = 1;
666  fMit[1][2][1] = 0;
667  fMit[1][0][2] = 0;
668  fMit[1][1][2] = 0;
669  fMit[1][2][2] = 1;
670  fMit[1][0][3] = q1;
671  fMit[1][1][3] = q2;
672  fMit[1][2][3] = 0;
673 
674  fMit[2][0][0] = 1;
675  fMit[2][1][0] = 0;
676  fMit[2][2][0] = 0;
677  fMit[2][0][1] = 0;
678  fMit[2][1][1] = 1;
679  fMit[2][2][1] = 0;
680  fMit[2][0][2] = 0;
681  fMit[2][1][2] = 0;
682  fMit[2][2][2] = 1;
683  fMit[2][0][3] = q1;
684  fMit[2][1][3] = q2;
685  fMit[2][2][3] = q3;
686 
687  fMit[3][0][0] = s4;
688  fMit[3][1][0] = -c4;
689  fMit[3][2][0] = 0;
690  fMit[3][0][1] = c4;
691  fMit[3][1][1] = s4;
692  fMit[3][2][1] = 0;
693  fMit[3][0][2] = 0;
694  fMit[3][1][2] = 0;
695  fMit[3][2][2] = 1;
696  fMit[3][0][3] = q1;
697  fMit[3][1][3] = q2;
698  fMit[3][2][3] = q3;
699 
700  fMit[4][0][0] = s4*s5;
701  fMit[4][1][0] = -c4*s5;
702  fMit[4][2][0] = c5;
703  fMit[4][0][1] = s4*c5;
704  fMit[4][1][1] = -c4*c5;
705  fMit[4][2][1] = -s5;
706  fMit[4][0][2] = c4;
707  fMit[4][1][2] = s4;
708  fMit[4][2][2] = 0;
709  fMit[4][0][3] = c4*this->_long_56+q1;
710  fMit[4][1][3] = s4*this->_long_56+q2;
711  fMit[4][2][3] = q3;
712 
713  fMit[5][0][0] = s4*s5*c6+c4*s6;
714  fMit[5][1][0] = -c4*s5*c6+s4*s6;
715  fMit[5][2][0] = c5*c6;
716  fMit[5][0][1] = -s4*s5*s6+c4*c6;
717  fMit[5][1][1] = c4*s5*s6+s4*c6;
718  fMit[5][2][1] = -c5*s6;
719  fMit[5][0][2] = -s4*c5;
720  fMit[5][1][2] = c4*c5;
721  fMit[5][2][2] = s5;
722  fMit[5][0][3] = c4*this->_long_56+q1;
723  fMit[5][1][3] = s4*this->_long_56+q2;
724  fMit[5][2][3] = q3;
725 
726  fMit[6][0][0] = fMit[5][0][0];
727  fMit[6][1][0] = fMit[5][1][0];
728  fMit[6][2][0] = fMit[5][2][0];
729  fMit[6][0][1] = fMit[5][0][1];
730  fMit[6][1][1] = fMit[5][1][1];
731  fMit[6][2][1] = fMit[5][2][1];
732  fMit[6][0][2] = fMit[5][0][2];
733  fMit[6][1][2] = fMit[5][1][2];
734  fMit[6][2][2] = fMit[5][2][2];
735  fMit[6][0][3] = fMit[5][0][3];
736  fMit[6][1][3] = fMit[5][1][3];
737  fMit[6][2][3] = fMit[5][2][3];
738 
739 // vpHomogeneousMatrix cMe;
740 // get_cMe(cMe);
741 // cMe = cMe.inverse();
742 // fMit[7] = fMit[6] * cMe;
743  vpAfma6::get_fMc(q,fMit[7]);
744 
745  #if defined(_WIN32)
746  WaitForSingleObject(mutex_fMi,INFINITE);
747  for (int i = 0; i < 8; i++)
748  fMi[i] = fMit[i];
749  ReleaseMutex(mutex_fMi);
750  #elif defined(VISP_HAVE_PTHREAD)
751  pthread_mutex_lock (&mutex_fMi);
752  for (int i = 0; i < 8; i++)
753  fMi[i] = fMit[i];
754  pthread_mutex_unlock (&mutex_fMi);
755  #endif
756 }
757 
758 
766 {
767  switch (newState) {
768  case vpRobot::STATE_STOP: {
769  // Start primitive STOP only if the current state is Velocity
771  stopMotion();
772  }
773  break;
774  }
777  std::cout << "Change the control mode from velocity to position control.\n";
778  stopMotion();
779  }
780  else {
781  //std::cout << "Change the control mode from stop to position control.\n";
782  }
783  break;
784  }
787  std::cout << "Change the control mode from stop to velocity control.\n";
788  }
789  break;
790  }
792  default:
793  break ;
794  }
795 
796  return vpRobot::setRobotState (newState);
797 }
798 
868 void
870 {
872  vpERROR_TRACE ("Cannot send a velocity to the robot "
873  "use setRobotState(vpRobot::STATE_VELOCITY_CONTROL) first) ");
875  "Cannot send a velocity to the robot "
876  "use setRobotState(vpRobot::STATE_VELOCITY_CONTROL) first) ");
877  }
878 
879  vpColVector vel_sat(6);
880 
881  double scale_trans_sat = 1;
882  double scale_rot_sat = 1;
883  double scale_sat = 1;
884  double vel_trans_max = getMaxTranslationVelocity();
885  double vel_rot_max = getMaxRotationVelocity();
886 
887  double vel_abs; // Absolute value
888 
889  // Velocity saturation
890  switch(frame)
891  {
892  // saturation in cartesian space
893  case vpRobot::CAMERA_FRAME :
895  {
896  if (vel.getRows() != 6)
897  {
898  vpERROR_TRACE ("The velocity vector must have a size of 6 !!!!");
899  throw;
900  }
901 
902  for (unsigned int i = 0 ; i < 3; ++ i)
903  {
904  vel_abs = fabs (vel[i]);
905  if (vel_abs > vel_trans_max && !jointLimit)
906  {
907  vel_trans_max = vel_abs;
908  vpERROR_TRACE ("Excess velocity %g m/s in TRANSLATION "
909  "(axis nr. %d).", vel[i], i+1);
910  }
911 
912  vel_abs = fabs (vel[i+3]);
913  if (vel_abs > vel_rot_max && !jointLimit) {
914  vel_rot_max = vel_abs;
915  vpERROR_TRACE ("Excess velocity %g rad/s in ROTATION "
916  "(axis nr. %d).", vel[i+3], i+4);
917  }
918  }
919 
920  if (vel_trans_max > getMaxTranslationVelocity())
921  scale_trans_sat = getMaxTranslationVelocity() / vel_trans_max;
922 
923  if (vel_rot_max > getMaxRotationVelocity())
924  scale_rot_sat = getMaxRotationVelocity() / vel_rot_max;
925 
926  if ( (scale_trans_sat < 1) || (scale_rot_sat < 1) )
927  {
928  if (scale_trans_sat < scale_rot_sat)
929  scale_sat = scale_trans_sat;
930  else
931  scale_sat = scale_rot_sat;
932  }
933  break;
934  }
935 
936  // saturation in joint space
938  {
939  if (vel.getRows() != 6)
940  {
941  vpERROR_TRACE ("The velocity vector must have a size of 6 !!!!");
942  throw;
943  }
944  for (unsigned int i = 0 ; i < 6; ++ i)
945  {
946  vel_abs = fabs (vel[i]);
947  if (vel_abs > vel_rot_max && !jointLimit)
948  {
949  vel_rot_max = vel_abs;
950  vpERROR_TRACE ("Excess velocity %g rad/s in ROTATION "
951  "(axis nr. %d).", vel[i], i+1);
952  }
953  }
954  if (vel_rot_max > getMaxRotationVelocity())
955  scale_rot_sat = getMaxRotationVelocity() / vel_rot_max;
956  if ( scale_rot_sat < 1 )
957  scale_sat = scale_rot_sat;
958  break;
959  }
960  case vpRobot::MIXT_FRAME :
961  {
962  break;
963  }
964  }
965 
966  set_velocity (vel * scale_sat);
967  setRobotFrame (frame);
968  setVelocityCalled = true;
969 }
970 
971 
975 void
977 {
979 
980  double scale_rot_sat = 1;
981  double scale_sat = 1;
982  double vel_rot_max = getMaxRotationVelocity();
983  double vel_abs;
984 
985  vpColVector articularCoordinates = get_artCoord();
986  vpColVector velocityframe = get_velocity();
987  vpColVector articularVelocity;
988 
989  switch(frame)
990  {
991  case vpRobot::CAMERA_FRAME :
992  {
993  vpMatrix eJe_;
995  vpAfma6::get_eJe(articularCoordinates,eJe_);
996  eJe_ = eJe_.pseudoInverse();
998  singularityTest(articularCoordinates,eJe_);
999  articularVelocity = eJe_*eVc*velocityframe;
1000  set_artVel (articularVelocity);
1001  break;
1002  }
1004  {
1005  vpMatrix fJe_;
1006  vpAfma6::get_fJe(articularCoordinates,fJe_);
1007  fJe_ = fJe_.pseudoInverse();
1009  singularityTest(articularCoordinates,fJe_);
1010  articularVelocity = fJe_*velocityframe;
1011  set_artVel (articularVelocity);
1012  break;
1013  }
1015  {
1016  articularVelocity = velocityframe;
1017  set_artVel (articularVelocity);
1018  break;
1019  }
1020  case vpRobot::MIXT_FRAME :
1021  {
1022  break;
1023  }
1024  }
1025 
1026 
1027 
1028  switch(frame)
1029  {
1030  case vpRobot::CAMERA_FRAME :
1032  {
1033  for (unsigned int i = 0 ; i < 6; ++ i)
1034  {
1035  vel_abs = fabs (articularVelocity[i]);
1036  if (vel_abs > vel_rot_max && !jointLimit)
1037  {
1038  vel_rot_max = vel_abs;
1039  vpERROR_TRACE ("Excess velocity %g rad/s in ROTATION "
1040  "(axis nr. %d).", articularVelocity[i], i+1);
1041  }
1042  }
1043  if (vel_rot_max > getMaxRotationVelocity())
1044  scale_rot_sat = getMaxRotationVelocity() / vel_rot_max;
1045  if ( scale_rot_sat < 1 )
1046  scale_sat = scale_rot_sat;
1047 
1048  set_artVel(articularVelocity * scale_sat);
1049  break;
1050  }
1052  case vpRobot::MIXT_FRAME :
1053  {
1054  break;
1055  }
1056  }
1057 }
1058 
1059 
1106 void
1108 {
1109  vel.resize(6);
1110 
1111  vpColVector articularCoordinates = get_artCoord();
1112  vpColVector articularVelocity = get_artVel();
1113 
1114  switch(frame)
1115  {
1116  case vpRobot::CAMERA_FRAME :
1117  {
1118  vpMatrix eJe_;
1120  vpAfma6::get_eJe(articularCoordinates,eJe_);
1121  vel = cVe*eJe_*articularVelocity;
1122  break ;
1123  }
1124  case vpRobot::ARTICULAR_FRAME :
1125  {
1126  vel = articularVelocity;
1127  break ;
1128  }
1129  case vpRobot::REFERENCE_FRAME :
1130  {
1131  vpMatrix fJe_;
1132  vpAfma6::get_fJe(articularCoordinates,fJe_);
1133  vel = fJe_*articularVelocity;
1134  break ;
1135  }
1136  case vpRobot::MIXT_FRAME :
1137  {
1138  break ;
1139  }
1140  default:
1141  {
1142  vpERROR_TRACE ("Error in spec of vpRobot. "
1143  "Case not taken in account.");
1144  return;
1145  }
1146  }
1147 }
1148 
1165 void
1167 {
1168  timestamp = vpTime::measureTimeSecond();
1169  getVelocity(frame, vel);
1170 }
1171 
1216 {
1217  vpColVector vel(6);
1218  getVelocity (frame, vel);
1219 
1220  return vel;
1221 }
1222 
1237 {
1238  timestamp = vpTime::measureTimeSecond();
1239  vpColVector vel(6);
1240  getVelocity (frame, vel);
1241 
1242  return vel;
1243 }
1244 
1245 void
1247 {
1248  double vel_rot_max = getMaxRotationVelocity();
1249  double velmax = fabs(q[0]);
1250  for (unsigned int i = 1; i < 6; i++)
1251  {
1252  if (velmax < fabs(q[i]))
1253  velmax = fabs(q[i]);
1254  }
1255 
1256  double alpha = (getPositioningVelocity() * vel_rot_max) / (velmax*100);
1257  q = q * alpha;
1258 }
1259 
1334 void
1336 {
1338  {
1339  vpERROR_TRACE ("Robot was not in position-based control\n"
1340  "Modification of the robot state");
1341  // setRobotState(vpRobot::STATE_POSITION_CONTROL) ;
1342  }
1343 
1344  vpColVector articularCoordinates = get_artCoord();
1345 
1346  vpColVector error(6);
1347  double errsqr = 0;
1348  switch(frame)
1349  {
1350  case vpRobot::CAMERA_FRAME :
1351  {
1352  int nbSol;
1353  vpColVector qdes(6);
1354 
1355  vpTranslationVector txyz;
1356  vpRxyzVector rxyz;
1357  for (unsigned int i=0; i < 3; i++)
1358  {
1359  txyz[i] = q[i];
1360  rxyz[i] = q[i+3];
1361  }
1362 
1363  vpRotationMatrix cRc2(rxyz);
1364  vpHomogeneousMatrix cMc2(txyz, cRc2);
1365 
1366  vpHomogeneousMatrix fMc_;
1367  vpAfma6::get_fMc(articularCoordinates, fMc_);
1368 
1369  vpHomogeneousMatrix fMc2 = fMc_ * cMc2;
1370 
1371  do
1372  {
1373  articularCoordinates = get_artCoord();
1374  qdes = articularCoordinates;
1375  nbSol = getInverseKinematics(fMc2, qdes, true, verbose_);
1376  setVelocityCalled = true;
1377  if (nbSol > 0)
1378  {
1379  error = qdes - articularCoordinates;
1380  errsqr = error.sumSquare();
1381  //findHighestPositioningSpeed(error);
1382  set_artVel(error);
1383  if (errsqr < 1e-4)
1384  {
1385  set_artCoord (qdes);
1386  error = 0;
1387  set_artVel(error);
1388  set_velocity(error);
1389  break;
1390  }
1391  }
1392  else
1393  {
1394  vpERROR_TRACE ("Positionning error.");
1396  "Position out of range.");
1397  }
1398  }while (errsqr > 1e-8 && nbSol > 0);
1399 
1400  break ;
1401  }
1402 
1404  {
1405  do
1406  {
1407  articularCoordinates = get_artCoord();
1408  error = q - articularCoordinates;
1409  errsqr = error.sumSquare();
1410  //findHighestPositioningSpeed(error);
1411  set_artVel(error);
1412  setVelocityCalled = true;
1413  if (errsqr < 1e-4)
1414  {
1415  set_artCoord (q);
1416  error = 0;
1417  set_artVel(error);
1418  set_velocity(error);
1419  break;
1420  }
1421  }while (errsqr > 1e-8);
1422  break ;
1423  }
1424 
1426  {
1427  int nbSol;
1428  vpColVector qdes(6);
1429 
1430  vpTranslationVector txyz;
1431  vpRxyzVector rxyz;
1432  for (unsigned int i=0; i < 3; i++)
1433  {
1434  txyz[i] = q[i];
1435  rxyz[i] = q[i+3];
1436  }
1437 
1438  vpRotationMatrix fRc(rxyz);
1439  vpHomogeneousMatrix fMc_(txyz, fRc);
1440 
1441  do
1442  {
1443  articularCoordinates = get_artCoord();
1444  qdes = articularCoordinates;
1445  nbSol = getInverseKinematics(fMc_, qdes, true, verbose_);
1446  setVelocityCalled = true;
1447  if (nbSol > 0)
1448  {
1449  error = qdes - articularCoordinates;
1450  errsqr = error.sumSquare();
1451  //findHighestPositioningSpeed(error);
1452  set_artVel(error);
1453  if (errsqr < 1e-4)
1454  {
1455  set_artCoord (qdes);
1456  error = 0;
1457  set_artVel(error);
1458  set_velocity(error);
1459  break;
1460  }
1461  }
1462  else
1463  vpERROR_TRACE ("Positionning error. Position unreachable");
1464  }while (errsqr > 1e-8 && nbSol > 0);
1465  break ;
1466  }
1467  case vpRobot::MIXT_FRAME:
1468  {
1469  vpERROR_TRACE ("Positionning error. Mixt frame not implemented");
1471  "Positionning error: "
1472  "Mixt frame not implemented.");
1473  break ;
1474  }
1475  }
1476 }
1477 
1542  const double pos1,
1543  const double pos2,
1544  const double pos3,
1545  const double pos4,
1546  const double pos5,
1547  const double pos6)
1548 {
1549  try{
1550  vpColVector position(6) ;
1551  position[0] = pos1 ;
1552  position[1] = pos2 ;
1553  position[2] = pos3 ;
1554  position[3] = pos4 ;
1555  position[4] = pos5 ;
1556  position[5] = pos6 ;
1557 
1558  setPosition(frame, position) ;
1559  }
1560  catch(...)
1561  {
1562  vpERROR_TRACE("Error caught");
1563  throw ;
1564  }
1565 }
1566 
1602 void vpSimulatorAfma6::setPosition(const char *filename)
1603 {
1604  vpColVector q;
1605  bool ret;
1606 
1607  ret = this->readPosFile(filename, q);
1608 
1609  if (ret == false) {
1610  vpERROR_TRACE ("Bad position in \"%s\"", filename);
1612  "Bad position in filename.");
1613  }
1616 }
1617 
1677 void
1679 {
1680  q.resize(6);
1681 
1682  switch(frame)
1683  {
1684  case vpRobot::CAMERA_FRAME :
1685  {
1686  q = 0;
1687  break ;
1688  }
1689 
1691  {
1692  q = get_artCoord();
1693  break ;
1694  }
1695 
1697  {
1698  vpHomogeneousMatrix fMc_;
1699  vpAfma6::get_fMc (get_artCoord(), fMc_);
1700 
1701  vpRotationMatrix fRc;
1702  fMc_.extract(fRc);
1703  vpRxyzVector rxyz(fRc);
1704 
1705  vpTranslationVector txyz;
1706  fMc_.extract(txyz);
1707 
1708  for (unsigned int i=0; i <3; i++)
1709  {
1710  q[i] = txyz[i];
1711  q[i+3] = rxyz[i];
1712  }
1713  break ;
1714  }
1715 
1716  case vpRobot::MIXT_FRAME:
1717  {
1718  vpERROR_TRACE ("Positionning error. Mixt frame not implemented");
1720  "Positionning error: "
1721  "Mixt frame not implemented.");
1722  break ;
1723  }
1724  }
1725 }
1726 
1753 void
1755 {
1756  timestamp = vpTime::measureTimeSecond();
1757  getPosition(frame, q);
1758 }
1759 
1760 
1771 void
1773 {
1774  vpColVector posRxyz;
1775  //recupere position en Rxyz
1776  this->getPosition(frame,posRxyz);
1777 
1778  //recupere le vecteur thetaU correspondant
1779  vpThetaUVector RtuVect(vpRxyzVector(posRxyz[3],posRxyz[4],posRxyz[5]));
1780 
1781  //remplit le vpPoseVector avec translation et rotation ThetaU
1782  for(unsigned int j=0;j<3;j++)
1783  {
1784  position[j]=posRxyz[j];
1785  position[j+3]=RtuVect[j];
1786  }
1787 }
1788 
1799 void
1801  vpPoseVector &position, double &timestamp)
1802 {
1803  timestamp = vpTime::measureTimeSecond();
1804  getPosition(frame, position);
1805 }
1806 
1813 void
1815 {
1816  if (limitMin.getRows() != 6 || limitMax.getRows() != 6)
1817  {
1818  vpTRACE("Joint limit vector has not a size of 6 !");
1819  return;
1820  }
1821 
1822  _joint_min[0] = limitMin[0];
1823  _joint_min[1] = limitMin[1];
1824  _joint_min[2] = limitMin[2];
1825  _joint_min[3] = limitMin[3];
1826  _joint_min[4] = limitMin[4];
1827  _joint_min[5] = limitMin[5];
1828 
1829  _joint_max[0] = limitMax[0];
1830  _joint_max[1] = limitMax[1];
1831  _joint_max[2] = limitMax[2];
1832  _joint_max[3] = limitMax[3];
1833  _joint_max[4] = limitMax[4];
1834  _joint_max[5] = limitMax[5];
1835 
1836 }
1837 
1843 bool
1845 {
1846  double q5 = q[4];
1847 
1848  bool cond = fabs(q5-M_PI/2) < 1e-1;
1849 
1850  if(cond)
1851  {
1852  J[0][3] = 0;
1853  J[0][4] = 0;
1854  J[1][3] = 0;
1855  J[1][4] = 0;
1856  J[3][3] = 0;
1857  J[3][4] = 0;
1858  J[5][3] = 0;
1859  J[5][4] = 0;
1860  return true;
1861  }
1862 
1863  return false;
1864 }
1865 
1869 int
1871 {
1872  int artNumb = 0;
1873  double diff = 0;
1874  double difft = 0;
1875 
1876  vpColVector articularCoordinates = get_artCoord();
1877 
1878  for (unsigned int i = 0; i < 6; i++)
1879  {
1880  if (articularCoordinates[i] <= _joint_min[i])
1881  {
1882  difft = _joint_min[i] - articularCoordinates[i];
1883  if (difft > diff)
1884  {
1885  diff = difft;
1886  artNumb = -(int)i-1;
1887  }
1888  }
1889  }
1890 
1891  for (unsigned int i = 0; i < 6; i++)
1892  {
1893  if (articularCoordinates[i] >= _joint_max[i])
1894  {
1895  difft = articularCoordinates[i] - _joint_max[i];
1896  if (difft > diff)
1897  {
1898  diff = difft;
1899  artNumb = (int)(i+1);
1900  }
1901  }
1902  }
1903 
1904  if (artNumb != 0)
1905  std::cout << "\nWarning: Velocity control stopped: axis " << fabs((float)artNumb) << " on joint limit!" <<std::endl;
1906 
1907  return artNumb;
1908 }
1909 
1921 void
1922 vpSimulatorAfma6::getCameraDisplacement(vpColVector &displacement)
1923 {
1924  getDisplacement(vpRobot::CAMERA_FRAME, displacement);
1925 }
1926 
1936 void
1937 vpSimulatorAfma6::getArticularDisplacement(vpColVector &displacement)
1938 {
1940 }
1941 
1960 void
1962  vpColVector &displacement)
1963 {
1964  displacement.resize (6);
1965  displacement = 0;
1966  vpColVector q_cur(6);
1967 
1968  q_cur = get_artCoord();
1969 
1970  if ( ! first_time_getdis )
1971  {
1972  switch (frame)
1973  {
1974  case vpRobot::CAMERA_FRAME:
1975  {
1976  std::cout << "getDisplacement() CAMERA_FRAME not implemented\n";
1977  return;
1978  break ;
1979  }
1980 
1982  {
1983  displacement = q_cur - q_prev_getdis;
1984  break ;
1985  }
1986 
1988  {
1989  std::cout << "getDisplacement() REFERENCE_FRAME not implemented\n";
1990  return;
1991  break ;
1992  }
1993 
1994  case vpRobot::MIXT_FRAME:
1995  {
1996  std::cout << "getDisplacement() MIXT_FRAME not implemented\n";
1997  return;
1998  break ;
1999  }
2000  }
2001  }
2002  else
2003  {
2004  first_time_getdis = false;
2005  }
2006 
2007  // Memorize the joint position for the next call
2008  q_prev_getdis = q_cur;
2009 }
2010 
2057 bool
2059 {
2060  FILE * fd ;
2061  fd = fopen(filename, "r") ;
2062  if (fd == NULL)
2063  return false;
2064 
2065  char line[FILENAME_MAX];
2066  char dummy[FILENAME_MAX];
2067  char head[] = "R:";
2068  bool sortie = false;
2069 
2070  do {
2071  // Saut des lignes commencant par #
2072  if (fgets (line, FILENAME_MAX, fd) != NULL) {
2073  if ( strncmp (line, "#", 1) != 0) {
2074  // La ligne n'est pas un commentaire
2075  if ( strncmp (line, head, sizeof(head)-1) == 0) {
2076  sortie = true; // Position robot trouvee.
2077  }
2078  // else
2079  // return (false); // fin fichier sans position robot.
2080  }
2081  }
2082  else {
2083  fclose(fd) ;
2084  return (false); /* fin fichier */
2085  }
2086 
2087  }
2088  while ( sortie != true );
2089 
2090  // Lecture des positions
2091  q.resize(njoint);
2092  int ret = sscanf(line, "%s %lf %lf %lf %lf %lf %lf",
2093  dummy,
2094  &q[0], &q[1], &q[2], &q[3], &q[4], &q[5]);
2095 
2096  if (ret != 7) {
2097  fclose(fd) ;
2098  return false;
2099  }
2100 
2101  // converts rotations from degrees into radians
2102  //q.deg2rad();
2103 
2104  q[3] = vpMath::rad(q[3]);
2105  q[4] = vpMath::rad(q[4]);
2106  q[5] = vpMath::rad(q[5]);
2107 
2108  fclose(fd) ;
2109  return (true);
2110 }
2111 
2134 bool
2135 vpSimulatorAfma6::savePosFile(const char *filename, const vpColVector &q)
2136 {
2137 
2138  FILE * fd ;
2139  fd = fopen(filename, "w") ;
2140  if (fd == NULL)
2141  return false;
2142 
2143  fprintf(fd, "\
2144 #AFMA6 - Position - Version 2.01\n\
2145 #\n\
2146 # R: X Y Z A B C\n\
2147 # Joint position: X, Y, Z: translations in meters\n\
2148 # A, B, C: rotations in degrees\n\
2149 #\n\
2150 #\n\n");
2151 
2152  // Save positions in mm and deg
2153  fprintf(fd, "R: %lf %lf %lf %lf %lf %lf\n",
2154  q[0],
2155  q[1],
2156  q[2],
2157  vpMath::deg(q[3]),
2158  vpMath::deg(q[4]),
2159  vpMath::deg(q[5]));
2160 
2161  fclose(fd) ;
2162  return (true);
2163 }
2164 
2172 void
2173 vpSimulatorAfma6::move(const char *filename)
2174 {
2175  vpColVector q;
2176 
2177  try
2178  {
2179  this->readPosFile(filename, q);
2182  }
2183  catch(...)
2184  {
2185  throw;
2186  }
2187 }
2188 
2198 void
2200 {
2201  vpAfma6::get_cMe(cMe) ;
2202 }
2203 
2211 void
2213 {
2214  vpHomogeneousMatrix cMe ;
2215  vpAfma6::get_cMe(cMe) ;
2216 
2217  cVe.buildFrom(cMe) ;
2218 }
2219 
2229 void
2231 {
2232  try
2233  {
2234  vpAfma6::get_eJe(get_artCoord(), eJe_) ;
2235  }
2236  catch(...)
2237  {
2238  vpERROR_TRACE("catch exception ") ;
2239  throw ;
2240  }
2241 }
2242 
2253 void
2255 {
2256  try
2257  {
2258  vpColVector articularCoordinates = get_artCoord();
2259  vpAfma6::get_fJe(articularCoordinates, fJe_) ;
2260  }
2261  catch(...)
2262  {
2263  vpERROR_TRACE("Error caught");
2264  throw ;
2265  }
2266 }
2267 
2271 void
2273 {
2275  return;
2276 
2277  vpColVector stop(6);
2278  stop = 0;
2279  set_artVel(stop);
2280  set_velocity(stop);
2282 }
2283 
2284 
2285 
2286 /**********************************************************************************/
2287 /**********************************************************************************/
2288 /**********************************************************************************/
2289 /**********************************************************************************/
2290 
2299 void
2301 {
2302  // set scene_dir from #define VISP_SCENE_DIR if it exists
2303  // VISP_SCENES_DIR may contain multiple locations separated by ";"
2304  std::string scene_dir_;
2305  std::vector<std::string> scene_dirs = vpIoTools::splitChain(std::string(VISP_SCENES_DIR), std::string(";"));
2306  bool sceneDirExists = false;
2307  for(size_t i=0; i < scene_dirs.size(); i++)
2308  if (vpIoTools::checkDirectory(scene_dirs[i]) == true) { // directory exists
2309  scene_dir_ = scene_dirs[i];
2310  sceneDirExists = true;
2311  break;
2312  }
2313  if (! sceneDirExists) {
2314  try {
2315  scene_dir_ = vpIoTools::getenv("VISP_SCENES_DIR");
2316  std::cout << "The simulator uses data from VISP_SCENES_DIR=" << scene_dir_ << std::endl;
2317  }
2318  catch (...) {
2319  std::cout << "Cannot get VISP_SCENES_DIR environment variable" << std::endl;
2320  }
2321  }
2322 
2323 
2324  unsigned int name_length = 30; // the size of this kind of string "/afma6_arm2.bnd"
2325  if (scene_dir_.size() > FILENAME_MAX)
2326  throw vpException (vpException::dimensionError, "Cannot initialize Afma6 simulator");
2327  unsigned int full_length = (unsigned int)scene_dir_.size() + name_length;
2328  if (full_length > FILENAME_MAX)
2329  throw vpException (vpException::dimensionError, "Cannot initialize Afma6 simulator");
2330 
2331  char *name_cam = new char [full_length];
2332 
2333  strcpy(name_cam, scene_dir_.c_str());
2334  strcat(name_cam,"/camera.bnd");
2335  set_scene(name_cam,&camera,cameraFactor);
2336 
2337  if (arm_dir.size() > FILENAME_MAX)
2338  throw vpException (vpException::dimensionError, "Cannot initialize Afma6 simulator");
2339  full_length = (unsigned int)arm_dir.size() + name_length;
2340  if (full_length > FILENAME_MAX)
2341  throw vpException (vpException::dimensionError, "Cannot initialize Afma6 simulator");
2342 
2343  char *name_arm = new char [full_length];
2344  strcpy(name_arm, arm_dir.c_str());
2345  strcat(name_arm,"/afma6_gate.bnd");
2346  std::cout <<"name arm: " << name_arm << std::endl;
2347  set_scene(name_arm, robotArms, 1.0);
2348  strcpy(name_arm, arm_dir.c_str());
2349  strcat(name_arm,"/afma6_arm1.bnd");
2350  set_scene(name_arm, robotArms+1, 1.0);
2351  strcpy(name_arm, arm_dir.c_str());
2352  strcat(name_arm,"/afma6_arm2.bnd");
2353  set_scene(name_arm, robotArms+2, 1.0);
2354  strcpy(name_arm, arm_dir.c_str());
2355  strcat(name_arm,"/afma6_arm3.bnd");
2356  set_scene(name_arm, robotArms+3, 1.0);
2357  strcpy(name_arm, arm_dir.c_str());
2358  strcat(name_arm,"/afma6_arm4.bnd");
2359  set_scene(name_arm, robotArms+4, 1.0);
2360 
2362  tool = getToolType();
2363  strcpy(name_arm, arm_dir.c_str());
2364  switch (tool) {
2365  case vpAfma6::TOOL_CCMOP: {
2366  strcat(name_arm,"/afma6_tool_ccmop.bnd");
2367  break;
2368  }
2369  case vpAfma6::TOOL_GRIPPER: {
2370  strcat(name_arm,"/afma6_tool_gripper.bnd");
2371  break;
2372  }
2373  case vpAfma6::TOOL_VACUUM: {
2374  strcat(name_arm,"/afma6_tool_vacuum.bnd");
2375  break;
2376  }
2378  std::cout << "The generic camera is not handled in vpSimulatorAfma6.cpp" << std::endl;
2379  break;
2380  }
2381  }
2382  set_scene(name_arm, robotArms+5, 1.0);
2383 
2384  add_rfstack(IS_BACK);
2385 
2386  add_vwstack ("start","depth", 0.0, 100.0);
2387  add_vwstack ("start","window", -0.1,0.1,-0.1,0.1);
2388  add_vwstack ("start","type", PERSPECTIVE);
2389 //
2390 // sceneInitialized = true;
2391 // displayObject = true;
2392  displayCamera = true;
2393 
2394  delete [] name_cam;
2395  delete [] name_arm;
2396 }
2397 
2398 
2399 void
2401 {
2402  bool changed = false;
2403  vpHomogeneousMatrix displacement = navigation(I_,changed);
2404 
2405  //if (displacement[2][3] != 0)
2406  if (std::fabs(displacement[2][3]) > std::numeric_limits<double>::epsilon())
2407  camMf2 = camMf2*displacement;
2408 
2409  f2Mf = camMf2.inverse()*camMf;
2410 
2411  camMf = camMf2* displacement * f2Mf;
2412 
2413  double u;
2414  double v;
2415  //if(px_ext != 1 && py_ext != 1)
2416  // we assume px_ext and py_ext > 0
2417  if( (std::fabs(px_ext-1.) > vpMath::maximum(px_ext,1.)*std::numeric_limits<double>::epsilon())
2418  && (std::fabs(py_ext-1) > vpMath::maximum(py_ext,1.)*std::numeric_limits<double>::epsilon()))
2419  {
2420  u = (double)I_.getWidth()/(2*px_ext);
2421  v = (double)I_.getHeight()/(2*py_ext);
2422  }
2423  else
2424  {
2425  u = (double)I_.getWidth()/(vpMath::minimum(I_.getWidth(),I_.getHeight()));
2426  v = (double)I_.getHeight()/(vpMath::minimum(I_.getWidth(),I_.getHeight()));
2427  }
2428 
2429  float w44o[4][4],w44cext[4][4],x,y,z;
2430 
2431  vp2jlc_matrix(camMf.inverse(),w44cext);
2432 
2433  add_vwstack ("start","cop", w44cext[3][0],w44cext[3][1],w44cext[3][2]);
2434  x = w44cext[2][0] + w44cext[3][0];
2435  y = w44cext[2][1] + w44cext[3][1];
2436  z = w44cext[2][2] + w44cext[3][2];
2437  add_vwstack ("start","vrp", x,y,z);
2438  add_vwstack ("start","vpn", w44cext[2][0],w44cext[2][1],w44cext[2][2]);
2439  add_vwstack ("start","vup", w44cext[1][0],w44cext[1][1],w44cext[1][2]);
2440  add_vwstack ("start","window", -u, u, -v, v);
2441 
2442  vpHomogeneousMatrix fMit[8];
2443  get_fMi(fMit);
2444 
2445  vp2jlc_matrix(vpHomogeneousMatrix(0,0,0,0,0,0),w44o);
2446  display_scene(w44o,robotArms[0],I_, curColor);
2447 
2448  vp2jlc_matrix(fMit[0],w44o);
2449  display_scene(w44o,robotArms[1],I_, curColor);
2450 
2451  vp2jlc_matrix(fMit[2],w44o);
2452  display_scene(w44o,robotArms[2],I_, curColor);
2453 
2454  vp2jlc_matrix(fMit[3],w44o);
2455  display_scene(w44o,robotArms[3],I_, curColor);
2456 
2457  vp2jlc_matrix(fMit[4],w44o);
2458  display_scene(w44o,robotArms[4],I_, curColor);
2459 
2460  vp2jlc_matrix(fMit[5],w44o);
2461  display_scene(w44o,robotArms[5],I_, curColor);
2462 
2463  if (displayCamera)
2464  {
2465  vpHomogeneousMatrix cMe;
2466  get_cMe(cMe);
2467  cMe = cMe.inverse();
2468  cMe = fMit[6] * cMe;
2469  vp2jlc_matrix(cMe,w44o);
2470  display_scene(w44o,camera, I_, camColor);
2471  }
2472 
2473  if (displayObject)
2474  {
2475  vp2jlc_matrix(fMo,w44o);
2476  display_scene(w44o,scene,I_, curColor);
2477  }
2478 }
2479 
2496 bool
2498 {
2499  vpColVector stop(6);
2500  bool status = true;
2501  stop = 0;
2502  set_artVel(stop);
2503  set_velocity(stop);
2504  vpHomogeneousMatrix fMc_;
2505  fMc_ = fMo * cMo_.inverse();
2506 
2507  vpColVector articularCoordinates = get_artCoord();
2508  int nbSol = getInverseKinematics(fMc_, articularCoordinates, true, verbose_);
2509 
2510  if (nbSol == 0) {
2511  status = false;
2512  vpERROR_TRACE ("Positionning error. Position unreachable");
2513  }
2514 
2515  if (verbose_)
2516  std::cout << "Used joint coordinates (rad): " << articularCoordinates.t() << std::endl;
2517 
2518  set_artCoord(articularCoordinates);
2519 
2520  compute_fMi();
2521 
2522  return status;
2523 }
2524 
2537 void
2539 {
2540  vpColVector stop(6);
2541  stop = 0;
2542  set_artVel(stop);
2543  set_velocity(stop);
2544  vpHomogeneousMatrix fMit[8];
2545  get_fMi(fMit);
2546  fMo = fMit[7] * cMo_;
2547 }
2548 
2559 bool
2561 {
2562  // get rid of max velocity
2563  double vMax = getMaxTranslationVelocity();
2564  double wMax = getMaxRotationVelocity();
2565  setMaxTranslationVelocity(10.*vMax);
2566  setMaxRotationVelocity(10.*wMax);
2567 
2568  vpColVector v(3),w(3),vel(6);
2569  vpHomogeneousMatrix cdMc;
2571  vpColVector err(6);err=1.;
2572  const double lambda = 5.;
2573  double t;
2574 
2576 
2577  unsigned int i,iter=0;
2578  while((iter++<300) & (err.euclideanNorm()>errMax))
2579  {
2580  t = vpTime::measureTimeMs();
2581 
2582  // update image
2583  if(Iint != NULL)
2584  {
2585  vpDisplay::display(*Iint);
2586  getInternalView(*Iint);
2587  vpDisplay::flush(*Iint);
2588  }
2589 
2590  // update pose error
2591  cdMc = cdMo_*get_cMo().inverse();
2592  cdMc.extract(cdRc);
2593  cdMc.extract(cdTc);
2594  cdTUc.buildFrom(cdRc);
2595 
2596  // compute v,w and velocity
2597  v = -lambda*cdRc.t()*cdTc;
2598  w = -lambda*cdTUc;
2599  for(i=0;i<3;++i)
2600  {
2601  vel[i] = v[i];
2602  vel[i+3] = w[i];
2603  err[i] = cdTc[i];
2604  err[i+3] = cdTUc[i];
2605  }
2606 
2607  // update feat
2609 
2610  // wait for it
2611  vpTime::wait(t,10);
2612  }
2613  vel=0.;
2614  set_velocity(vel);
2615  set_artVel(vel);
2617  setMaxRotationVelocity(wMax);
2618 
2619  //std::cout << "setPosition: final error " << err.t() << std::endl;
2620  return(err.euclideanNorm()<= errMax);
2621 }
2622 
2623 #elif !defined(VISP_BUILD_SHARED_LIBS)
2624 // Work arround to avoid warning: libvisp_robot.a(vpSimulatorAfma6.cpp.o) has no symbols
2625 void dummy_vpSimulatorAfma6() {};
2626 #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:514
Modelisation of Irisa's gantry robot named Afma6.
Definition: vpAfma6.h:65
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:92
vpRxyzVector _erc
Definition: vpAfma6.h:186
VISP_EXPORT int wait(double t0, double t)
Definition: vpTime.cpp:150
vpTranslationVector _etc
Definition: vpAfma6.h:185
static const unsigned int njoint
Number of joint.
Definition: vpAfma6.h:172
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:161
void setMaxTranslationVelocity(const double maxVt)
Definition: vpRobot.cpp:238
void get_eJe(vpMatrix &eJe)
int getInverseKinematics(const vpHomogeneousMatrix &fMc, vpColVector &q, const bool &nearest=true, const bool &verbose=false) const
Definition: vpAfma6.cpp:560
double getSamplingTime() const
vpAfma6ToolType getToolType() const
Get the current tool type.
Definition: vpAfma6.h:146
Implementation of an homogeneous matrix and operations on such kind of matrices.
void get_cVe(vpVelocityTwistMatrix &cVe)
double euclideanNorm() const
vpHomogeneousMatrix get_fMc(const vpColVector &q) const
Definition: vpAfma6.cpp:741
void move(const char *filename)
static void * launcher(void *arg)
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 ...
#define vpERROR_TRACE
Definition: vpDebug.h:391
VISP_EXPORT double measureTimeSecond()
Definition: vpTime.cpp:225
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:224
double getMaxTranslationVelocity(void) const
Definition: vpRobot.cpp:250
static const vpColor none
Definition: vpColor.h:175
Initialize the position controller.
Definition: vpRobot.h:69
void get_eJe(const vpColVector &q, vpMatrix &eJe) const
Definition: vpAfma6.cpp:895
error that can be emited by ViSP classes.
Definition: vpException.h:73
vpAfma6ToolType
List of possible tools that can be attached to the robot end-effector.
Definition: vpAfma6.h:104
void setJointLimit(const vpColVector &limitMin, const vpColVector &limitMax)
void track(const vpHomogeneousMatrix &cMo)
static const double defaultPositioningVelocity
vpRotationMatrix t() const
vpControlFrameType
Definition: vpRobot.h:76
double get_py() const
void getExternalImage(vpImage< vpRGBa > &I)
vpCameraParameters::vpCameraParametersProjType projModel
Definition: vpAfma6.h:194
double get_y() const
Get the point y coordinate in the image plane.
Definition: vpPoint.cpp:458
static const vpColor green
Definition: vpColor.h:166
vpHomogeneousMatrix fMo
static void flush(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:2233
double getMaxRotationVelocity(void) const
Definition: vpRobot.cpp:275
vpThetaUVector buildFrom(const vpHomogeneousMatrix &M)
void setPosition(const vpRobot::vpControlFrameType frame, const vpColVector &q)
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:201
Class that defines what is a point.
Definition: vpPoint.h:59
void setToolType(vpAfma6::vpAfma6ToolType tool)
Set the current tool type.
Definition: vpAfma6.h:170
bool initialiseCameraRelativeToObject(const vpHomogeneousMatrix &cMo)
static const char *const CONST_GRIPPER_CAMERA_NAME
Definition: vpAfma6.h:91
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:141
Implementation of a rotation matrix and operations on such kind of matrices.
void initPersProjWithoutDistortion(const double px, const double py, const double u0, const double v0)
void getDisplacement(const vpRobot::vpControlFrameType frame, vpColVector &displacement)
bool singularityTest(const vpColVector q, vpMatrix &J)
Initialize the velocity controller.
Definition: vpRobot.h:68
vpRobotStateType
Definition: vpRobot.h:64
void initialiseObjectRelativeToCamera(const vpHomogeneousMatrix &cMo)
void setExternalCameraPosition(const vpHomogeneousMatrix camMf_)
Initialize the acceleration controller.
Definition: vpRobot.h:70
vpVelocityTwistMatrix buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
#define vpTRACE
Definition: vpDebug.h:414
vpHomogeneousMatrix f2Mf
void set_displayBusy(const bool &status)
static void display(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:206
void get_cMe(vpHomogeneousMatrix &cMe) const
Definition: vpAfma6.cpp:857
vpRowVector t() const
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)
void extract(vpRotationMatrix &R) const
double get_x() const
Get the point x coordinate in the image plane.
Definition: vpPoint.cpp:456
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:1477
static Type minimum(const Type &a, const Type &b)
Definition: vpMath.h:152
void setCameraParameters(const vpCameraParameters &cam)
Implementation of a velocity twist matrix and operations on such kind of matrices.
unsigned int getRows() const
Return the number of rows of the 2D array.
Definition: vpArray2D.h:152
void set_velocity(const vpColVector &vel)
void getVelocity(const vpRobot::vpControlFrameType frame, vpColVector &q)
void buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
double get_px() const
static double rad(double deg)
Definition: vpMath.h:104
void setExternalCameraParameters(const vpCameraParameters &cam)
vpControlFrameType getRobotFrame(void) const
Definition: vpRobot.h:160
This class aims to be a basis used to create all the simulators of robots.
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:93
void setMaxRotationVelocity(const double maxVr)
Definition: vpRobot.cpp:262
double sumSquare() const
static void displayFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double size, const vpColor &color=vpColor::none, unsigned int thickness=1, vpImagePoint offset=vpImagePoint(0, 0))
Definition: vpDisplay.cpp:373
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)
double _long_56
Definition: vpAfma6.h:181
vpHomogeneousMatrix camMf
vpHomogeneousMatrix navigation(const vpImage< vpRGBa > &I, bool &changed)
static double deg(double rad)
Definition: vpMath.h:97
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
void get_fJe(vpMatrix &fJe)
Implementation of a pose vector and operations on poses.
Definition: vpPoseVector.h:93
vpHomogeneousMatrix inverse() const
vpHomogeneousMatrix _eMc
Definition: vpAfma6.h:188
virtual vpRobotStateType getRobotState(void) const
Definition: vpRobot.h:138
unsigned int getHeight() const
Definition: vpImage.h:152
Implementation of a rotation vector as Euler angle minimal representation.
Definition: vpRxyzVector.h:154
void getCameraParameters(vpCameraParameters &cam, const unsigned int &image_width, const unsigned int &image_height)
vpControlFrameType setRobotFrame(vpRobot::vpControlFrameType newFrame)
Definition: vpRobot.cpp:208
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:1756
double _joint_max[6]
Definition: vpAfma6.h:182
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
void set_artCoord(const vpColVector &coord)
virtual void displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)=0
VISP_EXPORT double getMinTimeForUsleepCall()
Definition: vpTime.cpp:82
void set_artVel(const vpColVector &vel)
void get_fMi(vpHomogeneousMatrix *fMit)
static const char *const CONST_CCMOP_CAMERA_NAME
Definition: vpAfma6.h:86
void get_fJe(const vpColVector &q, vpMatrix &fJe) const
Definition: vpAfma6.cpp:964
Class that consider the case of a translation vector.
Implementation of a rotation vector as axis-angle minimal representation.
vpHomogeneousMatrix camMf2
static bool savePosFile(const char *filename, const vpColVector &q)
double _joint_min[6]
Definition: vpAfma6.h:183
void findHighestPositioningSpeed(vpColVector &q)
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:217