Dynamixel  2.9.5
RoadNarrows Robotics Dynamixel Package
DynaBgThread Class Reference

#include <DynaBgThread.h>

Public Types

enum  BgThreadState {
  BgThreadStateZombie,
  BgThreadStateReady,
  BgThreadStateRunning,
  BgThreadStatePaused,
  BgThreadStateExit
}
 Background thread states. More...
 

Public Member Functions

 DynaBgThread (double fHz=HZ_EXEC_DFT, double fTolerance=TOLERANCE_DFT)
 Default initializer constructor. More...
 
virtual ~DynaBgThread ()
 Desctructor.
 
virtual void RegisterServoAgent (DynaServo *pServo)
 Register the Dynamixel servo for control and monitoring. More...
 
virtual void RegisterChainAgent (DynaChain *pChain)
 Register the Dynamixel chain for control and monitoring. More...
 
virtual void UnregisterAgent ()
 Unregister any chain or servo from control and monitoring. More...
 
virtual void RegisterUserCallback (void(*fnUserCb)(void *), void *pUserArg)
 Register user-defined callback function. More...
 
virtual void UnregisterUserCallback ()
 Unregister user-defined callback function.
 
virtual int Run ()
 Run the background thread control and monitoring tasks. More...
 
virtual int Stop ()
 Stop control and monitoring tasks. More...
 
virtual int Pause ()
 Pause control and monitoring tasks. More...
 
virtual int Resume ()
 Resume control and monitoring tasks. More...
 
BgThreadState GetCurrentState ()
 Get current background thread state. More...
 
void setHz (double fHz)
 Set new control and monitoring execution hertz rate. More...
 
double getHz ()
 Get control and monitoring hetrz rate. More...
 
bool isServoBeingControlled (int nServoId)
 Checks if servo is currently being controlled. More...
 

Static Public Member Functions

static int WriteGoalPos (int nServoId, int nOdGoalPos, void *pUserArg)
 Start controlling servo to rotate it to the given goal position. More...
 
static int WriteGoalSpeed (int nServoId, int nGoalSpeed, void *pUserArg)
 
static int WriteGoalSpeedPos (int nServoId, int nGoalSpeed, int nGoalPos, void *pUserArg)
 

Static Public Attributes

static const double HZ_EXEC_MIN = 1.0
 minimum exec hertz
 
static const double HZ_EXEC_DFT = 50.0
 default exec hertz
 
static const long T_EXEC_MIN = 100
 task exec period min (100usec)
 
static const double TOLERANCE_DFT = 1.0
 default pos. tolerance (deg)
 

Protected Types

typedef map< int, DynaVServoMapVServo
 Virtual Servo Associative Map Type.
 

Protected Member Functions

void lock ()
 Lock the background thread. More...
 
void unlock ()
 Unlock the background thread. More...
 
void changeState (DynaBgThread::BgThreadState eNewState)
 Change the background thread state. More...
 
void readyWait ()
 Wait indefinitely in ready state. More...
 
void timeWait (long lMicroSecs)
 Wait until state change or time out. More...
 
void setTolerance (double fTolerance)
 Set position tolerance. More...
 
virtual DynaServogetRegisteredServo (int nServoId)
 Get registered servo. More...
 
virtual DynaVServogetNextVServo (MapVServo::iterator &iter, int &nServoId)
 Get the next virtual servo. More...
 
virtual DynaVServogetPrevVServo (MapVServo::iterator &iter, int &nServoId)
 Get the previous virtual servo. More...
 
virtual void sched (long lPeriod)
 Schedule the Dynamixel background thread for the next task(s) to perform. More...
 
virtual void exec ()
 Execute background tasks. More...
 
virtual void execDynamics (DynaServo *pServo, DynaVServo *pVServo)
 Execute servo dynamics monitoring and control. More...
 
virtual void execTorqueCtl (DynaServo *pServo, DynaVServo *pVServo)
 Execute servo torque control. More...
 
virtual void execPosCtl (DynaServo *pServo, DynaVServo *pVServo)
 Execute servo position control. More...
 
virtual void stopPosCtl (DynaServo *pServo, DynaVServo *pVServo)
 Stop servo position control. More...
 
virtual void stopMotion (DynaServo *pServo)
 Stop servo motion. More...
 
virtual void monitorDynamics (DynaServo *pServo, DynaVServo *pVServo)
 Execute servo dynamics monitoring background task. More...
 
virtual void monitorHealth (DynaServo *pServo, DynaVServo *pVServo)
 Execute servo health monitoring background task. More...
 
void createThread ()
 Create the background thread. More...
 
void terminateThread ()
 Terminate the background thread. More...
 

Static Protected Member Functions

static void * bgThread (void *pArg)
 Dynamixel background thread. More...
 

Protected Attributes

BgThreadState m_eState
 thread state
 
pthread_mutex_t m_mutexSync
 synchonization mutex
 
pthread_cond_t m_condSync
 synchonization condition
 
pthread_t m_thread
 pthread identifier
 
DynaServom_pServo
 registered dynamixel servo
 
DynaChainm_pChain
 or registered dynamixel chain
 
MapVServo m_mapVServo
 virtual servo associative map
 
uint_t m_uNumServos
 number of servos to monitor
 
double m_fTolerance
 position ± tolerance (degrees)
 
DynaAgent_T m_agent
 servo/chain agent
 
void(* m_fnUserCb )(void *)
 user callback function
 
void * m_pUserArg
 user callback argument
 
double m_fHz
 thread execution hertz
 
long m_TExec
 full execution cycle μs period
 
struct timeval m_tvSched
 working scheduler time stamp
 
long m_TSched
 scheduler μs period
 
long m_dTSched
 scheduler delta time
 
MapVServo::iterator m_iterDynamics
 dynamics iterator
 
MapVServo::iterator m_iterHealth
 health iterator
 
int m_nHealthServoId
 current health monitoring servo id
 

Detailed Description

Dynamixel background thread.

The DynaBgThread class supports background control and monitoring of registered servos.

Definition at line 240 of file DynaBgThread.h.

Member Enumeration Documentation

Background thread states.

Enumerator
BgThreadStateZombie 

zombie instance - no thread exists

BgThreadStateReady 

thread created and ready to run

BgThreadStateRunning 

thread running

BgThreadStatePaused 

thread paused

BgThreadStateExit 

thread exiting

Definition at line 251 of file DynaBgThread.h.

252  {
253  BgThreadStateZombie, ///< zombie instance - no thread exists
254  BgThreadStateReady, ///< thread created and ready to run
255  BgThreadStateRunning, ///< thread running
256  BgThreadStatePaused, ///< thread paused
257  BgThreadStateExit ///< thread exiting
258  } BgThreadState;
BgThreadState
Background thread states.
Definition: DynaBgThread.h:251
zombie instance - no thread exists
Definition: DynaBgThread.h:253
thread created and ready to run
Definition: DynaBgThread.h:254

Constructor & Destructor Documentation

DynaBgThread::DynaBgThread ( double  fHz = HZ_EXEC_DFT,
double  fTolerance = TOLERANCE_DFT 
)

Default initializer constructor.

Parameters
fHzExecution hertz.
fTolerancePosition tolerance (degrees).

Definition at line 290 of file DynaBgThread.cxx.

References BG_TRACE_OPEN, DYNA_ID_NONE, and DynaVServo::m_mutexSync.

291 {
292  BG_TRACE_OPEN();
293 
294  pthread_mutex_init(&m_mutexSync, NULL);
295  pthread_cond_init(&m_condSync, NULL);
296 
297  m_pServo = NULL;
298  m_pChain = NULL;
299  m_uNumServos = 0;
300 
301  setTolerance(fTolerance);
302 
304  m_agent.m_fnWriteGoalSpeed = WriteGoalSpeed;
305  m_agent.m_fnWriteGoalSpeedPos = WriteGoalSpeedPos;
306 
307  m_fnUserCb = NULL;
308  m_pUserArg = NULL;
309 
310  m_iterDynamics = m_mapVServo.end();
311  m_iterHealth = m_mapVServo.end();
313 
314  setHz(fHz);
315 
316  // create background thread
317  createThread();
318 }
MapVServo m_mapVServo
virtual servo associative map
Definition: DynaBgThread.h:498
DynaAgent_T m_agent
servo/chain agent
Definition: DynaBgThread.h:503
MapVServo::iterator m_iterDynamics
dynamics iterator
Definition: DynaBgThread.h:517
void createThread()
Create the background thread.
void setTolerance(double fTolerance)
Set position tolerance.
Definition: DynaBgThread.h:586
int(* m_fnWriteGoalPos)(int nServoId, int nGoalPos, void *pUsrArg)
Definition: DynaTypes.h:233
pthread_cond_t m_condSync
synchonization condition
Definition: DynaBgThread.h:492
int(* m_fnWriteGoalSpeedPos)(int nServoId, int nGoalSpeed, int nGoalPos, void *pUsrArg)
Definition: DynaTypes.h:239
pthread_mutex_t m_mutexSync
synchonization mutex
Definition: DynaBgThread.h:491
uint_t m_uNumServos
number of servos to monitor
Definition: DynaBgThread.h:499
void(* m_fnUserCb)(void *)
user callback function
Definition: DynaBgThread.h:506
int m_nHealthServoId
current health monitoring servo id
Definition: DynaBgThread.h:519
#define BG_TRACE_OPEN()
No tracing file open.
void * m_pUserArg
user callback argument
Definition: DynaBgThread.h:507
int(* m_fnWriteGoalSpeed)(int nServoId, int nGoalSpeed, void *pUsrArg)
Definition: DynaTypes.h:236
DynaServo * m_pServo
registered dynamixel servo
Definition: DynaBgThread.h:496
static int WriteGoalPos(int nServoId, int nOdGoalPos, void *pUserArg)
Start controlling servo to rotate it to the given goal position.
MapVServo::iterator m_iterHealth
health iterator
Definition: DynaBgThread.h:518
#define DYNA_ID_NONE
no servo id
Definition: Dynamixel.h:145
void setHz(double fHz)
Set new control and monitoring execution hertz rate.
DynaChain * m_pChain
or registered dynamixel chain
Definition: DynaBgThread.h:497

