Dynamixel  2.9.5
RoadNarrows Robotics Dynamixel Package
DynaShellCmdPlay Class Reference

Record dynamixel chain movements. More...

Inheritance diagram for DynaShellCmdPlay:
DynaShellCmd

Public Member Functions

 DynaShellCmdPlay ()
 Default constructor.
 
virtual ~DynaShellCmdPlay ()
 Default destructor.
 
virtual void Exec (DynaShell &shell, int argc, char *argv[])
 Execute playback of recording. More...
 
virtual char * TabCompletion (DynaShell &shell, const char *sText, size_t uTextLen, int nState, const char *sContext)
 Command tab completion generator. More...
 
- Public Member Functions inherited from DynaShellCmd
 DynaShellCmd (int nArgCntMin=0, int nArgCntMax=0)
 Default constructor.
 
virtual ~DynaShellCmd ()
 Default destructor.
 
const char * GetCmdName ()
 Get dynamixel shell command name. More...
 
const char * GetCmdHelpBrief ()
 Get shell command name brief description. More...
 
virtual void PrintHelp (int indent=0, int width=80)
 Print command help with the description aligned at the given indentation. More...
 
int GetPublishedLevel () const
 
const char * GetPublishedName () const
 
int SetPublishedInfo (int nLevel, const char *sParent=NULL)
 
virtual bool ChkArgCnt (DynaShell &shell, int argc)
 Check that the argument count is within the class (min,max). More...
 
bool ChkArgCnt0 (DynaShell &shell, int argc)
 Check that the argument count is zero. More...
 
bool ChkArgCntEQ (DynaShell &shell, int argc, int eq)
 Check that the argument count is equal to the required. More...
 
bool ChkArgCntGE (DynaShell &shell, int argc, int min)
 Check argument count against minimum required. More...
 
bool ChkArgCntLE (DynaShell &shell, int argc, int max)
 Check argument count against maximum allowed. More...
 
bool ChkComm (DynaShell &shell)
 Check that Dynamixel communication exists and is open. More...
 
bool ChkChain (DynaShell &shell)
 Check that the servo chain exists. More...
 
bool ChkChainNotEmpty (DynaShell &shell)
 Check that the servo chain exists and is not empty. More...
 
bool ChkChainHasServo (DynaShell &shell, int nServoId)
 Check that the given servo is present in the chain. More...
 
bool ChkChainIsMasterServo (DynaShell &shell, int nServoId)
 Check that the given servo is a master. More...
 
bool ToInt (DynaShell &shell, const char *sArg, int *pVal)
 Convert command argument to integer. More...
 
bool ToUInt (DynaShell &shell, const char *sArg, uint_t *pVal)
 Convert command argument to unsigned integer. More...
 
bool ToDouble (DynaShell &shell, const char *sArg, double *pVal)
 Convert command argument to double. More...
 
bool ToBool (DynaShell &shell, const char *sArg, bool *pVal)
 Convert command argument to boolean. More...
 

Protected Types

typedef vector< vector< uint_t > > VecCurves
 

Protected Member Functions

void Play (DynaShell &shell)
 Play back the previously recorded Dynamixel chain motion sequence. More...
 
int SetRecordGoals (DynaShell &shell, int nRecNum)
 Set record goals. More...
 
int ControlToGoals (DynaShell &shell, int nRecNum, double dt)
 Control the servos speed to reach the goal positions, hopefully at the end of the sampled period and with the sampled speed. More...
 
void Init (DynaShell &shell)
 
void SmoothRecordingCurves (DynaShell &shell)
 
void BSplineCurve (DynaShell &shell, int nFldNum)
 
void PidInit (DynaShell &shell)
 Initialize servo PIDs. More...
 
int PidSetPoint (DynaShell &shell, int nServoId, int nGoalPos, int nGoalSpeed)
 Specify (new) PID goal position setpoint. More...
 
void Cleanup (DynaShell &shell)
 Clean up any allocated playback resources. More...
 
bool MoveToStart (DynaShell &shell)
 
void SecureArm (DynaShell &shell)
 Secure arm in safe postition if posible. More...
 
void PlotInit (DynaShell &shell)
 Initialize plot data output. More...
 
void PlotWriteData (DynaShell &shell, int nRecNum, double dt, int nServoId, int nCurPos)
 Write plot data to plot file. More...
 
void WaitStop (DynaShell &shell)
 Wait until all servos in chain have stopped moving utility function. More...
 
- Protected Member Functions inherited from DynaShellCmd
virtual void PrintSynopses (int indent, int width)
 Print synsopses. More...
 
virtual void PrintBlock (int col, int indent, int width, const char *sText)
 Print a block of indented text of width. More...
 
virtual void PrintDelim (int width, const char cDelim)
 
