Visual Servoing Platform  version 3.1.0
vpRobotPtu46.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Interface for the ptu-46 robot.
33  *
34  * Authors:
35  * Fabien Spindler
36  *
37  *****************************************************************************/
38 
39 #include <signal.h>
40 #include <string.h>
41 
42 #include <visp3/core/vpConfig.h>
43 #ifdef VISP_HAVE_PTU46
44 
45 /* Headers des fonctions implementees. */
46 #include <visp3/core/vpDebug.h>
47 #include <visp3/core/vpIoTools.h>
48 #include <visp3/robot/vpPtu46.h>
49 #include <visp3/robot/vpRobotException.h>
50 #include <visp3/robot/vpRobotPtu46.h>
51 
52 /* ---------------------------------------------------------------------- */
53 /* --- STATIC ------------------------------------------------------------ */
54 /* ------------------------------------------------------------------------ */
55 
56 bool vpRobotPtu46::robotAlreadyCreated = false;
58 
59 /* ----------------------------------------------------------------------- */
60 /* --- CONSTRUCTOR ------------------------------------------------------ */
61 /* ---------------------------------------------------------------------- */
62 
72 vpRobotPtu46::vpRobotPtu46(const char *device) : vpRobot()
73 {
74  this->device = new char[FILENAME_MAX];
75 
76  sprintf(this->device, "%s", device);
77 
78  vpDEBUG_TRACE(12, "Open communication with Ptu-46.");
79  try {
80  init();
81  } catch (...) {
82  delete[] this->device;
83  vpERROR_TRACE("Error caught");
84  throw;
85  }
86 
87  try {
89  } catch (...) {
90  delete[] this->device;
91  vpERROR_TRACE("Error caught");
92  throw;
93  }
94  positioningVelocity = defaultPositioningVelocity;
95  return;
96 }
97 
98 /* ------------------------------------------------------------------------ */
99 /* --- DESTRUCTOR -------------------------------------------------------- */
100 /* ------------------------------------------------------------------------ */
101 
109 {
110 
112 
113  if (0 != ptu.close()) {
114  vpERROR_TRACE("Error while closing communications with the robot ptu-46.");
115  }
116 
117  vpRobotPtu46::robotAlreadyCreated = false;
118 
119  delete[] device;
120 
121  return;
122 }
123 
124 /* --------------------------------------------------------------------------
125  */
126 /* --- INITIALISATION -------------------------------------------------------
127  */
128 /* --------------------------------------------------------------------------
129  */
130 
141 {
142 
143  vpDEBUG_TRACE(12, "Open connection Ptu-46.");
144  if (0 != ptu.init(device)) {
145  vpERROR_TRACE("Cannot open connection with ptu-46.");
146  throw vpRobotException(vpRobotException::constructionError, "Cannot open connection with ptu-46");
147  }
148 
149  return;
150 }
151 
159 {
160  switch (newState) {
161  case vpRobot::STATE_STOP: {
163  ptu.stop();
164  }
165  break;
166  }
169  vpDEBUG_TRACE(12, "Passage vitesse -> position.");
170  ptu.stop();
171  } else {
172  vpDEBUG_TRACE(1, "Passage arret -> position.");
173  }
174  break;
175  }
178  vpDEBUG_TRACE(10, "Arret du robot...");
179  ptu.stop();
180  }
181  break;
182  }
183  default:
184  break;
185  }
186 
187  return vpRobot::setRobotState(newState);
188 }
189 
196 {
197  ptu.stop();
199 }
200 
212 {
214  vpPtu46::get_cMe(cMe);
215 
216  cVe.buildFrom(cMe);
217 }
218 
229 
241 {
242  vpColVector q(2);
244 
245  try {
246  vpPtu46::get_eJe(q, eJe);
247  } catch (...) {
248  vpERROR_TRACE("catch exception ");
249  throw;
250  }
251 }
252 
261 {
262  vpColVector q(2);
264 
265  try {
266  vpPtu46::get_fJe(q, fJe);
267  } catch (...) {
268  vpERROR_TRACE("Error caught");
269  throw;
270  }
271 }
272 
279 void vpRobotPtu46::setPositioningVelocity(const double velocity) { positioningVelocity = velocity; }
286 double vpRobotPtu46::getPositioningVelocity(void) { return positioningVelocity; }
287 
305 {
306 
308  vpERROR_TRACE("Robot was not in position-based control\n"
309  "Modification of the robot state");
311  }
312 
313  switch (frame) {
315  vpERROR_TRACE("Cannot move the robot in camera frame: "
316  "not implemented");
317  throw vpRobotException(vpRobotException::wrongStateError, "Cannot move the robot in camera frame: "
318  "not implemented");
319  break;
321  vpERROR_TRACE("Cannot move the robot in reference frame: "
322  "not implemented");
323  throw vpRobotException(vpRobotException::wrongStateError, "Cannot move the robot in reference frame: "
324  "not implemented");
325  break;
326  case vpRobot::MIXT_FRAME:
327  vpERROR_TRACE("Cannot move the robot in mixt frame: "
328  "not implemented");
329  throw vpRobotException(vpRobotException::wrongStateError, "Cannot move the robot in mixt frame: "
330  "not implemented");
331  break;
333  break;
334  }
335 
336  // Interface for the controller
337  double artpos[2];
338 
339  artpos[0] = q[0];
340  artpos[1] = q[1];
341 
342  if (0 != ptu.move(artpos, positioningVelocity, PTU_ABSOLUTE_MODE)) {
343  vpERROR_TRACE("Positionning error.");
344  throw vpRobotException(vpRobotException::lowLevelError, "Positionning error.");
345  }
346 
347  return;
348 }
349 
366 void vpRobotPtu46::setPosition(const vpRobot::vpControlFrameType frame, const double &q1, const double &q2)
367 {
368  try {
369  vpColVector q(2);
370  q[0] = q1;
371  q[1] = q2;
372 
373  setPosition(frame, q);
374  } catch (...) {
375  vpERROR_TRACE("Error caught");
376  throw;
377  }
378 }
379 
393 void vpRobotPtu46::setPosition(const char *filename)
394 {
395  vpColVector q;
396  if (readPositionFile(filename, q) == false) {
397  vpERROR_TRACE("Cannot get ptu-46 position from file");
398  throw vpRobotException(vpRobotException::readingParametersError, "Cannot get ptu-46 position from file");
399  }
401 }
402 
417 {
418  vpDEBUG_TRACE(9, "# Entree.");
419 
420  switch (frame) {
422  vpERROR_TRACE("Cannot get position in camera frame: not implemented");
423  throw vpRobotException(vpRobotException::lowLevelError, "Cannot get position in camera frame: "
424  "not implemented");
425  break;
427  vpERROR_TRACE("Cannot get position in reference frame: "
428  "not implemented");
429  throw vpRobotException(vpRobotException::lowLevelError, "Cannot get position in reference frame: "
430  "not implemented");
431  break;
432  case vpRobot::MIXT_FRAME:
433  vpERROR_TRACE("Cannot get position in mixt frame: "
434  "not implemented");
435  throw vpRobotException(vpRobotException::lowLevelError, "Cannot get position in mixt frame: "
436  "not implemented");
437  break;
439  break;
440  }
441 
442  double artpos[2];
443 
444  if (0 != ptu.getCurrentPosition(artpos)) {
445  vpERROR_TRACE("Error when calling recup_posit_Afma4.");
446  throw vpRobotException(vpRobotException::lowLevelError, "Error when calling recup_posit_Afma4.");
447  }
448 
450 
451  q[0] = artpos[0];
452  q[1] = artpos[1];
453 }
454 
485 {
486  TPtuFrame ptuFrameInterface;
487 
489  vpERROR_TRACE("Cannot send a velocity to the robot "
490  "use setRobotState(vpRobot::STATE_VELOCITY_CONTROL) first) ");
492  "Cannot send a velocity to the robot "
493  "use setRobotState(vpRobot::STATE_VELOCITY_CONTROL) first) ");
494  }
495 
496  switch (frame) {
497  case vpRobot::CAMERA_FRAME: {
498  ptuFrameInterface = PTU_CAMERA_FRAME;
499  if (v.getRows() != 2) {
500  vpERROR_TRACE("Bad dimension fo speed vector in camera frame");
501  throw vpRobotException(vpRobotException::wrongStateError, "Bad dimension for speed vector "
502  "in camera frame");
503  }
504  break;
505  }
507  ptuFrameInterface = PTU_ARTICULAR_FRAME;
508  if (v.getRows() != 2) {
509  vpERROR_TRACE("Bad dimension fo speed vector in articular frame");
510  throw vpRobotException(vpRobotException::wrongStateError, "Bad dimension for speed vector "
511  "in articular frame");
512  }
513  break;
514  }
516  vpERROR_TRACE("Cannot send a velocity to the robot "
517  "in the reference frame: "
518  "functionality not implemented");
519  throw vpRobotException(vpRobotException::wrongStateError, "Cannot send a velocity to the robot "
520  "in the reference frame:"
521  "functionality not implemented");
522  }
523  case vpRobot::MIXT_FRAME: {
524  vpERROR_TRACE("Cannot send a velocity to the robot "
525  "in the mixt frame: "
526  "functionality not implemented");
527  throw vpRobotException(vpRobotException::wrongStateError, "Cannot send a velocity to the robot "
528  "in the mixt frame:"
529  "functionality not implemented");
530  }
531  default: {
532  vpERROR_TRACE("Error in spec of vpRobot. "
533  "Case not taken in account.");
534  throw vpRobotException(vpRobotException::wrongStateError, "Cannot send a velocity to the robot ");
535  }
536  }
537 
538  vpDEBUG_TRACE(12, "Velocity limitation.");
539  double ptuSpeedInterface[2];
540 
541  switch (frame) {
543  case vpRobot::CAMERA_FRAME: {
544  double max = this->maxRotationVelocity;
545  bool norm = false; // Flag to indicate when velocities need to be nomalized
546  for (unsigned int i = 0; i < 2; ++i) // rx and ry of the camera
547  {
548  if (fabs(v[i]) > max) {
549  norm = true;
550  max = fabs(v[i]);
551  vpERROR_TRACE("Excess velocity: ROTATION "
552  "(axe nr.%d).",
553  i);
554  }
555  }
556  // Rotations velocities normalisation
557  if (norm == true) {
558  max = this->maxRotationVelocity / max;
559  for (unsigned int i = 0; i < 2; ++i)
560  ptuSpeedInterface[i] = v[i] * max;
561  }
562  break;
563  }
564  default:
565  // Should never occur
566  break;
567  }
568 
569  vpCDEBUG(12) << "v: " << ptuSpeedInterface[0] << " " << ptuSpeedInterface[1] << std::endl;
570  ptu.move(ptuSpeedInterface, ptuFrameInterface);
571  return;
572 }
573 
574 /* -------------------------------------------------------------------------
575  */
576 /* --- GET -----------------------------------------------------------------
577  */
578 /* -------------------------------------------------------------------------
579  */
580 
593 {
594 
595  TPtuFrame ptuFrameInterface = PTU_ARTICULAR_FRAME;
596 
597  switch (frame) {
598  case vpRobot::CAMERA_FRAME: {
599  vpERROR_TRACE("Cannot get a velocity in the camera frame: "
600  "functionality not implemented");
601  throw vpRobotException(vpRobotException::wrongStateError, "Cannot get a velocity in the camera frame:"
602  "functionality not implemented");
603  }
605  ptuFrameInterface = PTU_ARTICULAR_FRAME;
606  break;
607  }
609  vpERROR_TRACE("Cannot get a velocity in the reference frame: "
610  "functionality not implemented");
611  throw vpRobotException(vpRobotException::wrongStateError, "Cannot get a velocity in the reference frame:"
612  "functionality not implemented");
613  }
614  case vpRobot::MIXT_FRAME: {
615 
616  vpERROR_TRACE("Cannot get a velocity in the mixt frame: "
617  "functionality not implemented");
618  throw vpRobotException(vpRobotException::wrongStateError, "Cannot get a velocity in the mixt frame:"
619  "functionality not implemented");
620  }
621  }
622 
623  q_dot.resize(vpPtu46::ndof);
624  double ptuSpeedInterface[2];
625 
626  ptu.getCurrentSpeed(ptuSpeedInterface, ptuFrameInterface);
627 
628  q_dot[0] = ptuSpeedInterface[0];
629  q_dot[1] = ptuSpeedInterface[1];
630 }
631 
644 {
645  vpColVector q_dot;
646  getVelocity(frame, q_dot);
647 
648  return q_dot;
649 }
650 
670 bool vpRobotPtu46::readPositionFile(const std::string &filename, vpColVector &q)
671 {
672  std::ifstream fd(filename.c_str(), std::ios::in);
673 
674  if (!fd.is_open()) {
675  return false;
676  }
677 
678  std::string line;
679  std::string key("R:");
680  std::string id("#PTU-EVI - Position");
681  bool pos_found = false;
682  int lineNum = 0;
683 
685 
686  while (std::getline(fd, line)) {
687  lineNum++;
688  if (lineNum == 1) {
689  if (!(line.compare(0, id.size(), id) == 0)) { // check if Ptu-46 position file
690  std::cout << "Error: this position file " << filename << " is not for Ptu-46 robot" << std::endl;
691  return false;
692  }
693  }
694  if ((line.compare(0, 1, "#") == 0)) { // skip comment
695  continue;
696  }
697  if ((line.compare(0, key.size(), key) == 0)) { // decode position
698  // check if there are at least njoint values in the line
699  std::vector<std::string> chain = vpIoTools::splitChain(line, std::string(" "));
700  if (chain.size() < vpPtu46::ndof + 1) // try to split with tab separator
701  chain = vpIoTools::splitChain(line, std::string("\t"));
702  if (chain.size() < vpPtu46::ndof + 1)
703  continue;
704 
705  std::istringstream ss(line);
706  std::string key_;
707  ss >> key_;
708  for (unsigned int i = 0; i < vpPtu46::ndof; i++)
709  ss >> q[i];
710  pos_found = true;
711  break;
712  }
713  }
714 
715  // converts rotations from degrees into radians
716  q.deg2rad();
717 
718  fd.close();
719 
720  if (!pos_found) {
721  std::cout << "Error: unable to find a position for Ptu-46 robot in " << filename << std::endl;
722  return false;
723  }
724 
725  return true;
726 }
727 
748 {
749  double d_[6];
750 
751  switch (frame) {
752  case vpRobot::CAMERA_FRAME: {
753  d.resize(6);
754  ptu.measureDpl(d_, PTU_CAMERA_FRAME);
755  d[0] = d_[0];
756  d[1] = d_[1];
757  d[2] = d_[2];
758  d[3] = d_[3];
759  d[4] = d_[4];
760  d[5] = d_[5];
761  break;
762  }
764  ptu.measureDpl(d_, PTU_ARTICULAR_FRAME);
766  d[0] = d_[0]; // pan
767  d[1] = d_[1]; // tilt
768  break;
769  }
771  vpERROR_TRACE("Cannot get a displacement in the reference frame: "
772  "functionality not implemented");
773  throw vpRobotException(vpRobotException::wrongStateError, "Cannot get a displacement in the reference frame:"
774  "functionality not implemented");
775  }
776  case vpRobot::MIXT_FRAME: {
777  vpERROR_TRACE("Cannot get a displacement in the mixt frame: "
778  "functionality not implemented");
779  throw vpRobotException(vpRobotException::wrongStateError, "Cannot get a displacement in the reference frame:"
780  "functionality not implemented");
781  }
782  }
783 }
784 
785 #elif !defined(VISP_BUILD_SHARED_LIBS)
786 // Work arround to avoid warning: libvisp_robot.a(vpRobotPtu46.cpp.o) has no
787 // symbols
788 void dummy_vpRobotPtu46(){};
789 #endif
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:104
Error that can be emited by the vpRobot class and its derivates.
void setPosition(const vpRobot::vpControlFrameType frame, const vpColVector &q)
void getVelocity(const vpRobot::vpControlFrameType frame, vpColVector &q_dot)
Implementation of an homogeneous matrix and operations on such kind of matrices.
void get_cMe(vpHomogeneousMatrix &_cMe) const
Definition: vpPtu46.cpp:210
#define vpERROR_TRACE
Definition: vpDebug.h:393
void setVelocity(const vpRobot::vpControlFrameType frame, const vpColVector &q_dot)
static const double defaultPositioningVelocity
Definition: vpRobotPtu46.h:97
void getPosition(const vpRobot::vpControlFrameType frame, vpColVector &q)
double maxRotationVelocity
Definition: vpRobot.h:93
Initialize the position controller.
Definition: vpRobot.h:68
void getDisplacement(vpRobot::vpControlFrameType frame, vpColVector &q)
unsigned int getRows() const
Definition: vpArray2D.h:156
Class that defines a generic virtual robot.
Definition: vpRobot.h:58
vpControlFrameType
Definition: vpRobot.h:75
void get_fJe(vpMatrix &_fJe)
virtual vpRobotStateType setRobotState(const vpRobot::vpRobotStateType newState)
Definition: vpRobot.cpp:201
vpRobot::vpRobotStateType setRobotState(vpRobot::vpRobotStateType newState)
void deg2rad()
Definition: vpColVector.h:134
void get_cVe(vpVelocityTwistMatrix &_cVe) const
Initialize the velocity controller.
Definition: vpRobot.h:67
static const unsigned int ndof
Definition: vpPtu46.h:80
virtual vpRobotStateType getRobotState(void) const
Definition: vpRobot.h:139
vpRobotStateType
Definition: vpRobot.h:64
virtual ~vpRobotPtu46(void)
vpVelocityTwistMatrix buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
#define vpCDEBUG(level)
Definition: vpDebug.h:511
void init(void)
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:1665
void get_eJe(vpMatrix &_eJe)
double getPositioningVelocity(void)
vpMatrix eJe
robot Jacobian expressed in the end-effector frame
Definition: vpRobot.h:99
void get_eJe(const vpColVector &q, vpMatrix &eJe) const
Definition: vpPtu46.cpp:249
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
void get_cMe(vpHomogeneousMatrix &_cMe) const
#define vpDEBUG_TRACE
Definition: vpDebug.h:487
bool readPositionFile(const std::string &filename, vpColVector &q)
vpMatrix fJe
robot Jacobian expressed in the robot reference frame available
Definition: vpRobot.h:103
void get_fJe(const vpColVector &q, vpMatrix &fJe) const
Definition: vpPtu46.cpp:278
void setPositioningVelocity(const double velocity)
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:241