Member Function Documentation

void * DynaBgThread::bgThread ( void *  pArg)
staticprotected

Dynamixel background thread.

Cannot have gui calls in this thread.

Parameters
pArgThread argument (point to DynaBgThread object).
Returns
Returns NULL on thread exit.

Definition at line 1187 of file DynaBgThread.cxx.

References exec(), m_eState, m_TSched, m_uNumServos, readyWait(), and sched().

Referenced by createThread().

1188 {
1189  DynaBgThread *pThis = (DynaBgThread *)pArg;
1190  int rc;
1191 
1192  LOGDIAG3("Dynamixel background thread created.");
1193 
1194  //
1195  // Loop forever until exit
1196  //
1197  while( (pThis->m_eState != BgThreadStateExit) )
1198  {
1199  switch( pThis->m_eState )
1200  {
1201  case BgThreadStateReady:
1202  case BgThreadStatePaused:
1203  pThis->readyWait();
1204  LOGDIAG3("New state: %d: t_sched=%lu",
1205  pThis->m_eState, pThis->m_TSched);
1206  break;
1207  case BgThreadStateRunning:
1208  if( pThis->m_uNumServos > 0 )
1209  {
1210  pThis->sched(pThis->m_TSched);
1211  if( pThis->m_eState == BgThreadStateRunning )
1212  {
1213  pThis->exec();
1214  }
1215  }
1216  else // nothing to do
1217  {
1218  // slowly
1219  pThis->sched(500000);
1220  }
1221  break;
1222  case BgThreadStateExit:
1223  break;
1224  default:
1225  LOGERROR("%d: Unexpected dynamixel background thread state.",
1226  pThis->m_eState);
1227  pThis->m_eState = BgThreadStateExit;
1228  break;
1229  }
1230  }
1231 
1232  pThis->m_eState = BgThreadStateZombie;
1233 
1234  LOGDIAG3("Dynamixel background thread exited.");
1235 
1236  return NULL;
1237 }
zombie instance - no thread exists
Definition: DynaBgThread.h:253
thread created and ready to run
Definition: DynaBgThread.h:254
uint_t m_uNumServos
number of servos to monitor
Definition: DynaBgThread.h:499
long m_TSched
scheduler &mu;s period
Definition: DynaBgThread.h:513
BgThreadState m_eState
thread state
Definition: DynaBgThread.h:490
virtual void sched(long lPeriod)
Schedule the Dynamixel background thread for the next task(s) to perform.
virtual void exec()
Execute background tasks.
void readyWait()
Wait indefinitely in ready state.
void DynaBgThread::changeState ( DynaBgThread::BgThreadState  eNewState)
protected

Change the background thread state.

Parameters
eNewStateNew state.
Context:
Calling thread or background thread.

Definition at line 769 of file DynaBgThread.cxx.

References DynaVServo::m_eState.

770 {
771  m_eState = eNewState;
772  pthread_cond_signal(&m_condSync);
773 }
pthread_cond_t m_condSync
synchonization condition
Definition: DynaBgThread.h:492
BgThreadState m_eState
thread state
Definition: DynaBgThread.h:490
void DynaBgThread::createThread ( )
protected

Create the background thread.

Context:
Calling thread.

Definition at line 1239 of file DynaBgThread.cxx.

References bgThread(), and DynaVServo::m_eState.

1240 {
1241  int rc;
1242 
1244 
1245  rc = pthread_create(&m_thread, NULL, DynaBgThread::bgThread, (void *)this);
1246 
1247  if( rc != 0 )
1248  {
1249  LOGSYSERROR("pthread_create()");
1251  }
1252 }
pthread_t m_thread
pthread identifier
Definition: DynaBgThread.h:493
zombie instance - no thread exists
Definition: DynaBgThread.h:253
thread created and ready to run
Definition: DynaBgThread.h:254
BgThreadState m_eState
thread state
Definition: DynaBgThread.h:490
static void * bgThread(void *pArg)
Dynamixel background thread.
void DynaBgThread::exec ( )
protectedvirtual

Execute background tasks.

Context:
Background thread.

Definition at line 868 of file DynaBgThread.cxx.

Referenced by bgThread().

869 {
870  int nServoId;
871  DynaVServo *pVServo;
872  DynaServo *pServo;
873 
874  //
875  // Get the next virtual servo.
876  //
877  if( (pVServo = getNextVServo(m_iterDynamics, nServoId)) == NULL )
878  {
879  return;
880  }
881 
882  //
883  // Get the associated registered servo.
884  //
885  if( (pServo = getRegisteredServo(nServoId)) == NULL )
886  {
887  // can't find servo - erase entry from vServo map
888  m_mapVServo.erase(nServoId);
889  m_uNumServos = (uint_t)m_mapVServo.size();
890  return;
891  }
892 
893  //
894  // Execute servo dynamics monitoring and control.
895  //
896  execDynamics(pServo, pVServo);
897 
898  //
899  // Monitor servo health.
900  //
901  if( nServoId == m_nHealthServoId )
902  {
903  monitorHealth(pServo, pVServo);
905  }
906 
907  //
908  // User callback
909  //
910  if( m_fnUserCb != NULL )
911  {
913  }
914 }
MapVServo m_mapVServo
virtual servo associative map
Definition: DynaBgThread.h:498
MapVServo::iterator m_iterDynamics
dynamics iterator
Definition: DynaBgThread.h:517
virtual DynaVServo * getPrevVServo(MapVServo::iterator &iter, int &nServoId)
Get the previous virtual servo.
Definition: DynaBgThread.h:634
uint_t m_uNumServos
number of servos to monitor
Definition: DynaBgThread.h:499
Dynamixel Servo Abstract Base Class.
Definition: DynaServo.h:78
void(* m_fnUserCb)(void *)
user callback function
Definition: DynaBgThread.h:506
int m_nHealthServoId
current health monitoring servo id
Definition: DynaBgThread.h:519
void * m_pUserArg
user callback argument
Definition: DynaBgThread.h:507
virtual DynaServo * getRegisteredServo(int nServoId)
Get registered servo.
Background Thread Virtual Servo Class.
Definition: DynaBgThread.h:87
virtual DynaVServo * getNextVServo(MapVServo::iterator &iter, int &nServoId)
Get the next virtual servo.
Definition: DynaBgThread.h:608
MapVServo::iterator m_iterHealth
health iterator
Definition: DynaBgThread.h:518
virtual void execDynamics(DynaServo *pServo, DynaVServo *pVServo)
Execute servo dynamics monitoring and control.
virtual void monitorHealth(DynaServo *pServo, DynaVServo *pVServo)
Execute servo health monitoring background task.
void DynaBgThread::execDynamics ( DynaServo pServo,
DynaVServo pVServo 
)
protectedvirtual

Execute servo dynamics monitoring and control.

Parameters
pServoPointer to registered servo.
pVServoPointer to associated virtual servo.
Context:
Background thread.

Definition at line 916 of file DynaBgThread.cxx.

References DYNA_GET_DIR, DYNA_SPEED_CONT_STOP, DynaVServo::getGoalDir(), DynaServo::GetState(), DynaVServo::lock(), DynaVServo::m_bOverTorqueCond, DynaVServo::m_bOverTorqueCtl, DynaServoState_T::m_bTorqueEnabled, DynaVServo::m_eState, DynaVServo::m_fTorqueOut, DynaVServo::m_nGoalSpeed, DynaVServo::StateIdle, and DynaVServo::unlock().

