Hekateros  3.4.3
RoadNarrows Robotics Robot Arm Project
hekCalib.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: Hekateros
4 //
5 // Library: libhekateros
6 //
7 // File: hekCalib.cxx
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2015-01-15 12:45:22 -0700 (Thu, 15 Jan 2015) $
12  * $Rev: 3857 $
13  *
14  * \brief HekCalib - Hekateros calibration abstract base class implementation.
15  *
16  * \author Robin Knight (robin.knight@roadnarrows.com)
17  *
18  * \copyright
19  * \h_copy 2013-2018. RoadNarrows LLC.\n
20  * http://www.roadnarrows.com\n
21  * All Rights Reserved
22  */
23 /*
24  * @EulaBegin@
25  *
26  * Unless otherwise stated explicitly, all materials contained are copyrighted
27  * and may not be used without RoadNarrows LLC's written consent,
28  * except as provided in these terms and conditions or in the copyright
29  * notice (documents and software) or other proprietary notice provided with
30  * the relevant materials.
31  *
32  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY
33  * MEMBERS/EMPLOYEES/CONTRACTORS OF ROADNARROWS OR DISTRIBUTORS OF THIS SOFTWARE
34  * BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
35  * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
36  * DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN
37  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38  *
39  * THE AUTHORS AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
40  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
41  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
42  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
43  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
44  *
45  * @EulaEnd@
46  */
47 ////////////////////////////////////////////////////////////////////////////////
48 
49 #include <unistd.h>
50 
51 #include "rnr/rnrconfig.h"
52 
53 #include "Dynamixel/Dynamixel.h"
54 #include "Dynamixel/DynaServo.h"
55 
56 #include "Hekateros/hekateros.h"
57 #include "Hekateros/hekCalib.h"
58 #include "Hekateros/hekRobot.h"
59 #include "Hekateros/hekUtils.h"
60 
61 
62 using namespace std;
63 using namespace hekateros;
64 
65 double HekCalib::moveWait(const string &strJointName,
66  const double fJointGoalPos,
67  const double fJointGoalVel)
68 {
69  static const int TuneMaxSecs = 30; // max of 30 seconds to complete move
70  static const int TuneWaituSec = 300000; // usec sleep between tests
71 
72  int nMaxIters = TuneMaxSecs * MILLION / TuneWaituSec; // max iterations
73 
74  double fJointCurPos, fJointCurVel;
75 
76  LOGDIAG3("%s(): Move joint %s to goalpos=%.2lf at goalvel=%.3lf", LOGFUNCNAME,
77  strJointName.c_str(), radToDeg(fJointGoalPos), radToDeg(fJointGoalVel));
78 
79  // start move
80  m_robot.m_pKin->move(strJointName, fJointGoalPos, fJointGoalVel);
81 
82  //
83  // Wait until move is completed, interrupted, or the maximum seconds reached.
84  //
85  for(int i=0; i<nMaxIters; ++i)
86  {
87  if( m_robot.m_pKin->isStopped(strJointName) )
88  {
89  LOGDIAG3("%s(): %s is stopped.", LOGFUNCNAME, strJointName.c_str());
90  break;
91  }
92 
93  m_robot.m_pKin->getJointCurPosVel(strJointName, fJointCurPos, fJointCurVel);
94 
95  LOGDIAG3("%s(): %s at curpos=%.2lf, curvel=%.3lf", LOGFUNCNAME,
96  strJointName.c_str(), radToDeg(fJointCurPos), radToDeg(fJointCurVel));
97 
98  // sleep (and a pthread cancelation point)
99  usleep(TuneWaituSec);
100  }
101 
102  m_robot.m_pKin->getJointCurPosVel(strJointName, fJointCurPos, fJointCurVel);
103 
104  LOGDIAG3("%s(): Joint %s move ended at to curpos=%.2lf", LOGFUNCNAME,
105  strJointName.c_str(), radToDeg(fJointCurPos));
106 
107  return fJointCurPos;
108 }
109 
110 double HekCalib::moveToTorqueLimit(const string &strJointName,
111  const double fJointGoalPos,
112  const double fJointGoalVel)
113 {
114  static const int TuneMaxSecs = 30; // max of 30 seconds to complete move
115  static const int TuneWaituSec = 300000; // usec sleep between tests
116 
117  int nMaxIters = TuneMaxSecs * MILLION / TuneWaituSec; // max iterations
118 
119  double fJointCurPos, fJointCurVel;
120 
121  LOGDIAG3("%s(): Move joint %s to goalpos=%.2lf at goalvel=%.3lf", LOGFUNCNAME,
122  strJointName.c_str(), radToDeg(fJointGoalPos), radToDeg(fJointGoalVel));
123 
124  // start move
125  m_robot.m_pKin->move(strJointName, fJointGoalPos, fJointGoalVel);
126 
127  //
128  // Wait until move is completed, interrupted, or the maximum seconds reached.
129  //
130  for(int i=0; i<nMaxIters; ++i)
131  {
132  // physically blocked
133  if( m_robot.m_pKin->hasOverTorqueCondition(strJointName) )
134  {
135  LOGDIAG3("%s(): %s in over torque condition.", LOGFUNCNAME,
136  strJointName.c_str());
137  break;
138  }
139 
140  // joint kinematics stopped
141  else if( m_robot.m_pKin->isStopped(strJointName) )
142  {
143  LOGDIAG3("%s(): %s is stopped.", LOGFUNCNAME, strJointName.c_str());
144  break;
145  }
146 
147  m_robot.m_pKin->getJointCurPosVel(strJointName, fJointCurPos, fJointCurVel);
148 
149  LOGDIAG3("%s(): %s at curpos=%.2lf, curvel=%.3lf", LOGFUNCNAME,
150  strJointName.c_str(), radToDeg(fJointCurPos), radToDeg(fJointCurVel));
151 
152  // sleep (and a pthread cancelation point)
153  usleep(TuneWaituSec);
154  }
155 
156  m_robot.m_pKin->getJointCurPosVel(strJointName, fJointCurPos, fJointCurVel);
157 
158  LOGDIAG3("%s(): Joint %s move ended at to curpos=%.2lf", LOGFUNCNAME,
159  strJointName.c_str(), radToDeg(fJointCurPos));
160 
161  return fJointCurPos;
162 }
163 
164 double HekCalib::moveToLight(const string &strJointName,
165  const double fJointGoalPos,
166  const double fJointGoalVel,
167  byte_t byMask)
168 {
169  static const int TuneMaxSecs = 30; // max of 30 seconds to complete move
170  static const int TuneWaituSec = 200000; // usec sleep between tests
171 
172  int nMaxIters = TuneMaxSecs * MILLION / TuneWaituSec; // max iterations
173 
174  double fJointCurPos, fJointCurVel;
175  byte_t byLimits;
176 
177  LOGDIAG3("%s(): Move %s to goalpos=%.2lf at goalvel=%.3lf", LOGFUNCNAME,
178  strJointName.c_str(), radToDeg(fJointGoalPos), radToDeg(fJointGoalVel));
179 
180  // start move
181  m_robot.m_pKin->move(strJointName, fJointGoalPos, fJointGoalVel);
182 
183  // wait until move is completed or maximum seconds reached.
184  for(int i=0; i<nMaxIters; ++i)
185  {
186  // physically blocked
187  if( m_robot.m_pKin->hasOverTorqueCondition(strJointName) )
188  {
189  LOGDIAG3("%s(): %s in over torque condition.", LOGFUNCNAME,
190  strJointName.c_str());
191  break;
192  }
193 
194  // joint kinematics stopped
195  else if( m_robot.m_pKin->isStopped(strJointName) )
196  {
197  LOGDIAG3("%s(): %s is stopped.", LOGFUNCNAME, strJointName.c_str());
198  break;
199  }
200 
201  // optical limits
202  byLimits = m_robot.m_monitor.getJointLimitBits();
203 
204  // light
205  if( getLitOpticalLimits(byLimits, byMask) != 0 )
206  {
207  LOGDIAG3("%s(): %s reached the light.", LOGFUNCNAME,
208  strJointName.c_str());
209  break;
210  }
211 
212  m_robot.m_pKin->getJointCurPosVel(strJointName, fJointCurPos, fJointCurVel);
213 
214  LOGDIAG3("%s(): %s at curpos=%.2lf, curvel=%.3lf", LOGFUNCNAME,
215  strJointName.c_str(), radToDeg(fJointCurPos), radToDeg(fJointCurVel));
216 
217  // sleep (and a pthread cancelation point)
218  usleep(TuneWaituSec);
219  }
220 
221  m_robot.m_pKin->stop(strJointName);
222 
223  usleep(TuneWaituSec);
224 
225  byLimits = m_robot.m_monitor.getJointLimitBits();
226 
227  if( getLitOpticalLimits(byLimits, byMask) == 0 )
228  {
229  LOGWARN("%s(): %s stopped before finding the light.", LOGFUNCNAME,
230  strJointName.c_str());
231  }
232 
233  m_robot.m_pKin->getJointCurPosVel(strJointName, fJointCurPos, fJointCurVel);
234 
235  LOGDIAG3("%s(): Joint %s move ended at to curpos=%.2lf", LOGFUNCNAME,
236  strJointName.c_str(), radToDeg(fJointCurPos));
237 
238  return fJointCurPos;
239 }
240 
241 double HekCalib::moveToDark(const string &strJointName,
242  const double fJointGoalPos,
243  const double fJointGoalVel,
244  byte_t byMask)
245 {
246  static const int TuneMaxSecs = 30; // max of 30 seconds to complete move
247  static const int TuneWaituSec = 200000; // usec sleep between tests
248 
249  int nMaxIters = TuneMaxSecs * MILLION / TuneWaituSec; // max iterations
250 
251  double fJointCurPos, fJointCurVel;
252  byte_t byLimits;
253 
254  LOGDIAG3("%s(): Move %s to goalpos=%.2lf at goalvel=%.3lf", LOGFUNCNAME,
255  strJointName.c_str(), radToDeg(fJointGoalPos), radToDeg(fJointGoalVel));
256 
257  // start move
258  m_robot.m_pKin->move(strJointName, fJointGoalPos, fJointGoalVel);
259 
260  // wait until move is completed or maximum seconds reached.
261  for(int i=0; i<nMaxIters; ++i)
262  {
263  // physically blocked
264  if( m_robot.m_pKin->hasOverTorqueCondition(strJointName) )
265  {
266  LOGDIAG3("%s(): %s in over torque condition.", LOGFUNCNAME,
267  strJointName.c_str());
268  break;
269  }
270 
271  // joint kinematics stopped
272  else if( m_robot.m_pKin->isStopped(strJointName) )
273  {
274  LOGDIAG3("%s(): %s is stopped.", LOGFUNCNAME, strJointName.c_str());
275  break;
276  }
277 
278  // optical limits
279  byLimits = m_robot.m_monitor.getJointLimitBits();
280 
281  // dark
282  if( getDarkOpticalLimits(byLimits, byMask) != 0 )
283  {
284  LOGDIAG3("%s(): %s reached the dark.", LOGFUNCNAME,
285  strJointName.c_str());
286  break;
287  }
288 
289  m_robot.m_pKin->getJointCurPosVel(strJointName, fJointCurPos, fJointCurVel);
290 
291  LOGDIAG3("%s(): %s at curpos=%.2lf, curvel=%.3lf", LOGFUNCNAME,
292  strJointName.c_str(), radToDeg(fJointCurPos), radToDeg(fJointCurVel));
293 
294  // sleep (and a pthread cancelation point)
295  usleep(TuneWaituSec);
296  }
297 
298  m_robot.m_pKin->stop(strJointName);
299 
300  usleep(TuneWaituSec);
301 
302  byLimits = m_robot.m_monitor.getJointLimitBits();
303 
304  if( getDarkOpticalLimits(byLimits, byMask) == 0 )
305  {
306  LOGWARN("%s(): %s stopped before finding the dark.", LOGFUNCNAME,
307  strJointName.c_str());
308  }
309 
310  m_robot.m_pKin->getJointCurPosVel(strJointName, fJointCurPos, fJointCurVel);
311 
312  LOGDIAG3("%s(): Joint %s move ended at to curpos=%.2lf", LOGFUNCNAME,
313  strJointName.c_str(), radToDeg(fJointCurPos));
314 
315  return fJointCurPos;
316 }
HekCalib - Hekateros calibration abstract base class interface.
double radToDeg(double r)
Convert radians to degrees.
Definition: hekUtils.h:137
static byte_t getDarkOpticalLimits(byte_t byBits, byte_t byMask)
Test if any of the optical limits have been triggered (occluded).
Definition: hekOptical.h:194
HekRobot - Hekateros Robot Class interface.
Top-level package include file.
static byte_t getLitOpticalLimits(byte_t byBits, byte_t byMask)
Test if any of the optical limits are lit (not occluded).
Definition: hekOptical.h:209
Hekateros common utilities.
The <b><i>Hekateros</i></b> namespace encapsulates all <b><i>Hekateros</i></b> related constructs...
Definition: hekateros.h:56