char * eow (const char *s)
 Find end of word. More...
 

Protected Attributes

int m_nNumSubSamplePts
 sub-sample playback control period (msec)
 
double m_fSpeedPct
 playback speed as a % of recorded speed
 
double m_fSamplePeriod
 playback sample period (seconds)
 
double m_fSubSamplePeriod
 control sub-sample period (seconds)
 
double m_dt
 playback delta time (seconds)
 
VecCurves m_vecCurves
 vector of fitted smooth curves
 
double m_fTAccum
 accumulated time
 
FILE * m_fpPlot
 plot data file pointer
 
int m_nPlotLineCnt
 plotted data line count
 
int m_nTabIndex
 tab completion: keyword index
 
- Protected Attributes inherited from DynaShellCmd
const char * m_sCmdName
 command name
 
const char * m_sCmdHelpBrief
 command help brief
 
const char * m_sCmdHelpArgs
 command help arguments
 
const char * m_sCmdHelpDesc
 command help description
 
const int m_nArgCntMin
 minimum argument count
 
const int m_nArgCntMax
 maximum argument count (0 if not max)
 
int m_nPubLevel
 command's published level (depth)
 
char * m_sPubName
 command's published name
 

Detailed Description

Record dynamixel chain movements.

Definition at line 1496 of file dynashell_cmd_train.cxx.

Member Function Documentation

void DynaShellCmdPlay::Cleanup ( DynaShell shell)
inlineprotected

Clean up any allocated playback resources.

Parameters
shellDynamixel shell.

Definition at line 2123 of file dynashell_cmd_train.cxx.

2124  {
2125  if( m_fpPlot != NULL )
2126  {
2127  fclose(m_fpPlot);
2128  m_fpPlot = NULL;
2129  }
2130 
2131  m_vecCurves.clear();
2132  }
VecCurves m_vecCurves
vector of fitted smooth curves
FILE * m_fpPlot
plot data file pointer
int DynaShellCmdPlay::ControlToGoals ( DynaShell shell,
int  nRecNum,
double  dt 
)
inlineprotected

Control the servos speed to reach the goal positions, hopefully at the end of the sampled period and with the sampled speed.

Parameters
shellDynamixel shell.
nRecNumRecord number in the recording.
dtDelta time (seconds).
Returns
On success, DYNA_OK is returned.
On error, the appropriate < 0 negated Dynamixel Error Code is returned.

Definition at line 1861 of file dynashell_cmd_train.cxx.

References DYNA_ID_NUMOF, DYNA_OK, DynaStrError(), DynaRecording::END, DynaRecording::FirstField(), DynaRecording::GetNumOfRecords(), DynaRecording::GetSamplePeriod(), DynaChain::GetServo(), DynaRecording::GetServoId(), DynaSpeedTuple_T::m_nServoId, DynaSpeedTuple_T::m_nSpeed, DynaShell::m_pDynaChain, DynaShell::m_pRecording, DynaRecording::NextField(), and DynaChain::SyncWriteGoalSpeed().