917 {
918  pVServo->lock();
919 
920  //
921  // Read relavent servo state dynamics.
922  //
923  monitorDynamics(pServo, pVServo);
924 
925  //
926  // Servo in torque overload condition, ease motor drive if possible.
927  //
928  if( pServo->GetState().m_bTorqueEnabled &&
929  (pVServo->m_bOverTorqueCond || pVServo->m_bOverTorqueCtl) )
930  {
931  execTorqueCtl(pServo, pVServo);
932  }
933 
934  //
935  // Servo not driven or state is idle.
936  //
937  if( !pServo->GetState().m_bTorqueEnabled ||
938  (pVServo->m_eState == DynaVServo::StateIdle) )
939  {
940  // do nothing
941  }
942 
943  //
944  // Stop servo.
945  //
946  else if( pVServo->m_nGoalSpeed == DYNA_SPEED_CONT_STOP )
947  {
948  stopPosCtl(pServo, pVServo);
949  }
950 
951  //
952  // Servo in torque overload condition and goal direction is in the same
953  // direction as the load, which would exasperate the condition.
954  //
955  else if( pVServo->m_bOverTorqueCond &&
956  (pVServo->getGoalDir(pServo) != DYNA_GET_DIR(pVServo->m_fTorqueOut)) )
957  {
958  //stopPosCtl(pServo, pVServo);
959  }
960 
961  //
962  // PID control servo to goal position.
963  //
964  else
965  {
966  execPosCtl(pServo, pVServo);
967  }
968 
969  pVServo->unlock();
970 }
virtual const DynaServoState_T & GetState() const
Get servo state.
Definition: DynaServo.h:205
int m_nGoalSpeed
current goal speed
Definition: DynaBgThread.h:115
double m_fTorqueOut
low-pass filtered torque
Definition: DynaBgThread.h:118
bool m_bOverTorqueCtl
[not] in torque overload control
Definition: DynaBgThread.h:117
virtual void execPosCtl(DynaServo *pServo, DynaVServo *pVServo)
Execute servo position control.
bool m_bOverTorqueCond
is [not] in torque overload condition
Definition: DynaBgThread.h:116
void unlock()
Unlock the virtual servo.
Definition: DynaBgThread.h:220
bool_t m_bTorqueEnabled
torque [not] enabled
Definition: DynaTypes.h:197
int getGoalDir(DynaServo *pServo)
Get the current goal rotation direction.
Definition: DynaBgThread.h:186
VServoState m_eState
virtual servo state
Definition: DynaBgThread.h:111
virtual void monitorDynamics(DynaServo *pServo, DynaVServo *pVServo)
Execute servo dynamics monitoring background task.
no active position control
Definition: DynaBgThread.h:103
virtual void execTorqueCtl(DynaServo *pServo, DynaVServo *pVServo)
Execute servo torque control.
#define DYNA_GET_DIR(scalar)
Get the direction component, given the rotational scalar.
Definition: Dynamixel.h:200
void lock()
Lock the virtual servo.
Definition: DynaBgThread.h:206
virtual void stopPosCtl(DynaServo *pServo, DynaVServo *pVServo)
Stop servo position control.
#define DYNA_SPEED_CONT_STOP
continuous mode: stop
Definition: Dynamixel.h:261
void DynaBgThread::execPosCtl ( DynaServo pServo,
DynaVServo pVServo 
)
protectedvirtual

Execute servo position control.

Parameters
pServoPointer to registered servo.
pVServoPointer to associated virtual servo.
Context:
Background thread.

Definition at line 1030 of file DynaBgThread.cxx.

References BG_TRACE, DynaPid::Control(), DYNA_MODE_SERVO, DYNA_OK, DYNA_SPEED_CONT_STOP, DynaPid::GetError(), DynaServo::GetOdometer(), DynaServo::GetServoId(), DynaServo::GetServoMode(), iabs(), DynaVServo::m_eState, DynaVServo::m_nGoalSpeed, DynaVServo::m_nOdGoalPos, DynaVServo::m_nTolerance, DynaVServo::m_pidPos, and DynaVServo::StateIdle.

1031 {
1032  int nOdGoalPos; // goal position
1033  int nGoalSpeed; // goal speed
1034  int nCurPos; // current position
1035  int nCurSpeed; // current speed
1036  int nErr; // position difference error
1037  double dt; // delta time
1038 
1039  //
1040  // Once goal position is set, servo mode servos move on there own.
1041  //
1042  if( pServo->GetServoMode() == DYNA_MODE_SERVO )
1043  {
1044  nGoalSpeed = pVServo->m_nGoalSpeed;
1045  nOdGoalPos = pVServo->m_nOdGoalPos;
1046 
1047  // stop
1048  if( iabs(nGoalSpeed) == 0 )
1049  {
1050  stopPosCtl(pServo, pVServo);
1051  }
1052 
1053  pVServo->m_eState = DynaVServo::StateIdle;
1054 
1055  return;
1056  }
1057 
1058  else
1059  {
1060  nCurPos = pServo->GetOdometer();
1061 
1062  dt = (double)m_dTSched/1000000.0;
1063 
1064  nGoalSpeed = (int)pVServo->m_pidPos.Control((double)nCurPos, dt);
1065  nErr = (int)pVServo->m_pidPos.GetError();
1066 
1067  if( (iabs(nErr) < pVServo->m_nTolerance) ||
1068  (nGoalSpeed == DYNA_SPEED_CONT_STOP) )
1069  {
1070  stopPosCtl(pServo, pVServo);
1071  }
1072  else if( pServo->WriteGoalSpeed(nGoalSpeed) == DYNA_OK )
1073  {
1074  BG_TRACE(BG_TRACE_FILTER_POSCTL, pServo->GetServoId(), "MOVE",
1075  "goalspeed=%d, cur_od_pos=%d, goal_od_pos=%d, diff=%d\n",
1076  nGoalSpeed,
1077  nCurPos,
1078  pVServo->m_nOdGoalPos,
1079  nErr);
1080  }
1081  }
1082 }
virtual uint_t GetServoMode() const
Get the servo operational mode.
Definition: DynaServo.h:165
double GetError() const
Get current error.
Definition: DynaPid.h:199
virtual double Control(double fPV, double dt)
Apply PID control.
Definition: DynaPid.cxx:83
#define DYNA_OK
not an error, success
Definition: Dynamixel.h:78
int m_nGoalSpeed
current goal speed
Definition: DynaBgThread.h:115
#define DYNA_MODE_SERVO
servo mode with limited rotation
Definition: Dynamixel.h:170
#define BG_TRACE(mask, servoid, prefix, fmt,...)
No tracing output.
INLINE_IN_H int iabs(int a)
Return absolute value of a.
Definition: DynaOlio.h:91
VServoState m_eState
virtual servo state
Definition: DynaBgThread.h:111
no active position control
Definition: DynaBgThread.h:103
int m_nOdGoalPos
current goal position
Definition: DynaBgThread.h:114
virtual uint_t GetServoId() const
Get servo id.
Definition: DynaServo.h:155
DynaPidPos m_pidPos
servo position PID
Definition: DynaBgThread.h:112
long m_dTSched
scheduler delta time
Definition: DynaBgThread.h:514
int GetOdometer()
Get the current virtual odometer value.
Definition: DynaServo.h:304
virtual void stopPosCtl(DynaServo *pServo, DynaVServo *pVServo)
Stop servo position control.
#define DYNA_SPEED_CONT_STOP
continuous mode: stop
Definition: Dynamixel.h:261
int m_nTolerance
position &plusmn; tolerance (ticks)
Definition: DynaBgThread.h:113
void DynaBgThread::execTorqueCtl ( DynaServo pServo,
DynaVServo pVServo 
)
protectedvirtual

Execute servo torque control.

Parameters
pServoPointer to registered servo.
pVServoPointer to associated virtual servo.
Context:
Background thread.

Definition at line 972 of file DynaBgThread.cxx.

References BG_TRACE, DYNA_GET_DIR, DYNA_MODE_CONTINUOUS, DYNA_MODE_SERVO, DYNA_SPEED_CONT_STOP, DynaServo::GetOdometer(), DynaServo::GetServoId(), DynaServo::GetServoMode(), DynaServo::GetSoftTorqueThresholds(), DynaVServo::GOAL_SPEED_DFT, DynaVServo::m_bOverTorqueCtl, and DynaVServo::m_fTorqueOut.

