59 #include "rnr/rnrconfig.h" 60 #include "rnr/units.h" 64 #include "Dynamixel/Dynamixel.h" 65 #include "Dynamixel/DynaComm.h" 66 #include "Dynamixel/DynaServo.h" 67 #include "Dynamixel/DynaChain.h" 68 #include "Dynamixel/DynaBgThread.h" 69 #include "Dynamixel/DynaError.h" 100 #define HEK_TRY_NO_EXEC() \ 124 #define HEK_TRY_GET_SERVO(nServoId, pServo) \ 127 if( (pServo = m_pDynaChain->GetServo(nServoId)) == NULL ) \ 129 LOGERROR("BUG: Servo %d: Cannot find in dynamixel chain.", nServoId); \ 130 return -HEK_ECODE_INTERNAL; \ 143 #define HEK_TRY_CONN() \ 146 if( !isConnected() ) \ 148 LOGERROR("Robot is not connected."); \ 149 return -HEK_ECODE_NO_EXEC; \ 161 #define HEK_TRY_CALIB() \ 164 if( m_eOpState != HekOpStateCalibrated ) \ 166 LOGERROR("Robot is not calibrated."); \ 167 return -HEK_ECODE_NO_EXEC; \ 179 #define HEK_TRY_NOT_ESTOP() \ 182 if( m_bIsEStopped ) \ 184 LOGERROR("Robot is emergency stopped."); \ 185 return -HEK_ECODE_NO_EXEC; \ 194 HekRobot::HekRobot(
bool bNoExec)
198 m_eRobotMode = HekRobotModeAuto;
199 m_eOpState = HekOpStateUncalibrated;
200 m_bIsEStopped =
false;
201 m_bAlarmState =
false;
202 m_bAreServosPowered =
false;
203 m_bAtBalancedPos =
false;
204 m_bAtParkedPos =
false;
209 m_pDynaBgThread = NULL;
212 m_eAsyncTaskState = HekAsyncTaskStateIdle;
213 m_rcAsyncTask = HEK_OK;
214 m_eAsyncTaskId = AsyncTaskIdNone;
215 m_pAsyncTaskArg = NULL;
217 pthread_mutex_init(&m_mutex, NULL);
220 HekRobot::~HekRobot()
223 pthread_mutex_destroy(&m_mutex);
226 int HekRobot::connect(
const string &strDevDynabus,
int nBaudRateDynabus,
227 const string &strDevArduino,
int nBaudRateArduino)
241 if( !m_descHek.isDescribed() )
243 LOGERROR(
"Undefined Hekateros description - " 244 "don't know how to initialized properly.");
245 return -HEK_ECODE_BAD_OP;
257 m_pDynaComm = DynaComm::New(strDevName.c_str(), nBaudRateDynabus);
259 if( m_pDynaComm == NULL )
261 LOGERROR(
"Failed to create dynamixel interface on '%s'@%d.",
262 strDevName.c_str(), nBaudRateDynabus);
263 return -HEK_ECODE_DYNA;
265 LOGDIAG2(
"Created dynamixel interface on '%s'@%d.",
266 strDevName.c_str(), nBaudRateDynabus);
269 m_pDynaChain =
new DynaChain(*m_pDynaComm);
272 if( (rc = scanDynaBus(3)) < 0 )
274 LOGERROR(
"Hekateros dynamixel bus scan failed.");
278 LOGDIAG2(
"Scanned for servos.");
290 if( (rc = convertSpecs()) < 0 )
292 LOGERROR(
"Failed to convert product specifications to " 293 "operations parameters.");
297 LOGDIAG2(
"Converted product specifications to operations parameters.");
305 adjustTuningFromSpecs();
314 xml.
load(m_tunes, HekSysCfgPath, HekEtcTune);
326 resetCalibStateForAllJoints(
true);
334 m_pKin =
new HekKinematics(*m_pDynaChain, m_jointsArm, m_tunes);
337 m_pKin->runThread(m_tunes.getKinematicsHz());
339 LOGDIAG2(
"Kinematics thread started.");
349 if( (rc = m_monitor.open(getVersionNum(), strDevName, nBaudRateArduino)) < 0 )
351 LOGERROR(
"Hekateros monitor interface failed to open on '%s'@%d.",
352 strDevName.c_str(), nBaudRateArduino);
356 LOGDIAG2(
"Hekateros monitor interface open on '%s'@%d.",
357 strDevName.c_str(), nBaudRateArduino);
359 m_bAlarmState =
false;
360 m_monitor.markAlarmCond(m_bAlarmState);
363 m_monitor.addServoChainToMonitor(m_pDynaChain);
366 m_monitor.addKinematicsToMonitor(m_pKin);
371 LOGDIAG2(
"Monitor thread started.");
378 LOGDIAG1(
"Connected to Hekateros.");
394 int HekRobot::disconnect()
406 if( m_pDynaChain != NULL )
408 m_pDynaChain->EStop();
414 if( m_pDynaComm != NULL )
416 if( m_pDynaComm->IsOpen() )
418 m_pDynaComm->Close();
425 m_eRobotMode = HekRobotModeAuto;
426 m_eOpState = HekOpStateUncalibrated;
427 m_bIsEStopped =
false;
428 m_bAlarmState =
false;
429 m_bAreServosPowered =
false;
430 m_bAtBalancedPos =
false;
431 m_bAtParkedPos =
false;
433 LOGDIAG1(
"Disconnected from Hekateros.");
436 int HekRobot::calibrate(
bool bForceRecalib)
448 m_eOpState = HekOpStateUncalibrated;
451 resetCalibStateForAllJoints(bForceRecalib);
454 m_eOpState = HekOpStateCalibrating;
459 LOGERROR(
"Failed to calibrate Hekateros.");
460 m_eOpState = HekOpStateUncalibrated;
469 if( (m_eOpState = determineRobotOpState()) != HekOpStateCalibrated )
471 LOGERROR(
"BUG: Failed to calibrate Hekateros.");
472 return -HEK_ECODE_INTERNAL;
478 LOGDIAG1(
"Hekateros calibrated.");
483 int HekRobot::calibrateAsync(
bool bForceRecalib)
485 if( m_eAsyncTaskState != HekAsyncTaskStateIdle )
487 LOGERROR(
"Already executing asynchronous task.");
488 return -HEK_ECODE_NO_RSRC;
492 m_eAsyncTaskId = AsyncTaskIdCalibrate;
493 m_pAsyncTaskArg = (
void *)bForceRecalib;
495 return createAsyncThread();
499 void HekRobot::reload()
504 if( xml.
load(m_tunes,HekSysCfgPath, HekEtcTune) == HEK_OK )
506 LOGDIAG2(
"User specified tuning parameters reloaded from XML file %s.",
509 m_pKin->reload(m_tunes);
513 int HekRobot::gotoBalancedPos()
516 MapRobotJoints::iterator iter;
529 for(iter = m_jointsArm.begin(); iter != m_jointsArm.end(); ++iter)
531 nMasterServoId = iter->first;
532 pJoint = &(iter->second);
534 switch( nMasterServoId )
540 case HekServoIdShoulderL:
544 case HekServoIdElbow:
548 case HekServoIdWristPitch:
552 case HekServoIdWristRot:
556 case HekServoIdGraboid:
565 if( (rc = moveArm(trajPoint)) < 0 )
567 LOGERROR(
"Move to pre-defined balanced position failed.");
571 m_bAtBalancedPos =
true;
572 LOGDIAG2(
"Hekateros at balanced position.");
578 int HekRobot::gotoParkedPos()
581 MapRobotJoints::iterator iter;
594 for(iter = m_jointsArm.begin(); iter != m_jointsArm.end(); ++iter)
596 nMasterServoId = iter->first;
597 pJoint = &(iter->second);
599 switch( nMasterServoId )
605 case HekServoIdShoulderL:
609 case HekServoIdElbow:
613 case HekServoIdWristPitch:
617 case HekServoIdWristRot:
621 case HekServoIdGraboid:
630 if( (rc = moveArm(trajPoint)) < 0 )
632 LOGERROR(
"Move to pre-defined parked position failed.");
636 m_bAtParkedPos =
true;
637 LOGDIAG2(
"Hekateros at parked position.");
643 int HekRobot::gotoZeroPtPos()
646 MapRobotJoints::iterator iter;
659 for(iter = m_jointsArm.begin(); iter != m_jointsArm.end(); ++iter)
661 nMasterServoId = iter->first;
662 pJoint = &(iter->second);
664 switch( nMasterServoId )
670 case HekServoIdShoulderL:
674 case HekServoIdElbow:
678 case HekServoIdWristPitch:
682 case HekServoIdWristRot:
686 case HekServoIdGraboid:
695 if( (rc = moveArm(trajPoint)) < 0 )
697 LOGERROR(
"Move to pre-defined calibrated zero point position failed.");
701 LOGDIAG2(
"Hekateros at zero point position.");
707 int HekRobot::openGripper()
718 if( (pJoint = getArmJoint(HekServoIdGraboid)) == NULL )
720 LOGERROR(
"No gripper end effector found.");
721 return -HEK_ECODE_NO_RSRC;
727 if( (rc = moveArm(trajPoint)) < 0 )
729 LOGERROR(
"Move to pre-defined gripper open position failed.");
733 LOGDIAG2(
"Hekateros gripper opened.");
739 int HekRobot::closeGripper()
750 if( (pJoint = getArmJoint(HekServoIdGraboid)) == NULL )
752 LOGERROR(
"No gripper end effector found.");
753 return -HEK_ECODE_NO_RSRC;
759 if( (rc = moveArm(trajPoint)) < 0 )
761 LOGERROR(
"Move to pre-defined gripper closed position failed.");
765 LOGDIAG2(
"Hekateros gripper closed.");
771 int HekRobot::estop()
778 m_bIsEStopped =
true;
779 m_bAreServosPowered =
false;
781 m_monitor.markEStopCond(m_bIsEStopped);
782 m_monitor.markPoweredCond(m_bAreServosPowered);
784 m_lastTrajArm.clear();
786 m_bAlarmState =
true;
787 m_monitor.markAlarmCond(m_bAlarmState);
789 LOGDIAG1(
"Hekateros emergency stopped.");
794 int HekRobot::freeze()
799 m_bAreServosPowered =
true;
801 m_monitor.markPoweredCond(m_bAreServosPowered);
803 m_lastTrajArm.clear();
807 LOGDIAG2(
"Hekateros frozen at current position.");
812 int HekRobot::release()
817 m_bAreServosPowered =
false;
819 m_monitor.markPoweredCond(m_bAreServosPowered);
821 m_lastTrajArm.clear();
825 LOGDIAG2(
"Hekateros servo drives released.");
830 int HekRobot::stop(
const vector<string> &vecNames)
838 m_lastTrajArm.clear();
840 n = m_pKin->stop(vecNames);
842 LOGDIAG3(
"%d joints stopped.", n);
847 int HekRobot::clearAlarms()
860 for(nServoId = m_pDynaChain->IterStart(&iter);
861 nServoId != DYNA_ID_NONE;
862 nServoId = m_pDynaChain->IterNext(&iter))
864 pServo = m_pDynaChain->GetServo(nServoId);
867 pServo->ReloadMaxTorqueLimit();
874 m_bAlarmState =
false;
875 m_monitor.markAlarmCond(m_bAlarmState);
890 if( !m_bAreServosPowered )
892 m_bAreServosPowered =
true;
894 m_monitor.markPoweredCond(m_bAreServosPowered);
897 rc = m_pKin->move(trajectoryPoint);
901 return rc >= 0? HEK_OK: rc;
906 static int TuneStoppedSpeed = 9;
917 bOldAlarmState = m_bAlarmState;
918 m_bAlarmState = m_monitor.getAlarmCond();
922 HekTriStateTrue: HekTriStateFalse;
924 HekTriStateTrue: HekTriStateFalse;
926 HekTriStateTrue: HekTriStateFalse;
928 !m_bAlarmState && !m_bNoExec?
929 HekTriStateTrue: HekTriStateFalse;
935 for(nServoId = m_pDynaChain->IterStart(&iter);
936 nServoId != DYNA_ID_NONE;
937 nServoId = m_pDynaChain->IterNext(&iter))
939 pServo = m_pDynaChain->GetServo(nServoId);
942 health.
m_fTemperature = pServo->CvtRawTempToC(pServo->GetCurTemp());
943 health.
m_fVoltage = pServo->CvtRawVoltToVolts(pServo->GetCurVolt());
946 if( health.
m_uAlarms != DYNA_ALARM_NONE )
952 if(
iabs(pServo->GetCurSpeed()) > TuneStoppedSpeed )
968 else if( m_bAlarmState && (m_bAlarmState != bOldAlarmState) )
974 robotState.
m_eIsInMotion = bIsMoving? HekTriStateTrue: HekTriStateFalse;
981 MapRobotJoints::iterator iter;
991 jointStatePoint.
clear();
998 for(iter = m_jointsArm.begin(); iter != m_jointsArm.end(); ++iter)
1000 nMasterServoId = iter->first;
1001 pJoint = &(iter->second);
1012 m_pKin->getFilteredJointCurPosVel(jointState.
m_strName,
1017 jointState.
m_nOdPos = pServo->GetOdometer();
1019 jointState.
m_nSpeed = pServo->GetCurSpeed();
1020 jointState.
m_fEffort = (double)pServo->GetCurLoad();
1023 for(
int i=0; i<HekOptLimitMaxPerJoint; ++i)
1025 jointState.
m_eOptSwitch[i] = m_monitor.getJointLimitTriState(pJoint, i);
1029 jointStatePoint.
append(jointState);
1042 trajectoryFeedback.
clear();
1045 trajectoryFeedback[HekJointTrajectoryFeedback::TRAJ_DESIRED] = m_lastTrajArm;
1048 if( (rc = getJointState(jointStatePoint)) < 0 )
1050 LOGERROR(
"Cannot retrieve joint state data.");
1055 iActual = HekJointTrajectoryFeedback::TRAJ_ACTUAL;
1059 trajectoryFeedback[iActual].append(jointStatePoint[i].m_strName,
1060 jointStatePoint[i].m_fPosition,
1061 jointStatePoint[i].m_fVelocity);
1067 bool HekRobot::isInMotion()
1069 static int TuneStoppedSpeed = 9;
1075 for(nServoId = m_pDynaChain->IterStart(&iter);
1076 nServoId != DYNA_ID_NONE;
1077 nServoId = m_pDynaChain->IterNext(&iter))
1079 pServo = m_pDynaChain->GetServo(nServoId);
1081 if(
iabs(pServo->GetCurSpeed()) > TuneStoppedSpeed )
1090 int HekRobot::scanDynaBus(
int nMaxTries)
1092 static uint_t usecTry = 500000;
1094 int nNumServosExpected;
1095 int nNumServosScanned;
1096 int nNumServosMatched;
1102 nNumServosExpected = m_descHek.getNumServos();
1107 for(nTries=0; nTries<nMaxTries; ++nTries)
1109 LOGDIAG3(
"Scanning Hekateros hardware - attempt %d of %d.",
1110 nTries+1, nMaxTries);
1113 nNumServosScanned = m_pDynaChain->AddNewServosByScan();
1118 if( nNumServosScanned >= nNumServosExpected )
1121 for(nServoId = m_pDynaChain->IterStart(&iter), nNumServosMatched=0;
1122 nServoId != DYNA_ID_NONE;
1123 nServoId = m_pDynaChain->IterNext(&iter))
1126 if( m_descHek.hasServo(nServoId) )
1128 ++nNumServosMatched;
1134 LOGWARN(
"Servo %d unexpected - uncontrolled.", nServoId);
1139 if( nNumServosMatched == nNumServosExpected )
1148 LOGERROR(
"Match %d scanned servo ids, expected %d required matches.",
1149 nNumServosMatched, nNumServosExpected);
1150 rc = -HEK_ECODE_FORMAT;
1159 LOGERROR(
"Scanned %d servos, expected %d.",
1160 nNumServosScanned, nNumServosExpected);
1161 rc = -HEK_ECODE_NO_RSRC;
1169 LOGDIAG3(
"Hekateros dynamixel bus hardware scanned successfully.");
1175 int HekRobot::convertSpecs()
1186 m_jointsArm.clear();
1187 m_jointsEquipDeck.clear();
1188 m_jointsAux.clear();
1189 m_imapJoints.clear();
1191 pDescArm = m_descHek.getArmDesc();
1192 pDescEE = m_descHek.getEEDesc();
1204 pJoint = &m_jointsArm[nServoId];
1209 LOGERROR(
"Servo %d: Cannot find servo specification.", nServoId);
1210 return -HEK_ECODE_NO_EXEC;
1214 rc = addRobotJoint(pSpecJoint, pSpecServo, m_jointsArm, m_imapJoints);
1217 LOGERROR(
"Servo %d: Cannot add to kinematic chain.", nServoId);
1222 if( (rc = m_monitor.addJointLimitsToMonitor(pSpecJoint, pJoint)) < 0 )
1224 LOGERROR(
"Servo %d: Cannot add to optical limit(s).", nServoId);
1239 pJoint = &m_jointsArm[nServoId];
1244 LOGERROR(
"Servo %d: Cannot find servo specification.", nServoId);
1245 return -HEK_ECODE_NO_EXEC;
1249 rc = addRobotJoint(pSpecJoint, pSpecServo, m_jointsArm, m_imapJoints);
1252 LOGERROR(
"Servo %d: Cannot add to kinematic chain.", nServoId);
1257 if( (rc = m_monitor.addJointLimitsToMonitor(pSpecJoint, pJoint)) < 0 )
1259 LOGERROR(
"Servo %d: Cannot add to optical limit(s).", nServoId);
1273 MapRobotJoints &kin,
1291 if( (pServo = m_pDynaChain->GetServo(nMasterServoId)) == NULL )
1293 LOGERROR(
"Servo %d: Cannot find servo in dynamixel chain.", nMasterServoId);
1294 return -HEK_ECODE_NO_EXEC;
1300 uTicks = pServo->GetSpecification().m_uRawPosModulo;
1301 fAngleMin = pServo->GetSpecification().m_fAngleMin;
1302 fAngleMax = pServo->GetSpecification().m_fAngleMax;
1303 fMaxRpm = pServo->GetSpecification().m_fMaxSpeed;
1346 HekTuneOverTorqueThMin,
1347 HekTuneOverTorqueThMax) / 100.0;
1352 for(i=0; i<HekOptLimitMaxPerJoint; ++i)
1373 kin[nMasterServoId] = joint;
1379 void HekRobot::adjustTuningFromSpecs()
1381 MapRobotJoints::iterator iter;
1383 string strJointName;
1385 for(iter = m_jointsArm.begin(); iter != m_jointsArm.end(); ++iter)
1387 strJointName = iter->second.m_strName;
1393 m_tunes.m_mapJointTunes[strJointName] = tunesJoint;
1397 void HekRobot::fauxcalibrate()
1399 MapRobotJoints::iterator iter;
1403 for(iter = m_jointsArm.begin(); iter != m_jointsArm.end(); ++iter)
1405 iter->second.m_eOpState = HekOpStateCalibrated;
1407 m_pKin->resetServoOdometersForAllJoints();
1408 m_eOpState = HekOpStateCalibrated;
1411 int HekRobot::configServos()
1415 if( (rc = configEEPROMForAllServos(m_jointsArm)) < 0 )
1417 LOGERROR(
"Failed to configure servo EEPROM for all servos.");
1421 if( (rc = configRAMForAllServos(m_jointsArm)) < 0 )
1423 LOGERROR(
"Failed to configure servo RAM for all servos.");
1430 int HekRobot::configEEPROMForAllServos(MapRobotJoints &kin)
1432 MapRobotJoints::iterator iter;
1437 for(iter = kin.begin(); iter != kin.end(); ++iter)
1439 nServoId = iter->second.m_nMasterServoId;
1441 if( (rc = configEEPROMForServo(nServoId, iter->second)) < 0 )
1443 LOGERROR(
"Servo %d: Failed to configure servo EEPROM memory map.",
1448 nServoId = iter->second.m_nSlaveServoId;
1450 if( nServoId != DYNA_ID_NONE )
1452 if( (rc = configEEPROMForServo(nServoId, iter->second)) < 0 )
1454 LOGERROR(
"Servo %d: Failed to configure servo EEPROM memory map.",
1477 uPosMin = pServo->GetSpecification().m_uRawPosMin;
1478 uPosMax = pServo->GetSpecification().m_uRawPosMax;
1479 uTorqueMax = pServo->GetSpecification().m_uRawTorqueMax;
1487 (pServo->GetServoMode() != DYNA_MODE_CONTINUOUS))
1489 if( (rc = pServo->CfgWriteServoModeContinuous()) < 0 )
1491 LOGERROR(
"Servo %d: Cannot configure EEPROM for continuous mode.",
1493 return -HEK_ECODE_DYNA;
1499 (pServo->GetServoMode() == DYNA_MODE_CONTINUOUS) )
1501 if( (rc = pServo->CfgWriteServoMode(uPosMin, uPosMax)) < 0 )
1503 LOGERROR(
"Servo %d: Cannot configure EEPROM for servo mode.", nServoId);
1504 return -HEK_ECODE_DYNA;
1513 if( (rc = pServo->CfgReadMaxTorqueLimit(&uVal)) < 0 )
1515 LOGWARN(
"Servo %d: Cannot read EEPROM maximum torque limit.", nServoId);
1517 else if( uVal < uTorqueMax )
1519 if( (rc = pServo->CfgWriteMaxTorqueLimit(uTorqueMax)) < 0 )
1521 LOGWARN(
"Servo %d: Cannot configure EEPROM maximum torque limit.",
1531 uMask = DYNA_ALARM_VOLTAGE | DYNA_ALARM_ANGLE | DYNA_ALARM_TEMP |
1534 if( (rc = pServo->CfgReadAlarmShutdownMask(&uVal)) < 0 )
1536 LOGWARN(
"Servo %d: Cannot read EEPROM alarm shutdown mask.", nServoId);
1538 else if( uVal != uMask )
1540 if( (rc = pServo->CfgWriteAlarmShutdownMask(uMask)) < 0 )
1542 LOGWARN(
"Servo %d: Cannot configure EEPROM alarm shutdown mask.",
1550 int HekRobot::configRAMForAllServos(MapRobotJoints &kin)
1552 MapRobotJoints::iterator iter;
1556 for(iter = kin.begin(); iter != kin.end(); ++iter)
1558 nServoId = iter->second.m_nMasterServoId;
1560 if( (rc = configRAMForServo(nServoId, iter->second)) < 0 )
1562 LOGERROR(
"Servo %d: Failed to configure servo RAM memory map.",
1583 uTorqueMax = pServo->GetSpecification().m_uRawTorqueMax;
1589 if( (rc = pServo->WriteMaxTorqueLimit(uTorqueMax)) < 0 )
1591 LOGWARN(
"Servo %d: Cannot write RAM alarm shutdown mask.", nServoId);
1598 if( (rc = pServo->WriteTorqueEnable(
false)) < 0 )
1600 LOGERROR(
"Servo %d: Cannot enable servo drive.", nServoId);
1601 return -HEK_ECODE_DYNA;
1607 void HekRobot::resetCalibStateForAllJoints(
bool bForceRecalib)
1609 MapRobotJoints::iterator iter;
1611 for(iter = m_jointsArm.begin(); iter != m_jointsArm.end(); ++iter)
1613 if( bForceRecalib || (iter->second.m_eOpState != HekOpStateCalibrated) )
1615 iter->second.m_eOpState = HekOpStateUncalibrated;
1620 HekOpState HekRobot::determineRobotOpState()
1622 MapRobotJoints::iterator iter;
1624 for(iter = m_jointsArm.begin(); iter != m_jointsArm.end(); ++iter)
1626 if( iter->second.m_eOpState != HekOpStateCalibrated )
1628 return HekOpStateUncalibrated;
1632 return HekOpStateCalibrated;
1635 int HekRobot::createAsyncThread()
1639 m_eAsyncTaskState = HekAsyncTaskStateWorking;
1640 m_rcAsyncTask = HEK_OK;
1642 rc = pthread_create(&m_threadAsync, NULL, HekRobot::asyncThread, (
void*)
this);
1651 m_eAsyncTaskState = HekAsyncTaskStateIdle;
1652 LOGSYSERROR(
"pthread_create()");
1653 m_rcAsyncTask = -HEK_ECODE_SYS;
1654 m_eAsyncTaskId = AsyncTaskIdNone;
1655 m_pAsyncTaskArg = NULL;
1662 void HekRobot::cancelAsyncTask()
1664 MapRobotJoints::iterator iter;
1666 if( m_eAsyncTaskState != HekAsyncTaskStateIdle )
1669 pthread_cancel(m_threadAsync);
1670 pthread_join(m_threadAsync, NULL);
1673 switch( m_eAsyncTaskId )
1675 case AsyncTaskIdCalibrate:
1677 for(iter = m_jointsArm.begin(); iter != m_jointsArm.end(); ++iter)
1679 if( iter->second.m_eOpState != HekOpStateCalibrated )
1681 iter->second.m_eOpState = HekOpStateUncalibrated;
1682 m_eOpState = HekOpStateUncalibrated;
1691 m_eAsyncTaskId = AsyncTaskIdNone;
1692 m_pAsyncTaskArg = NULL;
1693 m_rcAsyncTask = -HEK_ECODE_INTR;
1694 m_eAsyncTaskState = HekAsyncTaskStateIdle;
1695 LOGDIAG3(
"Async task canceled.");
1699 HekAsyncTaskState HekRobot::getAsyncState()
1701 return m_eAsyncTaskState;
1704 int HekRobot::getAsyncRc()
1706 return m_rcAsyncTask;
1709 void *HekRobot::asyncThread(
void *pArg)
1715 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
1716 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
1719 LOGDIAG3(
"Async robot task thread created.");
1729 case AsyncTaskIdCalibrate:
1738 LOGERROR(
"Unknown async task id = %d.", (
int)pThis->
m_eAsyncTaskId);
1739 rc = -HEK_ECODE_BAD_VAL;
1748 LOGDIAG3(
"Async robot task thread exited.");
int m_nSlaveServoId
linked slave servo id (if any)
HekSpecServo_T * getServoSpec(int nServoId)
Get servo spec associated with servo id.
void * m_pAsyncTaskArg
asynchronous argument
int m_nSlaveServoId
linked slave servo id, if any
double m_fCalibPos
joint calibrated position (degrees)
int m_nErrorCode
hekateros error code
HekOpticalLimit_T m_limit[HekOptLimitMaxPerJoint]
optical limits
Hekateros robotic manipulator calibration by stretching class.
std::string m_strName
joint name
int m_nMaxSoftLimitOd
joint max soft limit (odometer ticks)
byte_t m_uBit
i/o expander bit position
HekOpState m_eOpState
current operational state
HekDesc - Hekateros full robotic manipulator descripition class interface.
Joint trajectory feedback class.
double m_fMinSoftLimitRads
joint min soft limit (radians)
int m_nOdPos
current master servo odometer pos (ticks)
int m_eLimitTypes
joint limit types
#define HEK_TRY_NO_EXEC()
Define if heketeros has RN system board.
Joint trajectory point class.
Hekateros end effector tool description class.
double m_fBalancedPos
joint balanced position (degrees)
Operational robotic joint description class.
double m_fGearRatio
joint gear ratio
int m_nSpeed
current master servo raw speed (unitless)
VecHealth m_vecServoHealth
servos' health
int m_rcAsyncTask
last async task return code
<b><i>Hekateros</i></b> optical limit switches.
void clear()
Clear all state data.
double m_fTicksPerJointRad
encoder/odom. ticks per joint radian
double m_fTicksPerServoRad
encoder/odom. ticks per servo radian
double m_fMaxServoRadsPerSec
maximum servo radians per second
int m_eJointType
joint type
HekTriState m_eIsInError
robot is [not] in error condition
double m_fMaxJointRadsPerSec
maximum joint radians per second
Hekateros tuning per joint data class.
double m_fPosition
current joint position (radians)
size_t getNumPoints()
Get the number of joint states in joint state point.
double m_fVelocity
current joint velocity (% of max)
Joint points and trajectory class interfaces.
HekTriState m_eIsEStopped
robot is [not] emergency stopped
#define M_TAU
tau = 2 * pi
double fcap(double a, double min, double max)
Cap value within limits [min, max].
bool m_bIsContinuous
servo should [not] be configured in 360 mode
int m_nMinPhyLimitOd
joint min phys limit (odometer ticks)
int m_nMasterServoId
master servo id
map< std::string, int > IMapRobotJoints
Indirect map of robot joints.
HekOpState m_eOpState
joint operational state
double m_fTorqueLimitPct
torque limit(%). Set to 0 for no limit
float m_fTemperature
servo temperature (Celsius)
double m_fParkPosRads
joint parked position (radians)
Hekateros Robot State classes interface.
uint_t m_uAlarms
servo alarms
int m_eLimitTypes
joint limit types
#define HEK_TRY_NOT_ESTOP()
Test for not estop.
void append(const HekJointState &jointState)
Append joint state to end of joint state point.
int m_nMasterServoId
master servo id
double m_fCalibPosRads
joint calibrated position (radians)
double m_fOverTorqueTh
over torque conditon threshold (fraction)
The Hekateros kinematics and dynamics class interface.
float m_fVoltage
servo voltage (volts)
HekSpec m_spec
fixed specification
double m_fMinPhyLimitRads
joint min physical limit (radians)
Hekateros Monitor Class interface.
bool m_bIsServoContinuous
servo should [not] be continuous mode
HekRobotMode m_eRobotMode
robot operating mode
HekXmlTune <b><i>Hekateros</i></b> XML tuning class.
int m_nMinSoftLimitOd
joint min soft limit (odometer ticks)
double m_fMinPhyLimit
joint minimum physical limit (degrees)
Hekateros joint classes interfaces.
int m_nMaxPhyLimitOd
joint max phys limit (odometer ticks)
virtual int calibrate()
Calibrate the <b><i>Hekateros</i></b>'s robotic arm.
byte_t m_byOptLimitMask[HekOptLimitMaxPerJoint]
optical limit mask array
HekSpecJoint_T * getJointSpecAt(int index)
Get joint spec at the given index.
Hekateros robotic arm (manipulator) description class.
bool m_bStopAtOptLimits
do [not] stop at optical limits
int m_nMasterServoId
master servo id
HekRobot - Hekateros Robot Class interface.
void setKinematicChainName(std::string strKinName)
Set the kinematic chain name.
double m_fParkedPos
joint parked position (degrees)
int m_nDir
normalize cw/ccw direction.
double m_fMaxPhyLimit
joint maximum physical limit (degrees)
std::string m_strName
joint name
std::string m_strName
joint name
int iabs(int a)
Integer absolute value.
int m_nDoF
degrees of freedom
Top-level package include file.
double degToRad(double d)
Convert degrees to radians.
double m_fMaxSoftLimitRads
joint max soft limit (radians)
int m_eJointType
joint type
double m_fBalPosRads
joint balanced position (radians)
int calibrate(bool bForceRecalib=true)
Calibrate <b><i>Hekateros</i></b>'s odometers and limit switch positions.
#define HEK_TRY_CONN()
Test for connection.
int m_nSlaveServoId
linked slave servo id (if any)
#define HEK_TRY_GET_SERVO(nServoId, pServo)
Convenience macro for trying to get a servo object from dynamixel chain.
int m_nMasterServoDir
master servo normalized direction
double m_fGearRatio
joint gear ratio
void append(const std::string &strName, double fPosition, double fVelocity, double fAcceleration=0.0)
Append joint point to end of trajectory.
HekTriState m_eIsInMotion
robot is [not] moving
<b><i>Hekateros</i></b> product specification base classes.
AsyncTaskId m_eAsyncTaskId
asynchronous task id
#define HEK_TRY_CALIB()
Test for calibration.
std::string getRealDeviceName(const std::string &strDevName)
Get real device name.
Hekateros robotic manipulator plus accesories class.
Hekateros common utilities.
double m_fEffort
current joint effort (servo load)
double m_fMaxPhyLimitRads
joint max physical limit (radians)
virtual int load(HekTunes &tunes, const std::string &strSearchPath=HekSysCfgPath, const std::string &strXmlFileName=HekEtcTune, bool bAllInstances=false)
Load XML file into DOM and set the <b><i>Hekateros</i></b> tuning parameters.
HekAsyncTaskState m_eAsyncTaskState
asynchronous task state
HekSpec m_spec
fixed specification
Robotic joint specification.
int m_nEncPos
current master servo encoder pos (ticks)
Robotic servo specification.
HekTriState m_eIsMotionPossible
motion is [not] possible
HekTriState m_eOptSwitch[HekOptLimitMaxPerJoint]
current state of optical switch(es)
HekTriState m_eAreDrivesPowered
servos are [not] powered
HekTriState m_eIsCalibrated
robot is [not] calibrated
The <b><i>Hekateros</i></b> namespace encapsulates all <b><i>Hekateros</i></b> related constructs...
<b><i>Hekateros</i></b> XML tuning class interface.
double m_fOverTorqueThDft
joint over torque th default (norm).