1862  {
1863  int nFldNum;
1864  int nServoId;
1865  DynaServo *pServo;
1866  int nCurPos;
1867  int nCurSpeed;
1868  int nGoalSpeed;
1869  DynaSpeedTuple_T tupSpeed[DYNA_ID_NUMOF];
1870  uint_t uCount;
1871  int rc;
1872 
1873  printf(" speed_%d: ", nRecNum);
1874 
1875  //
1876  // Determine new speed goals and set.
1877  //
1878  for(nFldNum = shell.m_pRecording->FirstField(nRecNum), uCount=0;
1879  nFldNum != DynaRecording::END;
1880  nFldNum = shell.m_pRecording->NextField(nRecNum, nFldNum), ++uCount)
1881  {
1882  nServoId = shell.m_pRecording->GetServoId(nFldNum);
1883 
1884  pServo = shell.m_pDynaChain->GetServo(nServoId);
1885 
1886  // read current servo position
1887  rc = pServo->ReadCurPos(&nCurPos);
1888 
1889  if( rc != DYNA_OK )
1890  {
1891  printf("Error: Servo %d: ReadCurPos: %s\n", nServoId, DynaStrError(rc));
1892  return rc;
1893  }
1894 
1895  // read current speed
1896  rc = pServo->ReadCurSpeed(&nCurSpeed);
1897 
1898  if( rc != DYNA_OK )
1899  {
1900  printf("Error: Servo %d: ReadCurSpeed: %s\n", nServoId,
1901  DynaStrError(rc));
1902  return rc;
1903  }
1904 
1905  // pid control
1906  nGoalSpeed = pServo->GetSpeedPid().Control(nCurSpeed, dt);
1907 
1908  tupSpeed[nFldNum].m_nServoId = nServoId;
1909  tupSpeed[nFldNum].m_nSpeed = nGoalSpeed;
1910 
1911  if( m_fpPlot != NULL )
1912  {
1913  PlotWriteData(shell, nRecNum, dt, nServoId, nCurPos);
1914  }
1915 
1916  printf("%d %d ", nServoId, nGoalSpeed);
1917  }
1918 
1919  printf("\n");
1920 
1921  //
1922  // Synchronously write new goal speeds.
1923  //
1924  rc = shell.m_pDynaChain->SyncWriteGoalSpeed(tupSpeed, uCount);
1925 
1926  if( rc != DYNA_OK )
1927  {
1928  printf("Error: Servo %d: SyncWriteGoalSpeed: %s\n",
1929  nServoId, DynaStrError(rc));
1930  return rc;
1931  }
1932 
1933  return DYNA_OK;
1934  }
Synchronous Write Speed Tuple Structure.
Definition: DynaTypes.h:314
virtual int SyncWriteGoalSpeed(DynaSpeedTuple_T tuplesSpeed[], uint_t uCount)
Synchronous write new goal speed for servos.
Definition: DynaChain.cxx:940
#define DYNA_OK
not an error, success
Definition: Dynamixel.h:78
virtual const int GetServoId(int nFldNum)
Get the servo id associated with the given field number.
#define DYNA_ID_NUMOF
number of unique servo id&#39;s
Definition: Dynamixel.h:148
DynaRecording * m_pRecording
dynamixel recording
Definition: dynashell.h:362
Dynamixel Servo Abstract Base Class.
Definition: DynaServo.h:78
const char * DynaStrError(int ecode)
Get the error string describing the Dynamixel error code.
Definition: DynaError.cxx:141
static const int END
past-the-end mark
virtual DynaServo * GetServo(int nServoId)
Definition: DynaChain.h:129
void PlotWriteData(DynaShell &shell, int nRecNum, double dt, int nServoId, int nCurPos)
Write plot data to plot file.
int m_nSpeed
speed
Definition: DynaTypes.h:317
int m_nServoId
servo id
Definition: DynaTypes.h:316
virtual int NextField(int nRecNum, int nFldNum)
Get the next field number in the record after the given field number.
virtual int FirstField(int nRecNum)
Get the first field number in the given record.
DynaChain * m_pDynaChain
dynamixel chain
Definition: dynashell.h:360
FILE * m_fpPlot
plot data file pointer
virtual void DynaShellCmdPlay::Exec ( DynaShell shell,
int  argc,
char *  argv[] 
)
inlinevirtual

Execute playback of recording.

Parameters
shellDynamixel shell.
argcCommand argument count.
argvArray of arguments.

Implements DynaShellCmd.

Definition at line 1537 of file dynashell_cmd_train.cxx.

References DYNA_ID_NONE, DynaShell::Error(), DynaServo::GetModelNumber(), DynaChain::GetNumberOfMastersInChain(), DynaRecording::GetNumOfRecords(), DynaRecording::GetNumOfServosInRecording(), DynaChain::GetServo(), DynaRecording::GetServoModelNumber(), DynaRecording::HasServo(), DynaChain::IterNextMaster(), DynaChain::IterStartMaster(), DynaShell::m_pDynaChain, DynaShell::m_pRecording, and TRY.