973 {
974  double fTorqueAvg; // filtered load
975  uint_t uOverTorqueTh; // set over torque condition threshold
976  uint_t uClearTorqueTh; // clear over torque condition threshold
977  int nCurPos; // current position
978  int sign; // torque release direction sign
979  int nGoalSpeed; // goal speed
980  int nGoalPos; // goal position
981 
982  LOGWARN("BGThread: Executing torque control for servo %d, torque=%.2lf.",
983  pServo->GetServoId(), pVServo->m_fTorqueOut);
984 
985  pServo->GetSoftTorqueThresholds(uOverTorqueTh, uClearTorqueTh);
986 
987  fTorqueAvg = pVServo->m_fTorqueOut;
988 
989  if( (uint_t)fabs(fTorqueAvg) > uOverTorqueTh )
990  {
991  sign = DYNA_GET_DIR(fTorqueAvg);
992 
993  nGoalSpeed = DynaVServo::GOAL_SPEED_DFT;
994 
995  nCurPos = pServo->GetOdometer();
996  nGoalPos = nCurPos + sign * 5;
997 
998  switch( pServo->GetServoMode() )
999  {
1000  case DYNA_MODE_CONTINUOUS:
1001  nGoalSpeed = nGoalSpeed * sign;
1002  pServo->WriteGoalSpeed(nGoalSpeed);
1003  usleep(1000); // RDK hack
1004  stopMotion(pServo);
1005  break;
1006 
1007  case DYNA_MODE_SERVO:
1008  default:
1009  pServo->WriteGoalSpeed(nGoalSpeed);
1010  pServo->WriteGoalPos(nGoalPos);
1011  break;
1012  }
1013 
1014  pVServo->m_bOverTorqueCtl = true;
1015 
1016  BG_TRACE(BG_TRACE_FILTER_TORQCTL, pServo->GetServoId(), "TORQUECTL",
1017  "cur_load=%d, filtered_load=%.2lf, cur_od_pos=%d, "
1018  "goal_speed=%d, goal_od_pos=%d\n",
1019  nCurLoad, fTorqueAvg, nCurPos, nGoalSpeed, nGoalPos);
1020  }
1021 
1022  // stop servo, but don't touch current goals
1023  else
1024  {
1025  pVServo->m_bOverTorqueCtl = false;
1026  pServo->WriteGoalSpeed(DYNA_SPEED_CONT_STOP);
1027  }
1028 }
virtual uint_t GetServoMode() const
Get the servo operational mode.
Definition: DynaServo.h:165
#define DYNA_MODE_SERVO
servo mode with limited rotation
Definition: Dynamixel.h:170
double m_fTorqueOut
low-pass filtered torque
Definition: DynaBgThread.h:118
#define BG_TRACE(mask, servoid, prefix, fmt,...)
No tracing output.
bool m_bOverTorqueCtl
[not] in torque overload control
Definition: DynaBgThread.h:117
static const int GOAL_SPEED_DFT
default virutal goal speed
Definition: DynaBgThread.h:96
#define DYNA_MODE_CONTINUOUS
continuous mode with/without position
Definition: Dynamixel.h:171
#define DYNA_GET_DIR(scalar)
Get the direction component, given the rotational scalar.
Definition: Dynamixel.h:200
virtual uint_t GetServoId() const
Get servo id.
Definition: DynaServo.h:155
virtual void stopMotion(DynaServo *pServo)
Stop servo motion.
int GetOdometer()
Get the current virtual odometer value.
Definition: DynaServo.h:304
#define DYNA_SPEED_CONT_STOP
continuous mode: stop
Definition: Dynamixel.h:261
virtual void GetSoftTorqueThresholds(uint_t &uOverTorqueTh, uint_t &uClearTorqueTh)
Get soft torque thresholds.
Definition: DynaServo.h:546
BgThreadState DynaBgThread::GetCurrentState ( )
inline

Get current background thread state.

Returns
DynaBgThread::BgThreadState

Definition at line 415 of file DynaBgThread.h.

Referenced by DynaShellCmdCreate::Exec(), DynaShellCmdDestroy::Exec(), DynaShellCmdScan::Exec(), DynaShellCmdBgtStart::Exec(), DynaShellCmdBgtStop::Exec(), and DynaShellCmdBgtGetState::Exec().

416  {
417  return m_eState;
418  }
BgThreadState m_eState
thread state
Definition: DynaBgThread.h:490
double DynaBgThread::getHz ( )
inline

Get control and monitoring hetrz rate.

Returns
Execution hertz.

Definition at line 457 of file DynaBgThread.h.

Referenced by DynaShellCmdBgtStart::Exec(), and DynaShellCmdBgtGetState::Exec().

458  {
459  return m_fHz;
460  }
double m_fHz
thread execution hertz
Definition: DynaBgThread.h:510
virtual DynaVServo* DynaBgThread::getNextVServo ( MapVServo::iterator &  iter,
int &  nServoId 
)
inlineprotectedvirtual

Get the next virtual servo.

Parameters
[in,out]iterIterator at current position.
[out]nServoIdServo id.
Returns
Returns pointer to virtual servo on success. NULL on failure.

Definition at line 608 of file DynaBgThread.h.

609  {
610  if( m_mapVServo.size() == 0 )
611  {
612  return NULL;
613  }
614 
615  ++iter;
616 
617  if( iter == m_mapVServo.end() )
618  {
619  iter = m_mapVServo.begin();
620  }
621 
622  nServoId = iter->first;
623  return &(iter->second);
624  }
MapVServo m_mapVServo
virtual servo associative map
Definition: DynaBgThread.h:498
virtual DynaVServo* DynaBgThread::getPrevVServo ( MapVServo::iterator &  iter,
int &  nServoId 
)
inlineprotectedvirtual

Get the previous virtual servo.

Parameters
[in,out]iterIterator at current position.
[out]nServoIdServo id.
Returns
Returns pointer to virtual servo on success. NULL on failure.

Definition at line 634 of file DynaBgThread.h.

635  {
636  if( m_mapVServo.size() == 0 )
637  {
638  return NULL;
639  }
640 
641  if( iter == m_mapVServo.begin() )
642  {
643  iter = m_mapVServo.end();
644  }
645 
646  --iter;
647 
648  nServoId = iter->first;
649  return &(iter->second);
650  }
MapVServo m_mapVServo
virtual servo associative map
Definition: DynaBgThread.h:498
DynaServo * DynaBgThread::getRegisteredServo ( int  nServoId)
protectedvirtual

Get registered servo.

Parameters
nServoIdServo id.
Returns
Returns pointer to servo on success. NULL on failure.

Definition at line 810 of file DynaBgThread.cxx.

References DynaServo::GetServoId().

Referenced by WriteGoalPos().

811 {
812  if( m_pChain != NULL )
813  {
814  return m_pChain->GetServo(nServoId);
815  }
816  else if( m_pServo != NULL )
817  {
818  return m_pServo->GetServoId() == nServoId? m_pServo: NULL;
819  }
820  else
821  {
822  return NULL;
823  }
824 }
DynaServo * m_pServo
registered dynamixel servo
Definition: DynaBgThread.h:496
virtual DynaServo * GetServo(int nServoId)
Definition: DynaChain.h:129
virtual uint_t GetServoId() const
Get servo id.
Definition: DynaServo.h:155
DynaChain * m_pChain
or registered dynamixel chain
Definition: DynaBgThread.h:497
bool DynaBgThread::isServoBeingControlled ( int  nServoId)
inline

Checks if servo is currently being controlled.

Parameters
nServoIdServo Id.
Returns
Returns true or false.

Definition at line 469 of file DynaBgThread.h.

References DynaVServo::StateControl.

470  {
471  MapVServo::iterator pos;
472 
473  if( (pos = m_mapVServo.find(nServoId)) != m_mapVServo.end() )
474  {
475  return pos->second.m_eState == DynaVServo::StateControl? true: false;
476  }
477  else
478  {
479  return false;
480  }
481  }
MapVServo m_mapVServo
virtual servo associative map
Definition: DynaBgThread.h:498
in poistion control
Definition: DynaBgThread.h:105
void DynaBgThread::lock ( )
inlineprotected

Lock the background thread.

The calling thread will block while waiting for the mutex to become available. Once locked, the background thread will block.

The lock()/unlock() primitives provide a safe mechanism to modify the registered vServo data.

Context:
Any.

Definition at line 533 of file DynaBgThread.h.

534  {
535  pthread_mutex_lock(&m_mutexSync);
536  }
pthread_mutex_t m_mutexSync
synchonization mutex
Definition: DynaBgThread.h:491
void DynaBgThread::monitorDynamics ( DynaServo pServo,
DynaVServo pVServo 
)
protectedvirtual

Execute servo dynamics monitoring background task.

Parameters
pServoPointer to registered servo.
pVServoPointer to associated virtual servo.
Context:
Background thread.

Definition at line 1129 of file DynaBgThread.cxx.

References BG_TRACE, DynaVServo::filterTorques(), DynaServo::GetServoId(), DynaServo::GetSoftTorqueThresholds(), DynaServo::HasSoftTorqueOverCond(), DynaVServo::m_bOverTorqueCond, DynaVServo::m_fTorqueOut, and DynaServo::SetSoftTorqueOverCond().

