Hekateros  3.4.3
RoadNarrows Robotics Robot Arm Project
hekMonitor.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: Hekateros
4 //
5 // Library: libhekateros
6 //
7 // File: hekMonitor.cxx
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2015-05-01 16:17:27 -0600 (Fri, 01 May 2015) $
12  * $Rev: 3976 $
13  *
14  * \brief HekMonitor - Hekateros Monitor Class implementation.
15  *
16  * \author Robin Knight (robin.knight@roadnarrows.com)
17  * \author Daniel Packard (daniel@roadnarrows.com)
18  *
19  * \copyright
20  * \h_copy 2014-2017. RoadNarrows LLC.\n
21  * http://www.roadnarrows.com\n
22  * All Rights Reserved
23  */
24 /*
25  * @EulaBegin@
26  *
27  * Unless otherwise stated explicitly, all materials contained are copyrighted
28  * and may not be used without RoadNarrows LLC's written consent,
29  * except as provided in these terms and conditions or in the copyright
30  * notice (documents and software) or other proprietary notice provided with
31  * the relevant materials.
32  *
33  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY
34  * MEMBERS/EMPLOYEES/CONTRACTORS OF ROADNARROWS OR DISTRIBUTORS OF THIS SOFTWARE
35  * BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
36  * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
37  * DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN
38  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  * THE AUTHORS AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
41  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
42  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
43  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
44  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
45  *
46  * @EulaEnd@
47  */
48 ////////////////////////////////////////////////////////////////////////////////
49 
50 #include <sys/time.h>
51 #include <sys/types.h>
52 #include <time.h>
53 #include <stdio.h>
54 #include <unistd.h>
55 #include <pthread.h>
56 
57 #include <string>
58 #include <map>
59 
60 #include "rnr/rnrconfig.h"
61 #include "rnr/units.h"
62 #include "rnr/log.h"
63 
64 #ifdef HEK_HAS_SYS_BOARD
65 #include "rnr/i2c.h"
66 #endif // HEK_HAS_SYS_BOARD
67 
68 #include "Dynamixel/Dynamixel.h"
69 #include "Dynamixel/DynaComm.h"
70 #include "Dynamixel/DynaServo.h"
71 #include "Dynamixel/DynaChain.h"
72 #include "Dynamixel/DynaBgThread.h"
73 #include "Dynamixel/DynaError.h"
74 
75 #include "Hekateros/hekateros.h"
76 #include "Hekateros/hekUtils.h"
77 #include "Hekateros/hekOptical.h"
78 #include "Hekateros/hekUno.h"
79 #include "Hekateros/hekSpec.h"
80 #include "Hekateros/hekDesc.h"
81 #include "Hekateros/hekJoint.h"
82 #include "Hekateros/hekTraj.h"
83 #include "Hekateros/hekState.h"
84 #include "Hekateros/hekMonitor.h"
85 #include "Hekateros/hekUtils.h"
86 
87 using namespace std;
88 using namespace hekateros;
89 
90 
91 // -----------------------------------------------------------------------------
92 // Private Interface
93 // -----------------------------------------------------------------------------
94 
95 #define KILOSEC 1000
96 #define MEGASEC 1000000
97 #define GIGASEC 1000000000
98 
99 // RDK timeval and timespec should be classes and placed in appkit.
100 struct timespec now()
101 {
102  struct timeval tv;
103  struct timespec ts;
104 
105  clock_gettime(CLOCK_REALTIME, &ts);
106 
107  return ts;
108 }
109 
110 // t1 + t2
111 struct timespec add(const struct timespec &t1, const struct timespec &t2)
112 {
113  struct timespec t3;
114 
115  t3.tv_sec = t1.tv_sec + t2.tv_sec;
116  t3.tv_nsec = t1.tv_nsec + t2.tv_nsec;
117 
118  if( t3.tv_nsec >= GIGASEC )
119  {
120  t3.tv_sec += 1;
121  t3.tv_nsec -= GIGASEC;
122  }
123 
124  return t3;
125 }
126 
127 // t1 - t2
128 struct timespec sub(const struct timespec &t1, const struct timespec &t2)
129 {
130  struct timespec t3;
131 
132  t3.tv_sec = t1.tv_sec - t2.tv_sec;
133  t3.tv_nsec = t1.tv_nsec - t2.tv_nsec;
134 
135  if( t3.tv_nsec < 0 )
136  {
137  t3.tv_sec -= 1;
138  t3.tv_nsec += GIGASEC;
139  }
140 
141  return t3;
142 }
143 
144 // t1 <= t2
145 bool le(const struct timespec &t1, const struct timespec &t2)
146 {
147  if( t1.tv_sec < t2.tv_sec )
148  {
149  return true;
150  }
151  else if( t1.tv_sec > t2.tv_sec )
152  {
153  return false;
154  }
155  else if( t1.tv_nsec < t2.tv_nsec )
156  {
157  return true;
158  }
159  else if( t1.tv_nsec > t2.tv_nsec )
160  {
161  return false;
162  }
163  else
164  {
165  return true;
166  }
167 }
168 
169 // time to double
170 double ttod(const struct timespec &t)
171 {
172  return (double)t.tv_sec + ((double)t.tv_nsec)/((double)GIGASEC);
173 }
174 
175 
176 // -----------------------------------------------------------------------------
177 // Class HekMonitor
178 // -----------------------------------------------------------------------------
179 
180 HekMonitor::HekMonitor()
181 {
182  m_eMonState = MonStateIdInit;
183  m_bIsOpen = false;
184  m_bEStopCond = false;
185  m_bAlarmCond = false;
186  m_pDynaChain = NULL;
187  m_pKin = NULL;
188 
189 #ifdef HEK_HAS_SYS_BOARD
190  // expandsion board hardware
191  m_i2c.fd = -1;
192  m_i2c.addr = 0;
193 #endif // HEK_HAS_SYS_BOARD
194 
195  m_byLimitBits = 0x00;
196  m_byEEAuxBits = 0x00;
197 
198  // mutual exclusion variables
199  pthread_mutex_init(&m_mutexMon, NULL);
200  pthread_cond_init(&m_condMon, NULL);
201 
202  // no monitor thread
203  m_fHz = 1.0;
204  m_eMonThState = MonThStateIdExit;
205  m_eMonThStateOld = MonThStateIdInit;
206 }
207 
208 HekMonitor::~HekMonitor()
209 {
210  close();
211 
212  pthread_cond_destroy(&m_condMon);
213  pthread_mutex_destroy(&m_mutexMon);
214 }
215 
216 int HekMonitor::open(uint_t uHekHwVer,
217  const string &strDevArduino,
218  int nBaudRateArduino)
219 {
220  int rc;
221 
222  if( m_bIsOpen )
223  {
224  LOGWARN("Monitoring hardware already opened.");
225  return HEK_OK;
226  }
227 
228  if( (rc = m_hwif.open(uHekHwVer, strDevArduino, nBaudRateArduino)) < 0 )
229  {
230  LOGERROR("Hekateros monitor hardware open failed.");
231  return rc;
232  }
233  else if( (rc = m_hwif.scan()) < 0 )
234  {
235  LOGERROR("Hekateros monitor hardware scan failed.");
236  return rc;
237  }
238 
239  if( (rc = createMonThread()) < 0 )
240  {
241  LOGERROR("Hekateros monitor thread creation failed.");
242  return rc;
243  }
244 
245  m_eMonState = MonStateIdInit;
246  m_bIsOpen = true;
247 
248  LOGDIAG2("Opened monitoring hardware.");
249 
250  return HEK_OK;
251 }
252 
253 int HekMonitor::close()
254 {
255  if( m_bIsOpen )
256  {
257  destroyMonThread();
258 
259  m_hwif.close();
260 
261  m_eMonState = MonStateIdInit;
262  m_bIsOpen = false;
263  m_bEStopCond = false;
264  m_bAlarmCond = false;
265  m_pDynaChain = NULL;
266  m_pKin = NULL;
267 
268  m_opticalLimits.clear();
269 
270 #ifdef HEK_HAS_SYS_BOARD
271  // expandsion board hardware
272  m_i2c.fd = -1;
273  m_i2c.addr = 0;
274 #endif // HEK_HAS_SYS_BOARD
275 
276  m_byLimitBits = 0x00;
277  m_byEEAuxBits = 0x00;
278 
279  LOGDIAG2("Closed monitoring hardware.");
280  }
281 
282  return HEK_OK;
283 }
284 
285 
286 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
287 // Monitoring Thread Control
288 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
289 
290 int HekMonitor::start(double fHz)
291 {
292  double fPeriod;
293 
294  if( !m_bIsOpen )
295  {
296  LOGERROR("Monitor hardware not open.");
297  return -HEK_ECODE_NO_RSRC;
298  }
299  else if( m_eMonThState != MonThStateIdIdle )
300  {
301  LOGERROR("Monitor thread not in idle state.");
302  return -HEK_ECODE_BAD_OP;
303  }
304  else if( fHz <= 0.0 )
305  {
306  LOGERROR("Monitor thread run Hz=%lf invalid.", fHz);
307  return -HEK_ECODE_BAD_OP;
308  }
309 
310  m_fHz = fHz;
311  fPeriod = 1.0/fHz;
312 
313  m_tPeriod.tv_sec = (time_t)fPeriod;
314  fPeriod -= (double)m_tPeriod.tv_sec;
315  m_tPeriod.tv_nsec = (time_t)(fPeriod * GIGASEC);
316 
317  m_tStart = now();
318 
319  LOGDIAG3("Monitor thread started running at %.1lf Hz.", m_fHz);
320 
321  signalMonThread(MonThStateIdRun);
322 
323  m_eMonState = MonStateIdRunNormal;
324 
325  return HEK_OK;
326 }
327 
328 int HekMonitor::stop()
329 {
330  if( !m_bIsOpen )
331  {
332  LOGERROR("Monitor hardware not open.");
333  return -HEK_ECODE_NO_RSRC;
334  }
335  else if( m_eMonThState != MonThStateIdRun )
336  {
337  LOGERROR("Monitor thread not in run state.");
338  return -HEK_ECODE_BAD_OP;
339  }
340 
341  LOGDIAG3("Monitor thread stopped - blocked waiting.");
342 
343  signalMonThread(MonThStateIdIdle);
344 
345  m_eMonState = MonStateIdInit;
346 
347  return HEK_OK;
348 }
349 
350 
351 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
352 // Objects to Monitor
353 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
354 
355 int HekMonitor::addJointLimitsToMonitor(HekSpecJoint_T *pSpecJoint,
356  HekRobotJoint *pJoint)
357 {
358  HekJointOptical opticalLimit;
359  int i;
360 
361  for(i = 0; i < HekOptLimitMaxPerJoint; ++i)
362  {
363  if( pSpecJoint->m_limit[i].m_uBit == HekIOExpUnassigned )
364  {
365  break;
366  }
367 
368  opticalLimit.m_uMask = pSpecJoint->m_limit[i].m_uBit;
369  opticalLimit.m_uCurVal = HekIOExpDark;
370  opticalLimit.m_pJoint = pJoint;
371 
372  opticalLimit.m_limit.m_uBit = pSpecJoint->m_limit[i].m_uBit;
373  opticalLimit.m_limit.m_fMinEdgePos =
374  degToRad(pSpecJoint->m_limit[i].m_fMinEdgePos);
375  opticalLimit.m_limit.m_fMinBlackPos =
376  degToRad(pSpecJoint->m_limit[i].m_fMinBlackPos);
377  opticalLimit.m_limit.m_fCenterPos =
378  degToRad(pSpecJoint->m_limit[i].m_fCenterPos);
379  opticalLimit.m_limit.m_fMaxBlackPos =
380  degToRad(pSpecJoint->m_limit[i].m_fMaxBlackPos);
381  opticalLimit.m_limit.m_fMaxEdgePos =
382  degToRad(pSpecJoint->m_limit[i].m_fMaxEdgePos);
383 
384 
385  m_opticalLimits[opticalLimit.m_uMask] = opticalLimit;
386  }
387 
388  return HEK_OK;
389 }
390 
391 
392 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
393 // Monitor State & Conditions
394 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
395 
396 void HekMonitor::markAlarmCond( bool bAlarmCond)
397 {
398  m_bAlarmCond = bAlarmCond;
399 
400  writeAlarmLED(m_bAlarmCond || m_bEStopCond);
401 }
402 
403 void HekMonitor::markEStopCond(bool bEStopCond)
404 {
405  m_bEStopCond = bEStopCond;
406 
407  if( m_bEStopCond )
408  {
409  m_bAlarmCond = m_bEStopCond;
410  }
411 
412  writeAlarmLED(m_bAlarmCond || m_bEStopCond);
413 }
414 
415 
416 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
417 // Basic I/O
418 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
419 
420 byte_t HekMonitor::readLimitSwitches()
421 {
422  byte_t byVal = 0;
423 
424  lock();
425 
426  //LOGDIAG3("Reading optical limits.");
427 
428  byVal = m_hwif.cmdReadLimits();
429 
430  unlock();
431 
432  return byVal;
433 }
434 
435 byte_t HekMonitor::readEEGpio()
436 {
437  byte_t byVal = 0;
438 
439  lock();
440 
441  //LOGDIAG3("Reading optical switch pins");
442 
443  byVal = m_hwif.cmdReadAux();
444 
445  unlock();
446 
447  return byVal;
448 }
449 
450 int HekMonitor::writeEEGpioPin(byte_t byPin, byte_t byVal)
451 {
452  int rc = HEK_OK;
453 
454  lock();
455 
456  rc = m_hwif.cmdWritePin(byPin, byVal);
457 
458  unlock();
459 
460  return rc;
461 }
462 
463 int HekMonitor::configEEGpioPin(byte_t byPin, char cDir)
464 {
465  int rc = HEK_OK;
466 
467  lock();
468 
469  rc = m_hwif.cmdConfigPin(byPin, cDir);
470 
471  unlock();
472 
473  return rc;
474 }
475 
476 void HekMonitor::writeAlarmLED(bool bState)
477 {
478  lock();
479 
480  m_hwif.cmdSetAlarmLED(bState? 1: 0);
481 
482  unlock();
483 }
484 
485 void HekMonitor::testInterface()
486 {
487  lock();
488 
489  m_hwif.cmdTestInterface();
490 
491  unlock();
492 }
493 
494 
495 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
496 // Attibute Methods
497 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
498 
499 HekTriState HekMonitor::getJointLimitTriState(HekRobotJoint *pJoint, int nLimit)
500 {
501  uint_t uMask = pJoint->m_byOptLimitMask[nLimit];
502 
503  if( uMask == HekIOExpUnassigned )
504  {
505  return HekTriStateUnknown;
506  }
507  else if( m_opticalLimits[uMask].m_uCurVal & HekIOExpLight )
508  {
509  return HekTriStateLight;
510  }
511  else
512  {
513  return HekTriStateDark;
514  }
515 }
516 
517 
518 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
519 // Monitor Thread
520 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
521 
522 int HekMonitor::createMonThread()
523 {
524  int rc;
525 
526  m_eMonThState = MonThStateIdIdle;
527 
528  rc = pthread_create(&m_threadMon, NULL, HekMonitor::monThread, (void*)this);
529 
530  if( rc == 0 )
531  {
532  rc = HEK_OK;
533  }
534 
535  else
536  {
537  LOGSYSERROR("pthread_create()");
538  m_eMonThState = MonThStateIdExit;
539  rc = -HEK_ECODE_SYS;
540  }
541 
542  return rc;
543 }
544 
545 void HekMonitor::destroyMonThread()
546 {
547  signalMonThread(MonThStateIdExit);
548 
549  usleep(1000);
550 
551  pthread_cancel(m_threadMon);
552  pthread_join(m_threadMon, NULL);
553 
554  LOGDIAG3("Monitor thread canceled.");
555 }
556 
557 void HekMonitor::signalMonThread(MonThStateId eNewThState)
558 {
559  lock();
560 
561  m_eMonThStateOld = m_eMonThState;
562  m_eMonThState = eNewThState;
563  pthread_cond_signal(&m_condMon);
564 
565  unlock();
566 }
567 
568 void HekMonitor::idleWait()
569 {
570  lock();
571 
572  while( m_eMonThState == MonThStateIdIdle )
573  {
574  pthread_cond_wait(&m_condMon, &m_mutexMon);
575  }
576  m_tStart = now();
577 
578  unlock();
579 }
580 
581 void HekMonitor::runWait()
582 {
583  struct timespec tNow = now();
584 
585  lock();
586 
587  m_tStart = add(m_tStart, m_tPeriod);
588 
589  // tStart <= tNow
590  if( le(m_tStart, tNow) )
591  {
592  LOGWARN("Monitor slipped timing by %lf seconds.",
593  ttod(sub(tNow, m_tStart)));
594  m_tStart = tNow;
595  }
596  else
597  {
598  pthread_cond_timedwait(&m_condMon, &m_mutexMon, &m_tStart);
599  }
600 
601  unlock();
602 }
603 
604 const char *HekMonitor::getThStateName(MonThStateId eMonThState)
605 {
606  switch( eMonThState )
607  {
608  case MonThStateIdInit:
609  return "start";
610  case MonThStateIdIdle:
611  return "idle";
612  case MonThStateIdRun:
613  return "run";
614  case MonThStateIdExit:
615  return "exit";
616  default:
617  return "unknown";
618  }
619 }
620 
621 #undef HEK_MON_TEST_IF ///< define/undef to enable/disable debug test of i/f
622 
623 void *HekMonitor::monThread(void *pArg)
624 {
625  HekMonitor *pThis = (HekMonitor *)pArg;
626  int oldstate;
627  int rc;
628 
629  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
630  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
631  //pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldstate);
632 
633  pThis->m_eMonThStateOld = MonThStateIdInit;
634 
635  LOGDIAG3("Monitor thread created.");
636 
637  while( pThis->m_eMonThState != MonThStateIdExit )
638  {
639  if( pThis->m_eMonThStateOld != pThis->m_eMonThState )
640  {
641  LOGDIAG3("Monitor thread: %s -> %s state.",
642  pThis->getThStateName(pThis->m_eMonThStateOld),
643  pThis->getThStateName(pThis->m_eMonThState));
644  }
645 
646  switch( pThis->m_eMonThState )
647  {
648  case MonThStateIdIdle:
649  pThis->idleWait();
650  break;
651 
652  case MonThStateIdRun:
653  pThis->runWait();
654 #ifdef HEK_MON_TEST_IF
655  pThis->testInterface();
656 #endif
657  pThis->monJointLimits();
658  pThis->monEEAuxIO();
659  pThis->monServoAlarms();
660  break;
661 
662  case MonThStateIdExit:
663  break;
664 
665  default:
666  LOGERROR("%d: Unknown monitor state.", pThis->m_eMonThState);
667  pThis->m_eMonThState = MonThStateIdExit;
668  break;
669  }
670 
671  pThis->m_eMonThStateOld = pThis->m_eMonThState;
672  }
673 
674  pThis->unlock();
675 
676  LOGDIAG3("Monitor thread exited.");
677 
678  return NULL;
679 }
680 
681 void HekMonitor::monJointLimits()
682 {
683  // past limit backoff speed (rads/sec)
684  static double TuneBackOffVel = degToRad(10.0);
685 
686  MapOpticalLimits::iterator iter;
687  byte_t byMask;
688  byte_t byVal;
689  HekRobotJoint *pJoint;
690  DynaServo *pServo;
691  int nOdPos;
692 
693  if( (m_pDynaChain == NULL) || (m_pKin == NULL) )
694  {
695  return;
696  }
697 
698  m_byLimitBits = readLimitSwitches();
699 
700  for(iter = m_opticalLimits.begin(); iter != m_opticalLimits.end(); ++iter)
701  {
702  byMask = iter->first;
703  pJoint = iter->second.m_pJoint;
704 
705  byVal = m_byLimitBits & byMask;
706 
707  //
708  // Transitioned from light to dark.
709  //
710  if( (byVal == HekIOExpDark) && (byVal != iter->second.m_uCurVal) )
711  {
712  // have power to servos and this limit set to automatically stop
713  if( m_bPoweredCond && pJoint->doStopAtLimits() )
714  {
715  string strJointName;
716  double fJointCurPos, fJointCurVel;
717 
718  strJointName = pJoint->m_strName;
719 
720  m_pKin->getJointCurPosVel(strJointName, fJointCurPos, fJointCurVel);
721 
722  if( fJointCurPos < pJoint->m_fMinSoftLimitRads )
723  {
724  m_pKin->move(strJointName, pJoint->m_fMinSoftLimitRads,
725  TuneBackOffVel);
726  }
727  else if( fJointCurPos > pJoint->m_fMaxSoftLimitRads )
728  {
729  m_pKin->move(strJointName, pJoint->m_fMaxSoftLimitRads,
730  TuneBackOffVel);
731  }
732  else
733  {
734  m_pKin->stop(strJointName);
735  }
736  }
737  else
738  {
739  // could validate/resync position(s) here
740  }
741  }
742 
743  iter->second.m_uCurVal = byVal;
744  }
745 }
746 
747 void HekMonitor::monEEAuxIO()
748 {
749 }
750 
751 void HekMonitor::monServoAlarms()
752 {
753  int iter;
754  int nServoId;
755  DynaServo *pServo;
756  bool bAlarmState = false;
757 
758  if( m_pDynaChain == NULL )
759  {
760  return;
761  }
762 
763  //
764  // Emergency stop forces alarm state.
765  //
766  if( m_bEStopCond )
767  {
768  bAlarmState = true;
769  }
770 
771  //
772  // Search all servos for alarms.
773  //
774  else
775  {
776  for(nServoId = m_pDynaChain->IterStart(&iter);
777  nServoId != DYNA_ID_NONE;
778  nServoId = m_pDynaChain->IterNext(&iter))
779  {
780  if( (pServo = m_pDynaChain->GetServo(nServoId)) != NULL )
781  {
782  if( pServo->GetAlarms() != DYNA_ALARM_NONE )
783  {
784  bAlarmState = true;
785  break;
786  }
787  }
788  }
789  }
790 
791  //
792  // New alarm state. Set LED and save new state.
793  //
794  if( bAlarmState != m_bAlarmCond )
795  {
796  writeAlarmLED(bAlarmState);
797  m_bAlarmCond = bAlarmState;
798  }
799 }
void runWait()
Monitor thread block timed wait in run state.
Definition: hekMonitor.cxx:581
HekOpticalLimit_T m_limit[HekOptLimitMaxPerJoint]
optical limits
Definition: hekSpec.h:182
HekRobotJoint * m_pJoint
limit switch associated robotic joint
Definition: hekJoint.h:268
byte_t m_uBit
i/o expander bit position
Definition: hekOptical.h:177
void idleWait()
Monitor thread block wait in idle state.
Definition: hekMonitor.cxx:568
HekDesc - Hekateros full robotic manipulator descripition class interface.
double m_fMinSoftLimitRads
joint min soft limit (radians)
Definition: hekJoint.h:166
void monJointLimits()
Monitor joint (optical) limits for state transitions.
Definition: hekMonitor.cxx:681
Operational robotic joint description class.
Definition: hekJoint.h:80
<b><i>Hekateros</i></b> optical limit switches.
Joint points and trajectory class interfaces.
double m_fMinBlackPos
minimum complete occlusion position
Definition: hekOptical.h:179
Hekateros Robot State classes interface.
<b><i>Hekateros</i></b> Arduino Uno compatible I/O board class interface.
bool doStopAtLimits() const
Get auto-stop at joint electronic limits state.
Definition: hekJoint.h:142
byte_t m_uCurVal
i/o expander current bit value
Definition: hekJoint.h:267
Hekateros Monitor Class interface.
double m_fMaxEdgePos
maxinum edge position of occlusion band
Definition: hekOptical.h:182
Hekateros joint classes interfaces.
double m_fMaxBlackPos
maximum complete occlusion position
Definition: hekOptical.h:181
MonThStateId m_eMonThState
monitoring thread state
Definition: hekMonitor.h:463
double m_fMinEdgePos
mininum edge position of occlusion band
Definition: hekOptical.h:178
byte_t m_byOptLimitMask[HekOptLimitMaxPerJoint]
optical limit mask array
Definition: hekJoint.h:175
const char * getThStateName(MonThStateId eNewState)
Get thread state name string.
Definition: hekMonitor.cxx:604
std::string m_strName
joint name
Definition: hekJoint.h:149
byte_t m_uMask
i/o expander bit mask
Definition: hekJoint.h:266
Top-level package include file.
double degToRad(double d)
Convert degrees to radians.
Definition: hekUtils.h:125
double m_fMaxSoftLimitRads
joint max soft limit (radians)
Definition: hekJoint.h:167
void monEEAuxIO()
Monitor End Effector auxillary I/O.
Definition: hekMonitor.cxx:747
void unlock()
Unlock the monitor thread mutex.
Definition: hekMonitor.h:502
<b><i>Hekateros</i></b> product specification base classes.
MonThStateId
monitor thread states.
Definition: hekMonitor.h:129
<b><i>Hekateros</i></b> power, joint limits, and alarm monitoring class.
Definition: hekMonitor.h:100
Operational robotic joint optical limits class.
Definition: hekJoint.h:215
Hekateros common utilities.
Robotic joint specification.
Definition: hekSpec.h:139
void testInterface()
Test interface.
Definition: hekMonitor.cxx:485
double m_fCenterPos
center of operation position
Definition: hekOptical.h:180
HekOpticalLimit_T m_limit
optical limit info
Definition: hekJoint.h:269
The <b><i>Hekateros</i></b> namespace encapsulates all <b><i>Hekateros</i></b> related constructs...
Definition: hekateros.h:56
void monServoAlarms()
Monitor servos for alarms.
Definition: hekMonitor.cxx:751
MonThStateId m_eMonThStateOld
monitoring thread old state
Definition: hekMonitor.h:464