1538  {
1539  DynaRecording *pRecording = shell.m_pRecording;
1540  int i;
1541  char *sPlotFileName;
1542  int iter;
1543  int nServoId;
1544  DynaServo *pServo;
1545 
1546  //
1547  // Check and parse command-line arguments.
1548  //
1549  TRY( ChkArgCnt(shell, argc) );
1550 
1551  // Is there a recording?
1552  if( (pRecording == NULL) || (pRecording->GetNumOfRecords() == 0) )
1553  {
1554  shell.Error("No recording to play.");
1555  return;
1556  }
1557 
1558  // defaults
1559  m_fSpeedPct = 100.0;
1560  sPlotFileName = NULL;
1561  m_fpPlot = NULL;
1562 
1563  // RDK loop option
1564  //
1565  // Parse arguments
1566  //
1567  for(i=0; i<argc; ++i)
1568  {
1569  switch( i )
1570  {
1571  // sub-sample points
1572  case 0:
1573  TRY( ToInt(shell, argv[i], &m_nNumSubSamplePts) );
1574  // sub-sample period too big - adjust
1575  if( m_nNumSubSamplePts < 1 )
1576  {
1577  m_nNumSubSamplePts = 1;
1578  }
1579  break;
1580  // playback speed (optional)
1581  case 1:
1582  TRY( ToDouble(shell, argv[i], &m_fSpeedPct) );
1583  if( m_fSpeedPct < 0.0 )
1584  {
1585  m_fSpeedPct = 100.0;
1586  }
1587  break;
1588  case 2:
1589  // create gnuplot file (optional)
1590  sPlotFileName = argv[i];
1591  break;
1592  default:
1593  shell.Error("Huh?");
1594  break;
1595  }
1596  }
1597 
1598  //
1599  // Validate recording against chain.
1600  //
1601 
1602  // Does the recording have the same number of servos?
1603  if( pRecording->GetNumOfServosInRecording() !=
1605  {
1606  shell.Error("%d servos in recording != %d master servos in chain.",
1607  pRecording->GetNumOfServosInRecording(),
1609  return;
1610  }
1611 
1612  // Do the servos match in id and model number?
1613  for(nServoId = shell.m_pDynaChain->IterStartMaster(&iter);
1614  nServoId != DYNA_ID_NONE;
1615  nServoId = shell.m_pDynaChain->IterNextMaster(&iter))
1616  {
1617  if( !pRecording->HasServo(nServoId) )
1618  {
1619  shell.Error("Servo %d: Not in recording.");
1620  return;
1621  }
1622 
1623  pServo = shell.m_pDynaChain->GetServo(nServoId);
1624 
1625  if(pRecording->GetServoModelNumber(nServoId) != pServo->GetModelNumber())
1626  {
1627  shell.Error("Servo %d: Recording model number 0x%04x != 0x%04x.",
1628  pRecording->GetServoModelNumber(nServoId),
1629  pServo->GetModelNumber());
1630  return;
1631  }
1632  }
1633 
1634  //
1635  // Open gnuplot file
1636  //
1637  if( sPlotFileName != NULL )
1638  {
1639  if( (m_fpPlot = fopen(sPlotFileName, "w")) == NULL )
1640  {
1641  shell.Error("%s: cannot open.", sPlotFileName);
1642  return;
1643  }
1644  }
1645 
1646  // initialiize
1647  Init(shell);
1648 
1649  // play back the recording
1650  Play(shell);
1651 
1652  // clean up any resources
1653  Cleanup(shell);
1654  }
virtual int GetNumOfRecords()
Get the number of records in the recording.
virtual uint_t GetNumberOfMastersInChain()
Get the number of servos currently in chain.
Definition: DynaChain.cxx:182
double m_fSpeedPct
playback speed as a % of recorded speed
virtual int IterStartMaster(int *pIter)
Start iteration master servos over of entire servo chain.
Definition: DynaChain.cxx:1036
virtual int IterNextMaster(int *pIter)
Next iteration of master servos over of entire servo chain.
Definition: DynaChain.cxx:1058
DynaRecording * m_pRecording
dynamixel recording
Definition: dynashell.h:362
Dynamixel Servo Abstract Base Class.
Definition: DynaServo.h:78
virtual uint_t GetServoModelNumber(int nServoId)
Get the registered servo model number.
bool ToInt(DynaShell &shell, const char *sArg, int *pVal)
Convert command argument to integer.
void Cleanup(DynaShell &shell)
Clean up any allocated playback resources.
bool ToDouble(DynaShell &shell, const char *sArg, double *pVal)
Convert command argument to double.
virtual DynaServo * GetServo(int nServoId)
Definition: DynaChain.h:129
virtual bool ChkArgCnt(DynaShell &shell, int argc)
Check that the argument count is within the class (min,max).
virtual int GetNumOfServosInRecording()
Get the number of servos in the recording.
#define TRY(boolexpr,...)
Try boolean expression.
Definition: dynashell_cmd.h:89
virtual uint_t GetModelNumber() const
Get servo model number.
Definition: DynaServo.h:125
virtual bool HasServo(int nServoId)
Check if the given servo is in the list of registered servos in the recording header.
#define DYNA_ID_NONE
no servo id
Definition: Dynamixel.h:145
DynaChain * m_pDynaChain
dynamixel chain
Definition: dynashell.h:360
void Error(int rc, const char *sFmt,...)
Raise error on dynamixel error code.
Definition: dynashell.cxx:808
FILE * m_fpPlot
plot data file pointer
void Play(DynaShell &shell)
Play back the previously recorded Dynamixel chain motion sequence.
int m_nNumSubSamplePts
sub-sample playback control period (msec)
void DynaShellCmdPlay::PidInit ( DynaShell shell)
inlineprotected

Initialize servo PIDs.

Parameters
shellDynamixel shell.

Definition at line 2064 of file dynashell_cmd_train.cxx.

References DYNA_ID_NONE, DynaChain::GetServo(), DynaChain::IterNextMaster(), DynaChain::IterStartMaster(), and DynaShell::m_pDynaChain.

2065  {
2066  int iter;
2067  int nServoId;
2068  DynaServo *pServo;
2069 
2070  for(nServoId = shell.m_pDynaChain->IterStartMaster(&iter);
2071  nServoId != DYNA_ID_NONE;
2072  nServoId = shell.m_pDynaChain->IterNextMaster(&iter))
2073  {
2074  pServo = shell.m_pDynaChain->GetServo(nServoId);
2075  pServo->GetSpeedPid().InitControl();
2076  }
2077  }
virtual int IterStartMaster(int *pIter)
Start iteration master servos over of entire servo chain.
Definition: DynaChain.cxx:1036
virtual int IterNextMaster(int *pIter)
Next iteration of master servos over of entire servo chain.
Definition: DynaChain.cxx:1058
Dynamixel Servo Abstract Base Class.
Definition: DynaServo.h:78
virtual DynaServo * GetServo(int nServoId)
Definition: DynaChain.h:129
#define DYNA_ID_NONE
no servo id
Definition: Dynamixel.h:145
DynaChain * m_pDynaChain
dynamixel chain
Definition: dynashell.h:360
int DynaShellCmdPlay::PidSetPoint ( DynaShell shell,
int  nServoId,
int  nGoalPos,
int  nGoalSpeed 
)
inlineprotected

Specify (new) PID goal position setpoint.

Parameters
shellDynamixel shell.
nServoIdServo Id.
uGoalPosGoal odometer position.
nGoalSpeedGoal speed. Direction is important since a position may be obtained in two rotation directions.
Returns
On success, DYNA_OK is returned.
On error, the appropriate < 0 negated Dynamixel Error Code is returned.

Definition at line 2090 of file dynashell_cmd_train.cxx.

References DYNA_DIR_CCW, DYNA_DIR_CW, DYNA_OK, DynaStrError(), DynaChain::GetServo(), and DynaShell::m_pDynaChain.

2094  {
2095  int nDir = nGoalSpeed < 0? DYNA_DIR_CW: DYNA_DIR_CCW;
2096  DynaServo *pServo;
2097  int nCurPos;
2098  int nOdPos;
2099  int rc;
2100 
2101  pServo = shell.m_pDynaChain->GetServo(nServoId);
2102 
2103  // read current servo position
2104  rc = pServo->ReadCurPos(&nCurPos);
2105 
2106  if( rc != DYNA_OK )
2107  {
2108  printf("Error: Servo %d: ReadCurPos: %s\n", nServoId, DynaStrError(rc));
2109  return rc;
2110  }
2111 
2112  // set new setpoint
2113  pServo->GetSpeedPid().SpecifySetPoint(nOdPos);
2114 
2115  return DYNA_OK;
2116  }
#define DYNA_OK
not an error, success
Definition: Dynamixel.h:78
#define DYNA_DIR_CW
clockwise direction
Definition: Dynamixel.h:191
Dynamixel Servo Abstract Base Class.
Definition: DynaServo.h:78
const char * DynaStrError(int ecode)
Get the error string describing the Dynamixel error code.
Definition: DynaError.cxx:141
#define DYNA_DIR_CCW
counterclockwise direction
Definition: Dynamixel.h:193
virtual DynaServo * GetServo(int nServoId)
Definition: DynaChain.h:129
DynaChain * m_pDynaChain
dynamixel chain
Definition: dynashell.h:360
void DynaShellCmdPlay::Play ( DynaShell shell)
inlineprotected

Play back the previously recorded Dynamixel chain motion sequence.

Parameters
shellDynamixel shell.

Definition at line 1727 of file dynashell_cmd_train.cxx.

References DYNA_OK, DynaRecording::END, DynaRecording::FirstRecord(), DynaRecording::GetDate(), DynaRecording::GetNumOfRecords(), DynaShell::m_pRecording, DynaRecording::NextRecord(), DynaShell::Response(), and waitkey().

1728  {
1729  DynaRecording *pRecording = shell.m_pRecording;
1730  double dt;
1731  double t;
1732  int nRecNum;
1733  int rc;
1734 
1735  shell.Response("\nPlaying back recording made on %s.\n",
1736  pRecording->GetDate());
1737  shell.Response(" Number of records: %d\n",
1738  pRecording->GetNumOfRecords());
1739  shell.Response(" Playback sample period: %.1lfms.\n", m_fSamplePeriod);
1740  shell.Response(" Sub-sample period: %.3lfms.\n", dt);
1741  shell.Response("Press <CR> to abort recording.\n\n");
1742  fflush(stdout);
1743 
1744  m_fTAccum = 0.0;
1745 
1746  // move to the starting position
1747  MoveToStart(shell);
1748 
1749  //
1750  // Play back the recording.
1751  //
1752  for(nRecNum = pRecording->FirstRecord();
1753  nRecNum != DynaRecording::END;
1754  nRecNum = pRecording->NextRecord(nRecNum))
1755  {
1756  // set record goals
1757  rc = SetRecordGoals(shell, nRecNum);
1758 
1759  if( rc != DYNA_OK )
1760  {
1761  return;
1762  }
1763 
1764  //
1765  // Now control the speed profiles at the sub-sampled rate.
1766  //
1767  for(t=0.0; t<m_fSamplePeriod; t+=dt)
1768  {
1769  // control servos to goals
1770  rc = ControlToGoals(shell, nRecNum, dt);
1771 
1772  if( rc != DYNA_OK )
1773  {
1774  return;
1775  }
1776 
1777  // wait for next time interval or user keypress to abort
1778  if( waitkey(dt) )
1779  {
1780  // RDK could be that user aborted because of badness SecureArm(shell);
1781  return;
1782  }
1783 
1784  m_fTAccum += dt;
1785  }
1786  }
1787  }
virtual int GetNumOfRecords()
Get the number of records in the recording.
static bool_t waitkey(int nMSec)
Block, waiting for either timeout or user keyboard press.
double m_fTAccum
accumulated time
#define DYNA_OK
not an error, success
Definition: Dynamixel.h:78
Definition: t.py:1
DynaRecording * m_pRecording
dynamixel recording
Definition: dynashell.h:362
static const int END
past-the-end mark
void Response(const char *sFmt,...)
Print formatted success response.
Definition: dynashell.cxx:763
virtual const char * GetDate() const
Get the recording data.
virtual int FirstRecord()
Get the first record number in the recording.
double m_fSamplePeriod
playback sample period (seconds)
virtual int NextRecord(int nRecNum)
Get the next record number in the recording after the given record number.
int ControlToGoals(DynaShell &shell, int nRecNum, double dt)
Control the servos speed to reach the goal positions, hopefully at the end of the sampled period and ...
int SetRecordGoals(DynaShell &shell, int nRecNum)
Set record goals.
void DynaShellCmdPlay::PlotInit ( DynaShell shell)
inlineprotected

Initialize plot data output.

Parameters
shellDynamixel shell.

Definition at line 2154 of file dynashell_cmd_train.cxx.

References DynaRecording::GetDate(), DynaRecording::GetNumOfRecords(), DynaRecording::GetSamplePeriod(), and DynaShell::m_pRecording.

2155  {
2156  if( m_fpPlot != NULL )
2157  {
2158  m_nPlotLineCnt = 0;
2159 
2160  fprintf(m_fpPlot, "#\n");
2161  fprintf(m_fpPlot, "# Dynamixel Play Back Plot Data\n");
2162  fprintf(m_fpPlot, "# Recorded: %s\n",
2163  shell.m_pRecording->GetDate());
2164  fprintf(m_fpPlot, "# Number of records: %d\n",
2165  shell.m_pRecording->GetNumOfRecords());
2166  fprintf(m_fpPlot, "# Recording sample period: %dms\n",
2167  shell.m_pRecording->GetSamplePeriod());
2168  fprintf(m_fpPlot, "# Playback sample period: %.3f\n",
2169  m_fSamplePeriod);
2170  fprintf(m_fpPlot, "# Playback delta time step: %.4lfs\n", m_dt);
2171  fprintf(m_fpPlot, "#\n");
2172  fprintf(m_fpPlot, "#Fields:\n");
2173  fprintf(m_fpPlot, "# time servo goal_pos goal_speed cur_pos "
2174  "cur_speed\n");
2175  fprintf(m_fpPlot, "#\n");
2176  }
2177  }
virtual int GetNumOfRecords()
Get the number of records in the recording.
double m_dt
playback delta time (seconds)
DynaRecording * m_pRecording
dynamixel recording
Definition: dynashell.h:362
virtual int GetSamplePeriod() const
Get the sample period of the recording.
virtual const char * GetDate() const
Get the recording data.
double m_fSamplePeriod
playback sample period (seconds)
int m_nPlotLineCnt
plotted data line count
FILE * m_fpPlot
plot data file pointer
void DynaShellCmdPlay::PlotWriteData ( DynaShell shell,
int  nRecNum,
double  dt,
int  nServoId,
int  nCurPos 
)
inlineprotected

Write plot data to plot file.

Parameters
shellDynamixel shell.
nRecNumRecord number.
dtPlayback delta time step (seconds).
nServoidServo Id.
nCurPosServo current position.

Definition at line 2188 of file dynashell_cmd_train.cxx.

References DynaChain::GetServo(), and DynaShell::m_pDynaChain.

2193  {
2194  DynaServo *pServo;
2195 
2196  if( m_fpPlot != NULL )
2197  {
2198  pServo = shell.m_pDynaChain->GetServo(nServoId);
2199  fprintf(m_fpPlot, "%.4f %d %u %d %u\n",
2200  m_fTAccum,
2201  nServoId,
2202  (uint_t)pServo->GetSpeedPid().GetSP(),
2203  nCurPos,
2204  (uint_t)pServo->GetSpeedPid().GetOutput());
2205  }
2206  }
double m_fTAccum
accumulated time
Dynamixel Servo Abstract Base Class.
Definition: DynaServo.h:78
virtual DynaServo * GetServo(int nServoId)
Definition: DynaChain.h:129
DynaChain * m_pDynaChain
dynamixel chain
Definition: dynashell.h:360
FILE * m_fpPlot
plot data file pointer
void DynaShellCmdPlay::SecureArm ( DynaShell shell)
inlineprotected

Secure arm in safe postition if posible.

Parameters
pDynaChainPointer to Dynamixel chain handle.

Definition at line 2144 of file dynashell_cmd_train.cxx.

References DynaChain::Freeze(), and DynaShell::m_pDynaChain.

2145  {
2146  shell.m_pDynaChain->Freeze();
2147  }
virtual int Freeze()
Freeze all servos at current position.
Definition: DynaChain.cxx:751
DynaChain * m_pDynaChain
dynamixel chain
Definition: dynashell.h:360
int DynaShellCmdPlay::SetRecordGoals ( DynaShell shell,
int  nRecNum 
)
inlineprotected

Set record goals.

  • Set new PID setpoints
  • Initiate synchronous move of all servos to the recorded end position.
Parameters
shellDynamixel shell.
nRecNumRecord number in the recording.
Returns
On success, DYNA_OK is returned.
On error, the appropriate < 0 negated Dynamixel Error Code is returned.

Definition at line 1800 of file dynashell_cmd_train.cxx.

References DYNA_ID_NUMOF, DYNA_OK, DynaStrError(), DynaRecording::END, DynaRecording::FirstField(), DynaRecording::GetField(), DynaRecording::GetServoId(), DynaRecord::FieldTuple_T::m_nPos, DynaPosTuple_T::m_nPos, DynaPosTuple_T::m_nServoId, DynaRecord::FieldTuple_T::m_nSpeed, DynaShell::m_pDynaChain, DynaShell::m_pRecording, DynaRecording::NextField(), and DynaChain::SyncMoveTo().

1801  {
1802  DynaRecord::FieldTuple_T tupRec;
1803  int nFldNum;
1804  int nServoId;
1805  DynaPosTuple_T tupPos[DYNA_ID_NUMOF];
1806  uint_t uCount;
1807  int rc;
1808 
1809  printf("\n goalpos_%d: ", nRecNum);
1810 
1811  //
1812  // Build synchronous write tuple while setting new pid setpoints.
1813  //
1814  for(nFldNum = shell.m_pRecording->FirstField(nRecNum), uCount=0;
1815  nFldNum != DynaRecording::END;
1816  nFldNum = shell.m_pRecording->NextField(nRecNum, nFldNum), ++uCount)
1817  {
1818  nServoId = shell.m_pRecording->GetServoId(nFldNum);
1819 
1820  tupRec = shell.m_pRecording->GetField(nRecNum, nFldNum);
1821 
1822  tupPos[nFldNum].m_nServoId = nServoId;
1823  tupPos[nFldNum].m_nPos = tupRec.m_nPos;
1824 
1825  rc = PidSetPoint(shell, nServoId, tupRec.m_nPos, tupRec.m_nSpeed);
1826 
1827  if( rc < 0 )
1828  {
1829  return rc;
1830  }
1831 
1832  printf("%d %d ", nServoId, tupRec.m_nPos);
1833  }
1834 
1835  printf("\n");
1836 
1837  //
1838  // Move synchronously to new position.
1839  //
1840  rc = shell.m_pDynaChain->SyncMoveTo(tupPos, uCount);
1841 
1842  if( rc < 0 )
1843  {
1844  printf("Error: SyncMoveTo: %s\n", DynaStrError(rc));
1845  return rc;
1846  }
1847 
1848  return DYNA_OK;
1849  }
#define DYNA_OK
not an error, success
Definition: Dynamixel.h:78
virtual int SyncMoveTo(DynaPosTuple_T tuplesPos[], uint_t uCount)
Synchronous move servos to new goal positions in tuple list.
Definition: DynaChain.cxx:513
Record Field Tuple Structure Type.
int PidSetPoint(DynaShell &shell, int nServoId, int nGoalPos, int nGoalSpeed)
Specify (new) PID goal position setpoint.
virtual const int GetServoId(int nFldNum)
Get the servo id associated with the given field number.
#define DYNA_ID_NUMOF
number of unique servo id&#39;s
Definition: Dynamixel.h:148
DynaRecording * m_pRecording
dynamixel recording
Definition: dynashell.h:362
const char * DynaStrError(int ecode)
Get the error string describing the Dynamixel error code.
Definition: DynaError.cxx:141
static const int END
past-the-end mark
int m_nServoId
servo id
Definition: DynaTypes.h:306
virtual int NextField(int nRecNum, int nFldNum)
Get the next field number in the record after the given field number.
int m_nPos
position
Definition: DynaTypes.h:307
virtual const DynaRecord::FieldTuple_T & GetField(const int nRecNum, const int nFldNum) const
Get the given recorded field tuple.
virtual int FirstField(int nRecNum)
Get the first field number in the given record.
DynaChain * m_pDynaChain
dynamixel chain
Definition: dynashell.h:360
Position Tuple Structure.
Definition: DynaTypes.h:304
virtual char* DynaShellCmdPlay::TabCompletion ( DynaShell shell,
const char *  sText,
size_t  uTextLen,
int  nState,
const char *  sContext 
)
inlinevirtual

Command tab completion generator.

Completes NULL 100 <plot_file>

Parameters
shellDynamixel shell.
sTextPartial text string to complete.
uTextLenLength of text.
nStateGenerator state. If FIRST, then initialize any statics.
sContextGenerator context (i.e. canonical command path).
Returns
If a first/next match is made, return allocated completed match.
Otherwise return NULL.

Reimplemented from DynaShellCmd.

Definition at line 1671 of file dynashell_cmd_train.cxx.

References ReadLine::dupstr(), ReadLine::FileCompletionGenerator(), ReadLine::FIRST, and ReadLine::wc().

1676  {
1677  int nArgNum;
1678 
1679  // argument number of already (expanded) arguments
1680  nArgNum = ReadLine::wc(sContext) - ReadLine::wc(m_sPubName);
1681 
1682  //
1683  // New command argument to complete - initialize.
1684  //
1685  if( nState == ReadLine::FIRST )
1686  {
1687  m_nTabIndex = 0;
1688  }
1689 
1690  // only match default playback <speed>
1691  if( nArgNum == 1 )
1692  {
1693  if( (m_nTabIndex++ == 0) && !strncmp("100", sText, uTextLen) )
1694  {
1695  return ReadLine::dupstr("100");
1696  }
1697  }
1698 
1699  // <plot_file>
1700  else if( nArgNum == 2 )
1701  {
1702  return ReadLine::FileCompletionGenerator(sText, nState);
1703  }
1704 
1705  return NULL;
1706  }
static const int FIRST
first state
static char * dupstr(const string &str)
Duplicate string.
char * m_sPubName
command&#39;s published name
static int wc(const string &str)
Count the words in the string.
int m_nTabIndex
tab completion: keyword index
static char * FileCompletionGenerator(const char *sText, int nState)
File name tab completion generator.
void DynaShellCmdPlay::WaitStop ( DynaShell shell)
inlineprotected

Wait until all servos in chain have stopped moving utility function.

Note
Currently this member function is not used. But could be promoted to a usefull shell command.
Parameters
shellDynamixel shell.

Definition at line 2216 of file dynashell_cmd_train.cxx.

References DYNA_ID_NONE, DYNA_OK, DynaChain::GetNumberInChain(), DynaChain::GetServo(), DynaChain::IterNext(), DynaChain::IterStart(), and DynaShell::m_pDynaChain.

2217  {
2218  int nNumServos;
2219  int nMoving;
2220  int iter;
2221  int nServoId;
2222  DynaServo *pServo;
2223  bool bIsMoving;
2224  int rc;
2225 
2226  nNumServos = (int)shell.m_pDynaChain->GetNumberInChain();
2227  nMoving = nNumServos;
2228 
2229  while( nMoving > 0 )
2230  {
2231  //printf(".");
2232 
2233  for(nServoId = shell.m_pDynaChain->IterStart(&iter);
2234  nServoId != DYNA_ID_NONE;
2235  nServoId = shell.m_pDynaChain->IterNext(&iter))
2236  {
2237  pServo = shell.m_pDynaChain->GetServo(nServoId);
2238 
2239  if( ((rc = pServo->ReadIsMoving(&bIsMoving)) == DYNA_OK) && bIsMoving )
2240  {
2241  ++nMoving;
2242  }
2243  }
2244  }
2245 
2246  //printf("\n");
2247  }
#define DYNA_OK
not an error, success
Definition: Dynamixel.h:78
virtual uint_t GetNumberInChain() const
Get the number of servos currently in chain.
Definition: DynaChain.h:140
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
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_pDynaChain
dynamixel chain
Definition: dynashell.h:360

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