1130 {
1131  int nCurPos;
1132  int nCurSpeed;
1133  int nCurLoad;
1134  uint_t uTorqueAvg;
1135  uint_t uOverTorqueTh;
1136  uint_t uClearTorqueTh;
1137  bool bCurOverCond;
1138 
1139  // read the servo dynamics.
1140  if( pServo->ReadDynamics(&nCurPos, &nCurSpeed, &nCurLoad) >= 0 )
1141  {
1142  uTorqueAvg = (uint_t)fabs(pVServo->filterTorques(nCurLoad));
1143 
1144  pServo->GetSoftTorqueThresholds(uOverTorqueTh, uClearTorqueTh);
1145 
1146  bCurOverCond = pServo->HasSoftTorqueOverCond();
1147 
1148  // set over torque limit condition
1149  if( uTorqueAvg > uOverTorqueTh )
1150  {
1151  pVServo->m_bOverTorqueCond = true;
1152  pServo->SetSoftTorqueOverCond(true);
1153  }
1154 
1155  // clear over torque limit condition
1156  else if( (uTorqueAvg < uClearTorqueTh) && bCurOverCond )
1157  {
1158  pVServo->m_bOverTorqueCond = false;
1159  pServo->SetSoftTorqueOverCond(false);
1160  }
1161 
1162  BG_TRACE(BG_TRACE_FILTER_DYNA, pServo->GetServoId(), "DYNAMICS",
1163  "pos=%d, speed=%d, cur_load=%d, filtered_load=%.2lf, overtorque=%s\n",
1164  nCurPos, nCurSpeed, nCurLoad, pVServo->m_fTorqueOut,
1165  (pServo->HasSoftTorqueOverCond()? "true": "false"));
1166  }
1167 }
virtual void SetSoftTorqueOverCond(bool bNewCond)
Set or clear servo in soft over torque condition.
Definition: DynaServo.h:558
double m_fTorqueOut
low-pass filtered torque
Definition: DynaBgThread.h:118
#define BG_TRACE(mask, servoid, prefix, fmt,...)
No tracing output.
bool m_bOverTorqueCond
is [not] in torque overload condition
Definition: DynaBgThread.h:116
double filterTorques(int nServoLoad)
Apply a low-pass band filter on the sensed torques (loads).
virtual bool HasSoftTorqueOverCond()
Test if servo is in a soft over torque condition.
Definition: DynaServo.h:568
virtual uint_t GetServoId() const
Get servo id.
Definition: DynaServo.h:155
virtual void GetSoftTorqueThresholds(uint_t &uOverTorqueTh, uint_t &uClearTorqueTh)
Get soft torque thresholds.
Definition: DynaServo.h:546
void DynaBgThread::monitorHealth ( DynaServo pServo,
DynaVServo pVServo 
)
protectedvirtual

Execute servo health monitoring background task.

Parameters
pServoPointer to registered servo.
pVServoPointer to associated virtual servo.
Context:
Background thread.

Definition at line 1169 of file DynaBgThread.cxx.

References BG_TRACE, and DynaServo::GetServoId().

1170 {
1171  uint_t uAlarms;
1172  int nCurLoad;
1173  uint_t uCurVolt;
1174  uint_t uCurTemp;
1175 
1176  LOGDIAG4("BGThread: Monitoring health for servo %d.", pServo->GetServoId());
1177 
1178  pServo->ReadHealth(&uAlarms, &nCurLoad, &uCurVolt, &uCurTemp);
1179 
1180  //pVServo->filterTorques(nCurLoad);
1181 
1182  BG_TRACE(BG_TRACE_FILTER_HEALTH, pServo->GetServoId(), "HEALTH",
1183  "load=%d, voltage=%u, temperature=%u, alarms=0x%02x\n",
1184  nCurLoad, uCurVolt, uCurTemp, uAlarms);
1185 }
#define BG_TRACE(mask, servoid, prefix, fmt,...)
No tracing output.
virtual uint_t GetServoId() const
Get servo id.
Definition: DynaServo.h:155
int DynaBgThread::Pause ( )
virtual

Pause control and monitoring tasks.

The Pause()/Resume() actions provide a safe mechanism to modify the registered dynamixel chain and/or alter the time periods. When the thread is resumed, the time periods are automatically recalculated since the mix of servos in the chain could have changed.

Valid Current States:
BgThreadStateRunning BgThreadStatePaused
New State:
BgThreadStatePaused
Context:
Calling thread.

Definition at line 490 of file DynaBgThread.cxx.

References DYNA_ECODE_GEN, DYNA_LOG_ERROR, DYNA_OK, and DynaVServo::m_eState.

491 {
492  int rc;
493 
494  switch( m_eState )
495  {
497  case BgThreadStatePaused:
499  LOGDIAG3("Background thread paused.");
500  rc = DYNA_OK;
501  break;
502  case BgThreadStateZombie:
503  rc = -DYNA_ECODE_GEN;
504  DYNA_LOG_ERROR(rc, "No background thread.");
505  break;
506  case BgThreadStateReady:
507  case BgThreadStateExit:
508  default:
509  rc = -DYNA_ECODE_GEN;
510  DYNA_LOG_ERROR(rc, "Background thread in invalid state %d.", m_eState);
511  break;
512  }
513 
514  return rc;
515 }
#define DYNA_OK
not an error, success
Definition: Dynamixel.h:78
zombie instance - no thread exists
Definition: DynaBgThread.h:253
thread created and ready to run
Definition: DynaBgThread.h:254
void changeState(DynaBgThread::BgThreadState eNewState)
Change the background thread state.
#define DYNA_LOG_ERROR(ecode, efmt,...)
Log Error.
#define DYNA_ECODE_GEN
general, unspecified error
Definition: Dynamixel.h:80
BgThreadState m_eState
thread state
Definition: DynaBgThread.h:490
void DynaBgThread::readyWait ( )
protected

Wait indefinitely in ready state.

Context:
Calling thread or background thread.

Definition at line 775 of file DynaBgThread.cxx.

References DynaVServo::lock(), DynaVServo::m_eState, DynaVServo::m_mutexSync, and DynaVServo::unlock().

Referenced by bgThread().

776 {
777  lock();
778  while( m_eState == BgThreadStateReady )
779  {
780  pthread_cond_wait(&m_condSync, &m_mutexSync);
781  }
782  unlock();
783 }
void unlock()
Unlock the background thread.
Definition: DynaBgThread.h:547
thread created and ready to run
Definition: DynaBgThread.h:254
pthread_cond_t m_condSync
synchonization condition
Definition: DynaBgThread.h:492
pthread_mutex_t m_mutexSync
synchonization mutex
Definition: DynaBgThread.h:491
BgThreadState m_eState
thread state
Definition: DynaBgThread.h:490
void lock()
Lock the background thread.
Definition: DynaBgThread.h:533
void DynaBgThread::RegisterChainAgent ( DynaChain pChain)
virtual

Register the Dynamixel chain for control and monitoring.

The chain will replace the currently monitored servo or chain.

If the thread is running, it should be paused or locked prior to calling this function.

The time periods are automatically recalculated.

Parameters
pChainDynamixel chain. May be NULL to deregister.

Definition at line 367 of file DynaBgThread.cxx.

References DYNA_ID_NONE, DynaChain::GetNumberInChain(), DynaServo::RegisterAgent(), and DynaVServo::setToleranceInTicks().

Referenced by DynaShellCmdCreate::Exec(), DynaShellCmdScan::Exec(), and MainInitArgs().

368 {
369  int nServoId;
370  DynaServo *pServo;
371  int iter;
372  DynaVServo vServo;
373 
374  UnregisterAgent();
375 
376  if( pChain != NULL )
377  {
378  m_pServo = NULL;
379  m_pChain = pChain;
380  m_uNumServos = pChain->GetNumberInChain();
381 
382  for(nServoId = m_pChain->IterStart(&iter);
383  nServoId != DYNA_ID_NONE;
384  nServoId = m_pChain->IterNext(&iter))
385  {
386  if( (pServo = m_pChain->GetServo(nServoId)) != NULL )
387  {
388  m_mapVServo[nServoId] = vServo;
389  m_mapVServo[nServoId].setToleranceInTicks(pServo, m_fTolerance);
390 
391  pServo->RegisterAgent(&m_agent, this);
392  }
393  }
394  }
395 
396  setHz(m_fHz);
397 
398  m_iterDynamics = m_mapVServo.begin();
399  m_iterHealth = m_mapVServo.begin();
401 
402  LOGDIAG3("Registered chain: t_sched=%lu", m_TSched);
403 }
MapVServo m_mapVServo
virtual servo associative map
Definition: DynaBgThread.h:498
DynaAgent_T m_agent
servo/chain agent
Definition: DynaBgThread.h:503
double m_fHz
thread execution hertz
Definition: DynaBgThread.h:510
MapVServo::iterator m_iterDynamics
dynamics iterator
Definition: DynaBgThread.h:517
double m_fTolerance
position &plusmn; tolerance (degrees)
Definition: DynaBgThread.h:500
virtual uint_t GetNumberInChain() const
Get the number of servos currently in chain.
Definition: DynaChain.h:140
uint_t m_uNumServos
number of servos to monitor
Definition: DynaBgThread.h:499
Dynamixel Servo Abstract Base Class.
Definition: DynaServo.h:78
long m_TSched
scheduler &mu;s period
Definition: DynaBgThread.h:513
virtual void UnregisterAgent()
Unregister any chain or servo from control and monitoring.
int m_nHealthServoId
current health monitoring servo id
Definition: DynaBgThread.h:519
Background Thread Virtual Servo Class.
Definition: DynaBgThread.h:87
virtual int IterStart(int *pIter)
Start iteration over of entire servo chain.
Definition: DynaChain.cxx:1008
DynaServo * m_pServo
registered dynamixel servo
Definition: DynaBgThread.h:496
virtual DynaServo * GetServo(int nServoId)
Definition: DynaChain.h:129
MapVServo::iterator m_iterHealth
health iterator
Definition: DynaBgThread.h:518
#define DYNA_ID_NONE
no servo id
Definition: Dynamixel.h:145
void setHz(double fHz)
Set new control and monitoring execution hertz rate.
virtual void RegisterAgent(DynaAgent_T *pAgent, void *pAgentArg)
Register servo proxy agent.
Definition: DynaServo.h:584
virtual int IterNext(int *pIter)
Next iteration over of entire servo chain.
Definition: DynaChain.cxx:1020
DynaChain * m_pChain
or registered dynamixel chain
Definition: DynaBgThread.h:497
void DynaBgThread::RegisterServoAgent ( DynaServo pServo)
virtual

