59 #include "rnr/rnrconfig.h" 62 #include "Dynamixel/Dynamixel.h" 63 #include "Dynamixel/DynaError.h" 64 #include "Dynamixel/DynaServo.h" 65 #include "Dynamixel/DynaChain.h" 87 HekKinematics::HekKinematics(DynaChain &dynaChain,
88 MapRobotJoints &kinJointDesc,
90 m_dynaChain(dynaChain)
92 MapRobotJoints::iterator iter;
103 for(iter=kinJointDesc.begin(); iter!=kinJointDesc.end(); ++iter)
105 pJoint = &iter->second;
110 if( strJointName ==
"wrist_rot" )
131 #ifdef HEK_KIN_EXEC_ALG_INDIV 133 #endif // HEK_KIN_EXEC_ALG_INDIV 145 #ifdef HEK_KIN_EXEC_ALG_SYNC 146 m_bWaitOneCycle =
false;
147 #endif // HEK_KIN_EXEC_ALG_SYNC 149 LOGDIAG3(
"Registered kinematic chain of %d joints and %d servos.",
155 KinChain::iterator iter;
164 if( iter->second != NULL )
197 #ifdef HEK_KIN_EXEC_ALG_INDIV 203 LOGERROR(
"WTF: Task list not matching kinematic chain.");
205 #endif // HEK_KIN_EXEC_ALG_INDIV 210 KinChain::iterator iter;
214 iter->second->reload(tunes);
222 KinChain::iterator iter;
229 if( iter->second->resetServoOdometer() ==
HEK_OK )
243 double &fJointCurPos,
244 double &fJointCurVel)
246 KinChain::iterator pos;
250 pos->second->getJointCurPosVel(fJointCurPos, fJointCurVel);
255 double &fJointCurPos,
256 double &fJointCurVel)
258 KinChain::iterator pos;
262 pos->second->getFilteredJointCurPosVel(fJointCurPos, fJointCurVel);
270 KinChain::iterator pos;
274 pos->second->getServoCurPosSpeed(nServoCurPos, nServoCurSpeed);
281 KinChain::iterator pos;
285 return pos->second->jointPosToServoPos(fPos);
296 KinChain::iterator pos;
300 return pos->second->servoPosToJointPos(nOdPos);
310 KinChain::iterator pos;
314 return pos->second->isStopped();
324 KinChain::iterator pos;
328 return pos->second->hasOverTorqueCondition();
338 KinChain::iterator pos;
343 rc = pos->second->resetServoOdometer();
347 LOGWARN(
"Joint %s: Not found in kinematic chain.", strJointName.c_str());
401 KinChain::iterator iter;
410 iter->second->stop();
418 vector<string>::const_iterator iter;
420 KinChain::iterator pos;
428 for(iter = vecJointNames.begin(), n = 0; iter != vecJointNames.end(); ++iter)
432 if( pos->second->stop() ==
HEK_OK )
443 KinChain::iterator pos;
453 rc = pos->second->stop();
457 LOGWARN(
"Joint %s: Not found in kinematic chain.", strJointName.c_str());
466 static const useconds_t WaitDt = 100;
468 KinChain::iterator iter;
470 int nMaxTries = (int)ceil(fSeconds * MILLION / (
double)WaitDt);
473 for(
int i = 0; i < nMaxTries; ++i)
479 if( !iter->second->isStopped() )
494 LOGERROR(
"Timed out waiting for %.2lf seconds for all joints to stop.",
505 double fJointGoalPos;
506 double fJointGoalVel;
507 double fJointGoalAcc;
508 KinChain::iterator pos;
512 for(i=0, nNumPts=0; i<trajectoryPoint.
getNumPoints(); ++i)
517 trajectoryPoint[i].get(strJointName, fJointGoalPos,
518 fJointGoalVel, fJointGoalAcc);
522 pos->second->specifyMove(fJointGoalPos, fJointGoalVel);
527 LOGWARN(
"Joint %s: Not found in kinematic chain.", strJointName.c_str());
543 const double fJointGoalPos,
544 const double fJointGoalVel)
546 KinChain::iterator pos;
553 rc = pos->second->specifyMove(fJointGoalPos, fJointGoalVel);
558 LOGWARN(
"Joint %s: Not found in kinematic chain.", strJointName.c_str());
569 TaskList::iterator iter;
579 TaskList::iterator iter;
589 TaskList::iterator iter;
600 TaskList::iterator iter;
618 if( (uCount = m_msgs.getSpeedTupleCount()) > 0 )
620 rc =
m_dynaChain.SyncWriteGoalSpeed(m_msgs.getSpeedTuples(), uCount);
623 if( (rc == DYNA_OK) && ((uCount = m_msgs.getOdPosTupleCount()) > 0) )
625 rc =
m_dynaChain.SyncWriteGoalPos(m_msgs.getOdPosTuples(), uCount);
648 LOGDIAG4(
"Kinematics Thread: Monitoring health for servo %d.",
649 pServo->GetServoId());
651 pServo->ReadHealth(&uAlarms, &nCurLoad, &uCurVolt, &uCurTemp);
654 #ifdef HEK_KIN_EXEC_ALG_SYNC 676 if( m_bWaitOneCycle )
678 m_bWaitOneCycle =
false;
685 #else // HEK_KIN_EXEC_ALG_INDIV 701 fprintf(stderr,
"DBG: %s(): task=%s\n", LOGFUNCNAME, strTask.c_str());
713 if( strTask ==
"health" )
734 #endif // HEK_KIN_EXEC_ALG_SYNC 742 LOGDIAG3(
"Kinematics thread created - ready to run.");
744 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
745 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
765 #ifdef HEK_KIN_EXEC_ALG_SYNC 766 LOGDIAG3(
"Kinematics thread started - running at %.1lf Hz.",
768 #else // HEK_KIN_EXEC_ALG_INDIV 769 LOGDIAG3(
"Kinematics thread started - " 770 "running at %.1lf Hz, %lf seconds/task.",
772 #endif // HEK_KIN_EXEC_ALG_SYNC 775 clock_gettime(CLOCK_REALTIME, &pThis->
m_tsSched);
797 LOGERROR(
"%d: Unexpected dynamixel background thread state.",
804 LOGDIAG3(
"Kinematics thread exited.");
812 struct sched_param parm;
816 pthread_attr_init(&attr);
825 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
830 parm.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1;
831 pthread_attr_setschedparam(&attr, &parm);
845 LOGSYSERROR(
"pthread_create()");
859 #ifdef HEK_KIN_EXEC_ALG_SYNC 861 #else // !HEK_KIN_EXEC_ALG_INDIV 863 #endif // HEK_KIN_EXEC_ALG_SYNC 868 0.0, (double)(BILLION-1) );
888 LOGERROR(
"Kinematics thread in invalid state %d to run.",
m_eState);
901 #ifdef HEK_KIN_EXEC_ALG_SYNC 906 m_bWaitOneCycle =
true;
913 #else // HEK_KIN_EXEC_ALG_INDIV 930 fprintf(stderr,
"DBG: %s(): taskonecycle=%s\n", LOGFUNCNAME,
931 strTaskOneCycle.c_str());
939 #endif // HEK_KIN_EXEC_ALG_SYNC 967 static bool bLogWarnings =
false;
968 struct timespec tsNow;
969 struct timespec tsSlip;
972 clock_gettime(CLOCK_REALTIME, &tsNow);
980 tsSlip.tv_sec = tsSlip.tv_nsec = 0;
987 clock_gettime(CLOCK_REALTIME, &tsNow);
1005 #ifdef HEK_KIN_EXEC_ALG_SYNC 1006 LOGWARN(
"Kinematics thread: " 1007 "Execution slipped by %ld.%09ld seconds.",
1008 tsSlip.tv_sec, tsSlip.tv_nsec);
1009 #else // HEK_KIN_EXEC_ALG_INDIV 1010 LOGWARN(
"Kinematics thread: " 1011 "Scheduled task %s slipped by %ld.%09ld seconds.",
1012 m_iterTask->c_str(), tsSlip.tv_sec, tsSlip.tv_nsec);
1013 #endif // HEK_KIN_EXEC_ALG_SYNC int getMasterServoId() const
Get master servo id.
virtual int stop()
Stop kinematics chain at the current position.
virtual void freeze()
Freeze kinematics chain at the current position.
virtual int waitForAllStop(double fSeconds)
Wait for all joints to stop.
virtual void sense()
Sense the state of all joints.
virtual void getJointCurPosVel(const std::string &strJointName, double &fJointCurPos, double &fJointCurVel)
Get the current instantaneous joint position and velocity.
static const int HEK_OK
not an error, success
double m_fHz
thread run rate (Hertz)
virtual bool isStopped(const std::string &strJointName)
Test if joint is moving.
virtual void react()
React to any necessary time-critical joint events.
Joint trajectory point class.
Operational robotic joint description class.
static void * thread(void *pArg)
The kinematics thread.
bool m_bIsControlling
[not] actively controlling joints
TaskList m_taskList
list of tasks to exec per cycle
ThreadState m_eState
thread state
Joint points and trajectory class interfaces.
static const int HEK_ECODE_TIMEDOUT
operation timed out error
thread created and ready to run
double fcap(double a, double min, double max)
Cap value within limits [min, max].
void lock()
Lock the kinematics thread.
Hekateros tuning data class.
std::string getJointName() const
Get joint name.
static const int HEK_ECODE_BAD_OP
invalid operation error
virtual int resetServoOdometersForAllJoints()
Reset all joints' master servos odometers to the current respective encoder positions.
KinChain m_kinChain
kinematic chain
static const double HekTuneKinHzMin
Minimum kinematics thread cycle rate (Hertz).
Hekateros powered joint dynamics and kinematics control class.
The Hekateros kinematics and dynamics class interface.
void createThread()
Create the kinematics thread.
void unlock()
Unlock the kinematics thread.
void waitOneCycle()
Wait one full cycle.
int runThread(const double fHz=HekTuneKinHzDft)
Run the kinematics thread.
double m_fKinematicsHz
kinematic thread rate (hertz)
virtual ~HekKinematics()
Desctructor.
Hekateros joint classes interfaces.
virtual void monitorHealth()
Monitor servo health thread task.
virtual int act()
Move all joints.
std::string m_strTaskOneCycle
task name one cycle away
void terminateThread()
Terminate the kinematics thread.
virtual void plan()
Plan motions for all joints.
int m_nNumServos
number of servos to monitor
virtual int resetServoOdometer(const std::string &strJointName)
Reset joint's master servo odometer to the current encoder position.
thread created but unitialized
static const int HEK_ECODE_DYNA
dynamixel error
pthread_t m_thread
pthread identifier
size_t getNumPoints()
Get the number of joint points in trajectory.
Top-level package include file.
struct timespec m_tsSched
working scheduler time stamp
pthread_mutex_t m_mutexSync
synchonization mutex
int jointPosToServoPos(const std::string &strJointName, const double fPos)
Convert joint position to the equivalent servo position.
virtual bool hasOverTorqueCondition(const std::string &strJointName)
Test if joint is in an over torque condition.
virtual void sense_react()
Sense-react the state of all joints.
virtual void exec()
Execute kinematics task(s).
struct timespec m_tsExecPeriod
task execution period (converted)
void schedWait()
Block kinematics thread until the next subcycle task is to be run.
virtual int senseDynamics(bool bIsControlling)
Sense (read) the current servo dynamics and transform to useful state.
virtual void setHz(const double fHz)
Set thread run rate and ancillary data.
void changeState(ThreadState eNewState)
Change the kinematics thread state.
pthread_cond_t m_condSync
synchonization condition
Hekateros common utilities.
virtual void release()
Release kinematics chain.
static const int HEK_ECODE_GEN
general, unspecified error
virtual void getFilteredJointCurPosVel(const std::string &strJointName, double &fJointCurPos, double &fJointCurVel)
Get the smoothed (filtered) current joint position and velocity.
virtual void estop()
Emergency stop the kinematics chain.
static const int HEK_ECODE_BAD_VAL
bad value general error
virtual int move(HekJointTrajectoryPoint &trajectoryPoint)
Move kinematic chain through a trajectory point.
void getServoCurPosSpeed(const std::string &strJointName, int &nServoCurPos, int &nServoCurSpeed)
Get the current servo position and speed.
Hekateros powered joint kinematics and dynamics control class interface.
virtual void buildTaskList()
Build ordered list of tasks to execute.
virtual int act()
Act (write) to effect the servo dynamics for torque and motion control.
DynaChain & m_dynaChain
dynamixel chain
double m_fTExec
task execution period (seconds)
int m_iterHealth
servo health iterator
void timedWait(const struct timespec &tsTimeout)
Timed wait until state change or time out.
virtual void reload(const HekTunes &tunes)
Reload configuration tuning parameters for all joints.
Special wrist rotation joint kinematics and dynamics class.
TaskList::iterator m_iterTask
task iterator
The <b><i>Hekateros</i></b> namespace encapsulates all <b><i>Hekateros</i></b> related constructs...
double servoPosToJointPos(const std::string &strJointName, const int nOdPos)
Convert servo position to the equivalent joint position.
int m_nHealthServoId
health monitoring servo id
void readyWait()
Wait indefinitely while in the ready state.
int m_nNumJoints
number of joints to control