Visual Servoing Platform  version 3.6.1 under development (2024-12-12)
vpRobotPololuPtu.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
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 https://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  * Common features for Pololu Maestro PanTiltUnit.
32  */
33 
34 #include <visp3/core/vpConfig.h>
35 
36 #if defined(VISP_HAVE_POLOLU) && defined(VISP_HAVE_THREADS)
37 
38 #include <visp3/core/vpDebug.h>
39 #include <visp3/robot/vpRobot.h>
40 #include <visp3/robot/vpRobotException.h>
41 #include <visp3/robot/vpRobotPololuPtu.h>
42 
43 BEGIN_VISP_NAMESPACE
44 vpRobotPololuPtu::vpRobotPololuPtu(const std::string &device, int baudrate, bool verbose)
45  : m_verbose(verbose)
46 {
47  nDof = 2;
48  m_pan.connect(device, baudrate, 0);
49  m_pan.setPwmRange(4095, 7905);
50  m_pan.setAngularRange(static_cast<float>(vpMath::rad(-45)), static_cast<float>(vpMath::rad(45)));
51  m_pan.setVerbose(verbose);
52 
53  m_tilt.connect(device, baudrate, 1);
54  m_tilt.setPwmRange(4095, 7905);
55  m_tilt.setAngularRange(static_cast<float>(vpMath::rad(-45)), static_cast<float>(vpMath::rad(45)));
56  m_tilt.setVerbose(verbose);
57 }
58 
60 {
61  m_pan.stopVelocityCmd();
62  m_tilt.stopVelocityCmd();
63 }
64 
66 {
67  vpColVector q(nDof);
69 
70  get_eJe(q, eJe);
71 }
72 
74 {
75  vpColVector q(nDof);
77 
78  get_fJe(q, fJe);
79 }
80 
82 {
83  eJe.resize(6, nDof);
84 
85  if (q.size() != static_cast<unsigned int>(nDof)) {
86  throw(vpException(vpException::dimensionError, "Bad dimension for Pololu PTU joint position vector"));
87  }
88 
89  double s2 = sin(q[1]);
90  double c2 = cos(q[1]);
91 
92  eJe = 0;
93 
94  eJe[3][0] = -c2;
95  eJe[4][1] = -1;
96  eJe[5][0] = s2;
97 }
98 
100 {
101  if (q.size() != static_cast<unsigned int>(nDof)) {
102  throw(vpException(vpException::dimensionError, "Bad dimension for Pololu PTU joint position vector"));
103  }
104 
105  fJe.resize(6, nDof);
106 
107  double s1 = sin(q[0]);
108  double c1 = cos(q[0]);
109 
110  fJe = 0;
111 
112  fJe[3][1] = s1;
113  fJe[4][1] = -c1;
114  fJe[5][0] = 1;
115 }
116 
118 {
119  return m_pan.speedToRadS(1);
120 }
121 
123 {
124  if (q.size() != static_cast<unsigned int>(nDof)) {
125  throw(vpException(vpException::dimensionError, "Bad dimension for Pololu PTU joint position vector"));
126  }
127 
129  std::cout << "Warning: Robot is not in position-based control. Modification of the robot state" << std::endl;
131  }
132 
133  switch (frame) {
135  throw vpRobotException(vpRobotException::wrongStateError, "Cannot move the robot in camera frame: "
136  "not implemented");
137  break;
139  throw vpRobotException(vpRobotException::wrongStateError, "Cannot move the robot in reference frame: "
140  "not implemented");
141  break;
142  case vpRobot::MIXT_FRAME:
143  throw vpRobotException(vpRobotException::wrongStateError, "Cannot move the robot in mixt frame: "
144  "not implemented");
145  break;
147  throw vpRobotException(vpRobotException::wrongStateError, "Cannot move the robot in end-effector frame: "
148  "not implemented");
149  break;
151  break;
152  }
153 
154  float pos_vel = m_positioning_velocity_percentage * static_cast<float>(getMaxRotationVelocity());
155  m_pan.setAngularPosition(static_cast<float>(q[0]), pos_vel);
156  m_tilt.setAngularPosition(static_cast<float>(q[1]), pos_vel);
157 }
158 
160 {
161  if (q_dot.size() != static_cast<unsigned int>(nDof)) {
162  throw(vpException(vpException::dimensionError, "Bad dimension for Pololu PTU joint position vector"));
163  }
164 
167  "Cannot send a velocity to the robot "
168  "use setRobotState(vpRobot::STATE_VELOCITY_CONTROL) first) ");
169  }
170 
171  switch (frame) {
172  case vpRobot::CAMERA_FRAME: {
173  throw vpRobotException(vpRobotException::wrongStateError, "Cannot send a velocity to the robot "
174  "in the camera frame:"
175  "functionality not implemented");
176  }
177  case vpRobot::JOINT_STATE: {
178  if (q_dot.getRows() != 2) {
179  throw vpRobotException(vpRobotException::wrongStateError, "Bad dimension for speed vector "
180  "in joint state");
181  }
182  break;
183  }
185  throw vpRobotException(vpRobotException::wrongStateError, "Cannot send a velocity to the robot "
186  "in the reference frame:"
187  "functionality not implemented");
188  }
189  case vpRobot::MIXT_FRAME: {
190  throw vpRobotException(vpRobotException::wrongStateError, "Cannot send a velocity to the robot "
191  "in the mixt frame:"
192  "functionality not implemented");
193  }
195  throw vpRobotException(vpRobotException::wrongStateError, "Cannot send a velocity to the robot "
196  "in the end-effector frame:"
197  "functionality not implemented");
198  }
199  default: {
200  throw vpRobotException(vpRobotException::wrongStateError, "Cannot send a velocity to the robot ");
201  }
202  }
203 
204  bool norm = false; // Flag to indicate when velocities need to be normalized
205 
206  // Saturate joint speed
207  double max = getMaxRotationVelocity();
208  vpColVector q_dot_sat(nDof);
209 
210  // Init q_dot_saturated
211  q_dot_sat = q_dot;
212 
213  for (unsigned int i = 0; i < static_cast<unsigned int>(nDof); ++i) { // q1 and q2
214  if (fabs(q_dot[i]) > max) {
215  norm = true;
216  max = fabs(q_dot[i]);
217  vpERROR_TRACE("Excess velocity: ROTATION "
218  "(axe nr.%d).",
219  i);
220  }
221  }
222  // Rotations velocities normalization
223  if (norm == true) {
224  max = getMaxRotationVelocity() / max;
225  q_dot_sat = q_dot * max;
226  }
227 
228  std::cout << "Send velocity: " << q_dot_sat.t() << std::endl;
229 
230  m_pan.setAngularVelocity(static_cast<float>(q_dot_sat[0]));
231  m_tilt.setAngularVelocity(static_cast<float>(q_dot_sat[1]));
232 }
233 
235 {
236  switch (newState) {
237  case vpRobot::STATE_STOP: {
239  stopVelocity();
240  }
241  break;
242  }
245  std::cout << "Switch from velocity to position control." << std::endl;
246  stopVelocity();
247  }
248 
249  break;
250  }
252  }
253  default:
254  break;
255  }
256 
257  return vpRobot::setRobotState(newState);
258 }
259 
261 {
262  m_pan.stopVelocityCmd();
263  m_tilt.stopVelocityCmd();
264 }
265 
267 {
268  switch (frame) {
270  throw vpRobotException(vpRobotException::wrongStateError, "Cannot get position in camera frame: "
271  "not implemented");
272  break;
274  throw vpRobotException(vpRobotException::wrongStateError, "Cannot get position in reference frame: "
275  "not implemented");
276  break;
277  case vpRobot::MIXT_FRAME:
278  throw vpRobotException(vpRobotException::wrongStateError, "Cannot get position in mixt frame: "
279  "not implemented");
280  break;
282  throw vpRobotException(vpRobotException::wrongStateError, "Cannot get position in end-effector frame: "
283  "not implemented");
284  break;
286  break;
287  }
288 
289  q.resize(nDof);
290  q[0] = m_pan.getAngularPosition();
291  q[1] = m_tilt.getAngularPosition();
292 }
293 END_VISP_NAMESPACE
294 #elif !defined(VISP_BUILD_SHARED_LIBS)
295 // Work around to avoid warning: libvisp_robot.a(vpRobotPololuPtu.cpp.o) has no symbols
296 void dummy_vpRobotPololuPtu() { };
297 #endif
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:362
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:349
unsigned int getRows() const
Definition: vpArray2D.h:347
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
vpRowVector t() const
void resize(unsigned int i, bool flagNullify=true)
Definition: vpColVector.h:1143
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ dimensionError
Bad dimension.
Definition: vpException.h:71
static double rad(double deg)
Definition: vpMath.h:129
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169
void setVerbose(bool verbose)
Definition: vpPololu.h:239
float speedToRadS(short speed) const
Definition: vpPololu.cpp:283
void setAngularVelocity(float vel_rad_s)
Definition: vpPololu.cpp:239
void setAngularRange(float min_angle, float max_angle)
Definition: vpPololu.h:184
void setPwmRange(unsigned short min_pwm, unsigned short max_pwm)
Definition: vpPololu.h:218
void connect(const std::string &device, int baudrate, int channel)
Definition: vpPololu.cpp:66
float getAngularPosition() const
Definition: vpPololu.cpp:166
void setAngularPosition(float pos_rad, float vel_rad_s=0.f)
Definition: vpPololu.cpp:194
void stopVelocityCmd()
Definition: vpPololu.cpp:288
Error that can be emitted by the vpRobot class and its derivatives.
@ wrongStateError
Wrong robot state.
void setVelocity(const vpRobot::vpControlFrameType frame, const vpColVector &q_dot) VP_OVERRIDE
void getPosition(const vpRobot::vpControlFrameType frame, vpColVector &q) VP_OVERRIDE
void get_eJe(vpMatrix &eJe) VP_OVERRIDE
~vpRobotPololuPtu() VP_OVERRIDE
vpRobotPololuPtu(const std::string &device="/dev/ttyACM0", int baudrate=9600, bool verbose=false)
vpRobot::vpRobotStateType setRobotState(const vpRobot::vpRobotStateType newState) VP_OVERRIDE
float getAngularVelocityResolution() const
void setPosition(const vpRobot::vpControlFrameType frame, const vpColVector &q) VP_OVERRIDE
void get_fJe(vpMatrix &fJe) VP_OVERRIDE
int nDof
number of degrees of freedom
Definition: vpRobot.h:104
vpMatrix eJe
robot Jacobian expressed in the end-effector frame
Definition: vpRobot.h:106
virtual vpRobotStateType getRobotState(void) const
Definition: vpRobot.h:155
vpControlFrameType
Definition: vpRobot.h:77
@ REFERENCE_FRAME
Definition: vpRobot.h:78
@ JOINT_STATE
Definition: vpRobot.h:82
@ MIXT_FRAME
Definition: vpRobot.h:88
@ CAMERA_FRAME
Definition: vpRobot.h:84
@ END_EFFECTOR_FRAME
Definition: vpRobot.h:83
vpRobotStateType
Definition: vpRobot.h:65
@ STATE_POSITION_CONTROL
Initialize the position controller.
Definition: vpRobot.h:68
@ STATE_VELOCITY_CONTROL
Initialize the velocity controller.
Definition: vpRobot.h:67
@ STATE_STOP
Stops robot motion especially in velocity and acceleration control.
Definition: vpRobot.h:66
double getMaxRotationVelocity(void) const
Definition: vpRobot.cpp:274
vpMatrix fJe
robot Jacobian expressed in the robot reference frame available
Definition: vpRobot.h:110
virtual vpRobotStateType setRobotState(const vpRobot::vpRobotStateType newState)
Definition: vpRobot.cpp:202