Register the Dynamixel servo for control and monitoring.

The servo will replace the currently monitored servo or chain.

If the thread is running, it should be paused or locked prior to calling this function.

The time periods are automatically recalculated.

Parameters
pServoDynamixel servo. May be NULL to deregister.

Definition at line 336 of file DynaBgThread.cxx.

References DynaServo::GetServoId(), DynaServo::RegisterAgent(), and DynaVServo::setToleranceInTicks().

337 {
338  int nServoId;
339  DynaVServo vServo;
340 
341  UnregisterAgent();
342 
343  if( pServo != NULL )
344  {
345  m_pServo = pServo;
346  m_pChain = NULL;
347  m_uNumServos = 1;
348 
349  nServoId = pServo->GetServoId();
350 
351  m_mapVServo[nServoId] = vServo;
352 
353  m_mapVServo[nServoId].setToleranceInTicks(pServo, m_fTolerance);
354 
355  pServo->RegisterAgent(&m_agent, this);
356  }
357 
358  setHz(m_fHz);
359 
360  m_iterDynamics = m_mapVServo.begin();
361  m_iterHealth = m_mapVServo.begin();
363 
364  LOGDIAG3("Registered servo: t_sched=%lu", m_TSched);
365 }
MapVServo m_mapVServo
virtual servo associative map
Definition: DynaBgThread.h:498
DynaAgent_T m_agent
servo/chain agent
Definition: DynaBgThread.h:503
double m_fHz
thread execution hertz
Definition: DynaBgThread.h:510
MapVServo::iterator m_iterDynamics
dynamics iterator
Definition: DynaBgThread.h:517
double m_fTolerance
position &plusmn; tolerance (degrees)
Definition: DynaBgThread.h:500
uint_t m_uNumServos
number of servos to monitor
Definition: DynaBgThread.h:499
long m_TSched
scheduler &mu;s period
Definition: DynaBgThread.h:513
virtual void UnregisterAgent()
Unregister any chain or servo from control and monitoring.
int m_nHealthServoId
current health monitoring servo id
Definition: DynaBgThread.h:519
Background Thread Virtual Servo Class.
Definition: DynaBgThread.h:87
DynaServo * m_pServo
registered dynamixel servo
Definition: DynaBgThread.h:496
virtual uint_t GetServoId() const
Get servo id.
Definition: DynaServo.h:155
MapVServo::iterator m_iterHealth
health iterator
Definition: DynaBgThread.h:518
void setHz(double fHz)
Set new control and monitoring execution hertz rate.
virtual void RegisterAgent(DynaAgent_T *pAgent, void *pAgentArg)
Register servo proxy agent.
Definition: DynaServo.h:584
DynaChain * m_pChain
or registered dynamixel chain
Definition: DynaBgThread.h:497
virtual void DynaBgThread::RegisterUserCallback ( void(*)(void *)  fnUserCb,
void *  pUserArg 
)
inlinevirtual

Register user-defined callback function.

Parameters
fnUserCbUser callback function.
pUserArgUser callback argument.

Definition at line 320 of file DynaBgThread.h.

321  {
322  m_fnUserCb = fnUserCb;
323  m_pUserArg = pUserArg;
324  }
void(* m_fnUserCb)(void *)
user callback function
Definition: DynaBgThread.h:506
void * m_pUserArg
user callback argument
Definition: DynaBgThread.h:507
int DynaBgThread::Resume ( )
virtual

Resume control and monitoring tasks.

Valid Current States:
BgThreadStatePaused
New State:
BgThreadStateRunning
Context:
Calling thread.

Definition at line 517 of file DynaBgThread.cxx.

References DYNA_ECODE_GEN, DYNA_LOG_ERROR, DYNA_OK, and DynaVServo::m_eState.

518 {
519  int rc; // return code
520 
521  switch( m_eState )
522  {
523  case BgThreadStatePaused:
524  gettimeofday(&m_tvSched, NULL);
526  LOGDIAG3("Background thread resumed.");
527  rc = DYNA_OK;
528  break;
529  case BgThreadStateZombie:
530  rc = -DYNA_ECODE_GEN;
531  DYNA_LOG_ERROR(rc, "No background thread.");
532  break;
533  case BgThreadStateReady:
535  case BgThreadStateExit:
536  default:
537  rc = -DYNA_ECODE_GEN;
538  DYNA_LOG_ERROR(rc, "Background thread in invalid state %d.", m_eState);
539  break;
540  }
541 
542  return rc;
543 }
#define DYNA_OK
not an error, success
Definition: Dynamixel.h:78
zombie instance - no thread exists
Definition: DynaBgThread.h:253
thread created and ready to run
Definition: DynaBgThread.h:254
struct timeval m_tvSched
working scheduler time stamp
Definition: DynaBgThread.h:512
void changeState(DynaBgThread::BgThreadState eNewState)
Change the background thread state.
#define DYNA_LOG_ERROR(ecode, efmt,...)
Log Error.
#define DYNA_ECODE_GEN
general, unspecified error
Definition: Dynamixel.h:80
BgThreadState m_eState
thread state
Definition: DynaBgThread.h:490
int DynaBgThread::Run ( )
virtual

Run the background thread control and monitoring tasks.

Valid Current States:
BgThreadStateReady
New State:
BgThreadStateRunning
Context:
Calling thread.

Definition at line 435 of file DynaBgThread.cxx.

References DYNA_ECODE_GEN, DYNA_LOG_ERROR, DYNA_OK, and DynaVServo::m_eState.

Referenced by DynaShellCmdScan::Exec(), and DynaShellCmdBgtStart::Exec().

436 {
437  int rc; // return code
438 
439  switch( m_eState )
440  {
441  case BgThreadStateReady:
442  gettimeofday(&m_tvSched, NULL);
444  LOGDIAG3("Background thread running.");
445  rc = DYNA_OK;
446  break;
447  case BgThreadStateZombie:
448  rc = -DYNA_ECODE_GEN;
449  DYNA_LOG_ERROR(rc, "No background thread.");
450  break;
452  case BgThreadStatePaused:
453  case BgThreadStateExit:
454  default:
455  rc = -DYNA_ECODE_GEN;
456  DYNA_LOG_ERROR(rc, "Background thread in invalid state %d.", m_eState);
457  break;
458  }
459 
460  return rc;
461 }
#define DYNA_OK
not an error, success
Definition: Dynamixel.h:78
zombie instance - no thread exists
Definition: DynaBgThread.h:253
thread created and ready to run
Definition: DynaBgThread.h:254
struct timeval m_tvSched
working scheduler time stamp
Definition: DynaBgThread.h:512
void changeState(DynaBgThread::BgThreadState eNewState)
Change the background thread state.
#define DYNA_LOG_ERROR(ecode, efmt,...)
Log Error.
#define DYNA_ECODE_GEN
general, unspecified error
Definition: Dynamixel.h:80
BgThreadState m_eState
thread state
Definition: DynaBgThread.h:490
void DynaBgThread::sched ( long  lPeriod)
protectedvirtual

Schedule the Dynamixel background thread for the next task(s) to perform.

Context:
Background thread.

Definition at line 826 of file DynaBgThread.cxx.

References dt_usec().

Referenced by bgThread().

827 {
828  static bool bLogWarnings = false; // true to help tune
829 
830  struct timeval tvNow; // now
831  long dt; // delta time (microseconds)
832  long dtRemaining; // remaining delta time to next scheduled event
833 
834  // now
835  gettimeofday(&tvNow, NULL);
836 
837  // delta time between calls to this scheduler
838  dt = dt_usec(tvNow, m_tvSched);
839 
840  // time remaining till next background thread event
841  dtRemaining = lPeriod - dt;
842 
843  // wait
844  if( dtRemaining > 0 )
845  {
846  timeWait(dtRemaining);
847  gettimeofday(&tvNow, NULL);
848  m_dTSched = dt_usec(tvNow, m_tvSched);
849  }
850 
851  // slipped task period - don't wait
852  else
853  {
854  // only log if really bad
855  dtRemaining = fabs(dtRemaining);
856  if( bLogWarnings && (dtRemaining >= lPeriod) )
857  {
858  LOGWARN("BGThread: Scheduled task slipped by %.2fmsec for servo %d",
859  dtRemaining/1000.0, m_iterDynamics->first);
860  }
861  m_dTSched = dt;
862  }
863 
864  // save now
865  m_tvSched = tvNow;
866 }
MapVServo::iterator m_iterDynamics
dynamics iterator
Definition: DynaBgThread.h:517
struct timeval m_tvSched
working scheduler time stamp
Definition: DynaBgThread.h:512
void timeWait(long lMicroSecs)
Wait until state change or time out.
static long dt_usec(struct timeval t1, struct timeval t0)
Calculate the difference between two time-of-day times.
long m_dTSched
scheduler delta time
Definition: DynaBgThread.h:514
void DynaBgThread::setHz ( double  fHz)

Set new control and monitoring execution hertz rate.

Parameters
fHzNew execution hertz.

Definition at line 738 of file DynaBgThread.cxx.

Referenced by DynaShellCmdBgtStart::Exec().

739 {
740  if( fHz < HZ_EXEC_MIN )
741  {
742  fHz = HZ_EXEC_MIN;
743  }
744 
745  m_fHz = fHz;
746  m_TExec = (long)(1.0/m_fHz * 1000000.0);
747 
748  if( m_mapVServo.size() > 0 )
749  {
750  m_TSched = m_TExec / m_mapVServo.size();
751  }
752  else
753  {
754  m_TSched = 5000000;
755  }
756  if( m_TSched < T_EXEC_MIN )
757  {
759  }
760 
761  LOGDIAG3("BGThread: Hz: %.3lf, Scheduled period: %ldusecs.", m_fHz, m_TSched);
762 }
MapVServo m_mapVServo
virtual servo associative map
Definition: DynaBgThread.h:498
double m_fHz
thread execution hertz
Definition: DynaBgThread.h:510
long m_TSched
scheduler &mu;s period
Definition: DynaBgThread.h:513
static const double HZ_EXEC_MIN
minimum exec hertz
Definition: DynaBgThread.h:243
static const long T_EXEC_MIN
task exec period min (100usec)
Definition: DynaBgThread.h:245
long m_TExec
full execution cycle &mu;s period
Definition: DynaBgThread.h:511
void DynaBgThread::setTolerance ( double  fTolerance)
inlineprotected

Set position tolerance.

The servo is considered at a goal position when it is within ± of the tolerance.

Definition at line 586 of file DynaBgThread.h.

587  {
588  m_fTolerance = fTolerance > 0.0? fTolerance: 0.0;
589  }
double m_fTolerance
position &plusmn; tolerance (degrees)
Definition: DynaBgThread.h:500
int DynaBgThread::Stop ( )
virtual

Stop control and monitoring tasks.

Any servos being actively position controlled will be erased from the position control map.

Valid Current States:
BgThreadStateReady BgThreadStateRunning BgThreadStatePaused
New State:
BgThreadStateReady
Context:
Calling thread.

Definition at line 463 of file DynaBgThread.cxx.

References DYNA_ECODE_GEN, DYNA_LOG_ERROR, DYNA_OK, and DynaVServo::m_eState.

Referenced by DynaShellCmdCreate::Exec(), DynaShellCmdDestroy::Exec(), DynaShellCmdScan::Exec(), DynaShellCmdBgtStop::Exec(), and DynaShell::~DynaShell().

464 {
465  int rc;
466 
467  switch( m_eState )
468  {
469  case BgThreadStateReady:
471  case BgThreadStatePaused:
473  LOGDIAG3("Background thread stopped.");
474  rc = DYNA_OK;
475  break;
476  case BgThreadStateZombie:
477  rc = -DYNA_ECODE_GEN;
478  DYNA_LOG_ERROR(rc, "No background thread.");
479  break;
480  case BgThreadStateExit:
481  default:
482  rc = -DYNA_ECODE_GEN;
483  DYNA_LOG_ERROR(rc, "Background thread in invalid state %d.", m_eState);
484  break;
485  }
486 
487  return rc;
488 }
#define DYNA_OK
not an error, success
Definition: Dynamixel.h:78
zombie instance - no thread exists
Definition: DynaBgThread.h:253
thread created and ready to run
Definition: DynaBgThread.h:254
void changeState(DynaBgThread::BgThreadState eNewState)
Change the background thread state.
#define DYNA_LOG_ERROR(ecode, efmt,...)
Log Error.
#define DYNA_ECODE_GEN
general, unspecified error
Definition: Dynamixel.h:80
BgThreadState m_eState
thread state
Definition: DynaBgThread.h:490
void DynaBgThread::stopMotion ( DynaServo pServo)
protectedvirtual

Stop servo motion.

Parameters
pServoPointer to registered servo.

Definition at line 1101 of file DynaBgThread.cxx.

References DYNA_MODE_CONTINUOUS, DYNA_MODE_SERVO, DYNA_OK, DYNA_SPEED_CONT_STOP, and DynaServo::GetServoMode().

1102 {
1103  int nCurOdPos;
1104 
1105  // stop servo
1106  switch( pServo->GetServoMode() )
1107  {
1108  //
1109  // In continuous mode: Set the goal speed to zero.
1110  //
1111  case DYNA_MODE_CONTINUOUS:
1112  pServo->WriteGoalSpeed(DYNA_SPEED_CONT_STOP);
1113  break;
1114 
1115  //
1116  // In servo mode: Set the goal position to the current position (a 0 speed
1117  // value sets the speed to the default maximum).
1118  //
1119  case DYNA_MODE_SERVO:
1120  default:
1121  if( pServo->ReadCurPos(&nCurOdPos) == DYNA_OK )
1122  {
1123  pServo->WriteGoalPos(nCurOdPos);
1124  }
1125  break;
1126  }
1127 }
virtual uint_t GetServoMode() const
Get the servo operational mode.
Definition: DynaServo.h:165
#define DYNA_OK
not an error, success
Definition: Dynamixel.h:78
#define DYNA_MODE_SERVO
servo mode with limited rotation
Definition: Dynamixel.h:170
#define DYNA_MODE_CONTINUOUS
continuous mode with/without position
Definition: Dynamixel.h:171
#define DYNA_SPEED_CONT_STOP
continuous mode: stop
Definition: Dynamixel.h:261
void DynaBgThread::stopPosCtl ( DynaServo pServo,
DynaVServo pVServo 
)
protectedvirtual

Stop servo position control.

Parameters
pServoPointer to registered servo.
pVServoPointer to associated virtual servo.
Context:
Background thread.

Definition at line 1084 of file DynaBgThread.cxx.

References BG_TRACE, DynaServo::GetOdometer(), DynaServo::GetServoId(), DynaVServo::m_eState, DynaVServo::m_nOdGoalPos, and DynaVServo::StateIdle.

Referenced by WriteGoalPos().

1085 {
1086  int nGoalOdPos;
1087 
1088  // stop servo movement
1089  stopMotion(pServo);
1090 
1091  nGoalOdPos = pVServo->m_nOdGoalPos;
1092  pVServo->m_nOdGoalPos = pServo->GetOdometer();
1093  pVServo->m_eState = DynaVServo::StateIdle;
1094 
1095  BG_TRACE(BG_TRACE_FILTER_POSCTL,
1096  pServo->GetServoId(), "STOP",
1097  "cur_od_pos=%d, goal_od_pos=%d\n",
1098  pVServo->m_nOdGoalPos, nOdGoalPos);
1099 }
#define BG_TRACE(mask, servoid, prefix, fmt,...)
No tracing output.
VServoState m_eState
virtual servo state
Definition: DynaBgThread.h:111
no active position control
Definition: DynaBgThread.h:103
int m_nOdGoalPos
current goal position
Definition: DynaBgThread.h:114
virtual uint_t GetServoId() const
Get servo id.
Definition: DynaServo.h:155
virtual void stopMotion(DynaServo *pServo)
Stop servo motion.
int GetOdometer()
Get the current virtual odometer value.
Definition: DynaServo.h:304
void DynaBgThread::terminateThread ( )
protected

Terminate the background thread.

This function does not return until the thread actually terminates.

Context:
Calling thread.

Definition at line 1254 of file DynaBgThread.cxx.

1255 {
1257  pthread_join(m_thread, NULL);
1258 }
pthread_t m_thread
pthread identifier
Definition: DynaBgThread.h:493
void changeState(DynaBgThread::BgThreadState eNewState)
Change the background thread state.
void DynaBgThread::timeWait ( long  lMicroSecs)
protected

Wait until state change or time out.

Parameters
lMicroSecMaximum wait duration (microseconds).
Context:
Calling thread or background thread.

Definition at line 785 of file DynaBgThread.cxx.

References DynaVServo::lock(), DynaVServo::m_mutexSync, and DynaVServo::unlock().

786 {
787  struct timespec tsTimeout;
788  long int lSecs;
789 
790  if( lMicroSecs <= 0 )
791  {
792  return;
793  }
794 
795  clock_gettime(CLOCK_REALTIME, &tsTimeout);
796 
797  tsTimeout.tv_nsec = lMicroSecs * 1000;
798  if( tsTimeout.tv_nsec > 1000000000 )
799  {
800  tsTimeout.tv_sec += 1000000000;
801  tsTimeout.tv_nsec -= 1000000000;
802  }
803 
804  // wait with timeout
805  lock();
806  pthread_cond_timedwait(&m_condSync, &m_mutexSync, &tsTimeout);
807  unlock();
808 }
void unlock()
Unlock the background thread.
Definition: DynaBgThread.h:547
pthread_cond_t m_condSync
synchonization condition
Definition: DynaBgThread.h:492
pthread_mutex_t m_mutexSync
synchonization mutex
Definition: DynaBgThread.h:491
void lock()
Lock the background thread.
Definition: DynaBgThread.h:533
void DynaBgThread::unlock ( )
inlineprotected

Unlock the background thread.

The background thread will be available to run.

Context:
Any.

Definition at line 547 of file DynaBgThread.h.

548  {
549  pthread_mutex_unlock(&m_mutexSync);
550  }
pthread_mutex_t m_mutexSync
synchonization mutex
Definition: DynaBgThread.h:491
void DynaBgThread::UnregisterAgent ( )
virtual

Unregister any chain or servo from control and monitoring.

If the thread is running, it should be paused or locked prior to calling this function.

The time periods are automatically recalculated.

Parameters
pChainDynamixel chain. May be NULL to deregister.

Definition at line 405 of file DynaBgThread.cxx.

References DYNA_ID_NONE, and DynaServo::UnregisterAgent().

Referenced by DynaShellCmdCreate::Exec(), DynaShellCmdDestroy::Exec(), and DynaShellCmdScan::Exec().

406 {
407  int nServoId;
408  DynaServo *pServo;
409  int iter;
410 
411  if( m_pServo != NULL )
412  {
414  }
415  else if( m_pChain != NULL )
416  {
417  for(nServoId = m_pChain->IterStart(&iter);
418  nServoId != DYNA_ID_NONE;
419  nServoId = m_pChain->IterNext(&iter))
420  {
421  if( (pServo = m_pChain->GetServo(nServoId)) != NULL )
422  {
423  pServo->UnregisterAgent();
424  }
425  }
426  }
427 
428  m_pServo = NULL;
429  m_pChain = NULL;
430  m_uNumServos = 0;
431 
432  m_mapVServo.clear();
433 }
MapVServo m_mapVServo
virtual servo associative map
Definition: DynaBgThread.h:498
virtual void UnregisterAgent()
Unregister servo proxy agent.
Definition: DynaServo.h:594
uint_t m_uNumServos
number of servos to monitor
Definition: DynaBgThread.h:499
Dynamixel Servo Abstract Base Class.
Definition: DynaServo.h:78
virtual int IterStart(int *pIter)
Start iteration over of entire servo chain.
Definition: DynaChain.cxx:1008
DynaServo * m_pServo
registered dynamixel servo
Definition: DynaBgThread.h:496
virtual DynaServo * GetServo(int nServoId)
Definition: DynaChain.h:129
#define DYNA_ID_NONE
no servo id
Definition: Dynamixel.h:145
virtual int IterNext(int *pIter)
Next iteration over of entire servo chain.
Definition: DynaChain.cxx:1020
DynaChain * m_pChain
or registered dynamixel chain
Definition: DynaBgThread.h:497
int DynaBgThread::WriteGoalPos ( int  nServoId,
int  nOdGoalPos,
void *  pUserArg 
)
static

Start controlling servo to rotate it to the given goal position.

When the servo attains the given goal position within tolerance, the servo will be stopped. The servo speed to the goal position is controlled externally.

The servo is expected to be in continuous mode and to support 306 ° position information.

Parameters
nServoIdServo id.
uGoalPosGoal position in odometer virtual raw units.
pUserArgPointer to this class instance.
Returns
On success, DYNA_OK is returned.
On error, the appropriate < 0 negated Dynamixel Error Code is returned.

Definition at line 545 of file DynaBgThread.cxx.

References BG_TRACE, DYNA_ECODE_NO_SERVO, DYNA_MODE_CONTINUOUS, DYNA_MODE_SERVO, DYNA_OK, DYNA_SPEED_CONT_STOP, DynaServo::GetCurSpeed(), DynaServo::GetOdometer(), getRegisteredServo(), DynaServo::GetServoMode(), DynaServo::IsOdometerReversed(), DynaVServo::lock(), DynaVServo::m_eState, m_mapVServo, DynaVServo::m_nGoalSpeed, DynaVServo::m_nOdGoalPos, DynaVServo::m_nTolerance, DynaVServo::m_pidPos, DynaPidPos::SpecifySetPoint(), DynaVServo::StateControl, stopPosCtl(), and DynaVServo::unlock().

546 {
547  DynaBgThread *pThis = (DynaBgThread *)pUserArg;
548  MapVServo::iterator iter;
549  DynaServo *pServo;
550  DynaVServo *pVServo;
551  int nOdCurPos;
552  int nGoalSpeed;
553  int rc;
554 
555  pServo = pThis->getRegisteredServo(nServoId);
556 
557  if( pServo == NULL )
558  {
559  rc = -DYNA_ECODE_NO_SERVO;
560  }
561 
562  iter = pThis->m_mapVServo.find(nServoId);
563 
564  if( iter == pThis->m_mapVServo.end() )
565  {
566  rc = -DYNA_ECODE_NO_SERVO;
567  }
568 
569  else
570  {
571  pVServo = &(iter->second);
572  pVServo->lock();
573  nOdCurPos = pServo->GetOdometer();
575  pVServo->m_nOdGoalPos = nOdGoalPos;
576  nGoalSpeed = pVServo->m_nGoalSpeed;
577 
578  pVServo->m_pidPos.SpecifySetPoint(nOdCurPos,
579  nOdGoalPos,
580  nGoalSpeed,
581  pServo->GetCurSpeed(),
582  pServo->IsOdometerReversed(),
583  true);
584 
585  pVServo->unlock();
586 
587  BG_TRACE(BG_TRACE_FILTER_POSCTL|BG_TRACE_FILTER_TORQCTL, nServoId,
588  "WriteGoalPos",
589  "speedlimit=%d, goalpos=%d, curpos=%d, tol=%d.\n",
590  nGoalSpeed,
591  nOdGoalPos,
592  nOdCurPos,
593  pVServo->m_nTolerance);
594 
595  rc = DYNA_OK;
596  }
597 
598  return rc;
599 }
MapVServo m_mapVServo
virtual servo associative map
Definition: DynaBgThread.h:498
virtual void SpecifySetPoint(int nOdPosStart, int nOdPosGoal, int nSpeedLim, int nCurSpeed, bool bIsReversed, bool bUnwind=false)
Specify position setpoint.
Definition: DynaPidPos.cxx:71
#define DYNA_OK
not an error, success
Definition: Dynamixel.h:78
int m_nGoalSpeed
current goal speed
Definition: DynaBgThread.h:115
virtual int GetCurSpeed() const
Get the current servo speed.
Definition: DynaServo.h:455
#define BG_TRACE(mask, servoid, prefix, fmt,...)
No tracing output.
#define DYNA_ECODE_NO_SERVO
no servo found
Definition: Dynamixel.h:86
Dynamixel Servo Abstract Base Class.
Definition: DynaServo.h:78
void unlock()
Unlock the virtual servo.
Definition: DynaBgThread.h:220
in poistion control
Definition: DynaBgThread.h:105
virtual DynaServo * getRegisteredServo(int nServoId)
Get registered servo.
VServoState m_eState
virtual servo state
Definition: DynaBgThread.h:111
Background Thread Virtual Servo Class.
Definition: DynaBgThread.h:87
bool IsOdometerReversed()
Test if the virtual odometer is reversed.
Definition: DynaServo.h:334
int m_nOdGoalPos
current goal position
Definition: DynaBgThread.h:114
void lock()
Lock the virtual servo.
Definition: DynaBgThread.h:206
DynaPidPos m_pidPos
servo position PID
Definition: DynaBgThread.h:112
int GetOdometer()
Get the current virtual odometer value.
Definition: DynaServo.h:304
int m_nTolerance
position &plusmn; tolerance (ticks)
Definition: DynaBgThread.h:113

The documentation for this class was generated from the following files: