55 #include "rnr/rnrconfig.h" 81 else if( nSpeed == 0 )
108 m_sCmdName =
"moveto";
109 m_sCmdHelpBrief =
"Move servos to goal positions.";
110 m_sCmdHelpArgs =
"<servo_id> <pos> [<servo_id> <pos> ...]\n" 112 m_sCmdHelpDesc =
"Move the specified servos to the goal positions. " 113 "If more than one servo is specifed then a synchronous " 114 "move will be automatically performed. " 115 "If the keyword 'chain' is specified, then all servos in " 116 "the chain are synchronously moved.\n" 117 " <servo_id> Servo id [0-253].\n" 118 " <pos> Odometer goal position.";
145 shell.
Error(rc,
"Servo %d: move to %d failed.",
146 tup[0].m_nServoId, tup[0].m_nVal);
153 for(i=0; i<uCount; ++i)
163 shell.
Error(rc,
"Synchronous move of %u servos failed.", uCount);
186 m_sCmdName =
"moveatspeedto";
187 m_sCmdHelpBrief =
"Move servos at speeds to goal positions.";
188 m_sCmdHelpArgs =
"<servo_id> <speed> <pos> [<servo_id> <speed> " 190 "chain <speed> <pos>";
191 m_sCmdHelpDesc =
"Move the specified servos to the goal positions at the " 193 "If more than one servo is specifed then a synchronous " 194 "move will be automatically performed. " 195 "If the keyword 'chain' is specified, then all servos in " 196 "the chain are synchronously moved.\n" 197 " <servo_id> Servo id [0-253].\n" 198 " <speed> Servo goal speed.\n" 199 " <pos> Odometer goal position.";
224 TRY( ChkArgCnt(shell, argc) );
226 if( (argc % 3) != 0 )
228 shell.
Error(
"Unmatched servo_id,speed,pos triplets.");
232 uNumPairs = (uint_t)(argc / 3);
236 shell.
Error(
"%u: Too many servo_id,speed,pos triplets.", uNumPairs);
240 TRY( ChkComm(shell) );
241 TRY( ChkChainNotEmpty(shell) );
244 if( !strcmp(argv[0],
"chain") )
246 TRY( ChkArgCntEQ(shell, argc, 3) );
247 TRY( ToInt(shell, argv[1], &nSpeed) );
248 TRY( ToInt(shell, argv[2], &nPos) );
259 uNumPairs = (uint_t)cnt;
265 for(iter=0, cnt=0; iter<argc; iter+=3, ++cnt)
267 TRY( ToInt(shell, argv[iter], &nServoId) );
268 TRY( ToInt(shell, argv[iter+1], &nSpeed) );
269 TRY( ToInt(shell, argv[iter+2], &nPos) );
270 TRY( ChkChainHasServo(shell, nServoId) );
271 TRY( ChkChainIsMasterServo(shell, nServoId) );
279 doExec(shell, tup, uNumPairs);
304 shell.
Error(rc,
"Servo %d: move at speed %d to %d failed.",
305 tup[0].m_nServoId, tup[0].m_nSpeed, tup[0].m_nPos);
314 shell.
Error(rc,
"Synchronous move at speed of %u servos failed.",
338 m_sCmdName =
"estop";
339 m_sCmdHelpBrief =
"Emergency stop all servos.";
360 TRY( ChkComm(shell) );
361 TRY( ChkChain(shell) );
371 shell.
Error(rc,
"Emergency stop failed.");
394 m_sCmdHelpBrief =
"Stop servo movement.";
395 m_sCmdHelpArgs =
"<servo_id [<servo_id ...]\nchain";
396 m_sCmdHelpDesc =
"Stop the movement of the specified servos. " 397 "If the keyword 'chain' is specified, then all servos " 398 "in the chain are stopped.\n" 399 " <servo_id> Servo id [0-253].";
431 m_sCmdName =
"freeze";
432 m_sCmdHelpBrief =
"Freeze all servos.";
434 m_sCmdHelpDesc =
"Freeze all servos at the current positions. Torque is " 435 "applied to keep the positions.";
454 TRY( ChkArgCnt(shell, argc) );
455 TRY( ChkComm(shell) );
456 TRY( ChkChainNotEmpty(shell) );
466 shell.
Error(rc,
"Freeze failed.");
488 m_sCmdName =
"release";
489 m_sCmdHelpBrief =
"Release all servos.";
491 m_sCmdHelpDesc =
"Release all servos. No torque is applied.";
510 TRY( ChkArgCnt(shell, argc) );
511 TRY( ChkComm(shell) );
512 TRY( ChkChainNotEmpty(shell) );
522 shell.
Error(rc,
"Release failed.");
544 m_sCmdName =
"odometer";
545 m_sCmdHelpBrief =
"Get servo odometer parameters.";
546 m_sCmdHelpArgs =
"<servo_id> [servo_id...]\nchain";
547 m_sCmdHelpDesc =
"Get the servo odometer zero point, modulo, and reverse " 548 "parameters. If the keyword 'chain' is specified, then " 549 "the odometer settings for all of the servos in the " 551 " <servo_id> Servo id [0-253].";
577 shell.
Response(
"Servo %3d: odometer %5d, zeropt %4d, reverse: %s\n",
579 (bOdReversed?
"true":
"false"));
600 m_sCmdName =
"odometer";
601 m_sCmdHelpBrief =
"Set odometer parameters.";
602 m_sCmdHelpArgs =
"<servo_id> <zeropt> <modulo> <reverse>";
603 m_sCmdHelpDesc =
"Set servo virtual odometer parameters.\n" 604 " <servo_id> Servo id [0-253].\n" 605 " <zeropt> Zero point in encoder units.\n" 606 " <reverse> Odometer is [not] reversed. One of: " 607 "t true 1 f false 0";
629 TRY( ChkArgCnt(shell, argc) );
631 TRY( ChkComm(shell) );
632 TRY( ChkChainNotEmpty(shell) );
634 TRY( ToInt(shell, argv[0], &nServoId) );
635 TRY( ToInt(shell, argv[1], &nOdZeroPt) );
636 TRY( ToBool(shell, argv[2], &bOdReversed) );
637 TRY( ChkChainHasServo(shell, nServoId) );
638 TRY( ChkChainIsMasterServo(shell, nServoId) );
644 shell.
Error(
"Servo %d: Servo not found.\n");
679 m_sCmdHelpBrief =
"Configure servo operational modes.";
680 m_sCmdHelpArgs =
"<servo_id> <mode> [<servo_id> <mode> ...]\n" 682 m_sCmdHelpDesc =
"Configure the operational modes of the specified " 683 "servos. The servo configuration is written to the servo " 684 "EEPROM. If the keyword 'chain' is specified, then all " 685 "servos in the chain are configured.\n" 686 " <servo_id> Servo id [0-253].\n" 687 " <mode> Servo mode. One of: continuous servo.";
714 switch( tup[i].m_nVal )
717 rc = pServo->CfgWriteServoModeContinuous();
730 shell.
Error(rc,
"Servo %d: Failed to set mode to %d.",
746 size_t n = strlen(sArg);
748 if( !strncmp(
"continuous", sArg, n) )
753 else if( !strncmp(
"servo", sArg, n) )
760 shell.
Error(
"Argument value \"%s\": Not a servo mode.", sArg);
783 m_sCmdName =
"torqueenable";
784 m_sCmdHelpBrief =
"Read servo torque enable states.";
785 m_sCmdHelpArgs =
"<servo_id> [servo_id...]\nchain";
786 m_sCmdHelpDesc =
"Read the servo torque enable states for the specified " 787 "servos. If the keyword 'chain' is specified, then the " 788 "torque enable states for all of the servos in the " 790 " <servo_id> Servo id [0-253].";
811 rc = pServo->ReadTorqueEnable(&bTorqueEnable);
815 shell.
Error(rc,
"Servo %d: Read torque enable failed.",
821 (bTorqueEnable?
"enabled":
"disabled"));
842 m_sCmdName =
"torqueenable";
843 m_sCmdHelpBrief =
"Enable/disable servo torques.";
844 m_sCmdHelpArgs =
"<servo_id> <switch> [<servo_id> <switch> ...]\n" 846 m_sCmdHelpDesc =
"Enable or disable servo torques for the specified " 847 "servos. If the keyword 'chain' is specified, then all " 848 "servos in the chain are set.\n";
849 " <servo_id> Servo id [0-253].\n" 850 " <switch>: One of: enable e on true 1" 851 "disable d off false 0";
877 state = tup[i].
m_nVal?
true:
false;
879 rc = pServo->WriteTorqueEnable(state);
884 "Servo %d: Failed to set torque enable state.",
901 if( !strcmp(sArg,
"e") || !strcmp(sArg,
"enable") ||
902 !strcmp(sArg,
"on") || !strcmp(sArg,
"true") ||
908 else if( !strcmp(sArg,
"d") || !strcmp(sArg,
"disable") ||
909 !strcmp(sArg,
"off") || !strcmp(sArg,
"false") ||
917 shell.
Error(
"Argument value \"%s\": Invalid state.", sArg);
940 m_sCmdName =
"goalpos";
941 m_sCmdHelpBrief =
"Read servo goal positions.";
942 m_sCmdHelpArgs =
"<servo_id> [servo_id...]\nchain";
943 m_sCmdHelpDesc =
"Read servo goal positions for all of the specified " 944 "servos. If the keyword 'chain' is specified, then the " 945 "goal positions for all of the servos in the chain are " 947 " <servo_id> Servo id [0-253].";
968 rc = pServo->ReadGoalPos(&nGoalPos);
972 shell.
Error(rc,
"Servo %d: Read goal position failed.",
980 shell.
Response(
"Servo %3d: %d (continuous mode)\n",
1008 m_sCmdName =
"goalspeed";
1009 m_sCmdHelpBrief =
"Read servo goal speeds.";
1010 m_sCmdHelpArgs =
"<servo_id> [servo_id...]\nchain";
1011 m_sCmdHelpDesc =
"Read the goal rotational speeds for the specified " 1012 "servos. Speeds <0 are clockwise rotations, >0 are " 1013 "conterclockwise. Directions are N/A for servos in " 1014 "servo mode. If the keyword 'chain' is specified, then " 1015 "the goal speeds for all of the servos in the chain are " 1017 " <servo_id> Servo id [0-253].";
1039 rc = pServo->ReadGoalSpeed(&nGoalSpeed);
1043 shell.
Error(rc,
"Servo %d: Read goal speed failed.",
1050 shell.
Response(
"Servo %3d: %d %s\n",
1077 m_sCmdName =
"goalspeed";
1078 m_sCmdHelpBrief =
"Write the servo goal speeds.";
1079 m_sCmdHelpArgs =
"<servo_id> <speed> [<servo_id> <speed> ...]\n" 1081 m_sCmdHelpDesc =
"Write the goal speeds for the specified servos. " 1082 "Speeds <0 are clockwise rotations, >0 are " 1083 "conterclockwise. Directions are N/A for servos in " 1084 "servo mode. If more than one servo is specifed then a " 1085 "synchronous write will be automatically performed. " 1086 "If the keyword 'chain' is specified, all servos in the " 1087 "chain are synchronously written.\n" 1088 " <servo_id> Servo id [0-253].\n" 1089 " <speed> Servo goal speed.";
1117 nGoalSpeed = tup[0].
m_nVal;
1119 rc = pServo->WriteGoalSpeed(nGoalSpeed);
1124 "Servo %d: Write goal speed %d failed.",
1130 for(i=0; i<(int)uCount; ++i)
1143 "Synchronous write of goal speeds for %u servos failed.",
1167 m_sCmdName =
"maxtorque";
1168 m_sCmdHelpBrief =
"Read maximum torque limits.";
1169 m_sCmdHelpArgs =
"<which> <servo_id> [<servo_id> ...]\n<which> chain";
1170 m_sCmdHelpDesc =
"Read either the on power-up maximum torque limits " 1171 "or the run-time limits for the specified " 1172 "servos. The power-up limits are read from servo EEPROM " 1173 "configuration. The run-time limits are read from servo " 1175 "If the keyword 'chain' is specified, then the " 1176 "torque limits for all of the servos in the chain are " 1178 " <which> Which maximum torque limits. One of: " 1179 "powerup runtime.\n" 1180 " <servo_id> Servo id [0-253].";
1200 TRY( ChkArgCnt(shell, argc) );
1201 TRY( ChkComm(shell) );
1202 TRY( ChkChainNotEmpty(shell) );
1204 if( !strcmp(argv[0],
"powerup") )
1208 else if( !strcmp(argv[0],
"runtime") )
1214 shell.
Error(
"%s: Unknown <which> value.", argv[0]);
1218 if( !strcmp(argv[1],
"chain") )
1220 TRY( ChkArgCntEQ(shell, argc, 2) );
1226 doExec(shell, nServoId, uAddr);
1232 for(iter=1; iter<argc; ++iter)
1234 TRY( ToInt(shell, argv[iter], &nServoId) );
1235 TRY( ChkChainHasServo(shell, nServoId) );
1237 doExec(shell, nServoId, uAddr);
1261 const char *sContext)
1284 while( m_nTabIter < 2 )
1291 if( !strncmp(
"powerup", sText, uTextLen) )
1297 if( !strncmp(
"runtime", sText, uTextLen) )
1317 m_bTabIncChain =
true;
1321 m_bTabIncChain =
false;
1327 snprintf(buf,
sizeof(buf),
"%d", m_nTabServoId);
1328 buf[
sizeof(buf)-1] = 0;
1332 if( !strncmp(buf, sText, uTextLen) )
1338 if( m_bTabIncChain )
1340 m_bTabIncChain =
false;
1341 if( !strncmp(
"chain", sText, uTextLen) )
1366 uint_t uMaxTorqueLimit;
1373 shell.
Error(rc,
"Servo %d: Read maximum torque limit failed.", nServoId);
1377 shell.
Response(
"Servo %3d: %d\n", nServoId, uMaxTorqueLimit);
1398 m_sCmdName =
"maxtorque";
1399 m_sCmdHelpBrief =
"Write maximum torque limits.";
1400 m_sCmdHelpArgs =
"<which> <servo_id> <limit> [<servo_id> <limit> ...]\n" 1401 "<which> chain <limit>";
1402 m_sCmdHelpDesc =
"Write either the on power-up maximum torque limits " 1403 "or the run-time limits for the specified " 1404 "servos. The power-up limits are written to servo EEPROM " 1405 "configuration. The run-time limits are written to servo " 1407 "If the keyword 'chain' is specified, then the " 1408 "torque limits for all of the servos in the chain are " 1410 " <which> Which maximum torque limits. One of: " 1411 "powerup runtime.\n" 1412 " <servo_id> Servo id [0-253].\n" 1413 " <limit> Servo torque limit.";
1438 TRY( ChkArgCnt(shell, argc) );
1440 if( ((argc-1) % 2) != 0 )
1442 shell.
Error(
"Unmatched servo_id,value pairs.");
1446 if( !strcmp(argv[0],
"powerup") )
1450 else if( !strcmp(argv[0],
"runtime") )
1456 shell.
Error(
"%s: Unknown <which> value.", argv[0]);
1460 uNumPairs = (uint_t)((argc-1) / 2);
1464 shell.
Error(
"%u: Too many servo_id,value pairs.", uNumPairs);
1468 TRY( ChkComm(shell) );
1469 TRY( ChkChainNotEmpty(shell) );
1472 if( !strcmp(argv[1],
"chain") )
1474 TRY( ChkArgCntEQ(shell, argc, 3) );
1475 TRY( ToInt(shell, argv[2], &nVal) );
1485 uNumPairs = (uint_t)cnt;
1491 for(iter=1, cnt=0; iter<argc-1; iter+=2, ++cnt)
1493 TRY( ToInt(shell, argv[iter], &nServoId) );
1494 TRY( ToInt(shell, argv[iter+1], &nVal) );
1495 TRY( ChkChainHasServo(shell, nServoId) );
1502 doExec(shell, uAddr, tup, uNumPairs);
1525 const char *sContext)
1548 while( m_nTabIter < 2 )
1555 if( !strncmp(
"powerup", sText, uTextLen) )
1561 if( !strncmp(
"runtime", sText, uTextLen) )
1571 else if( !(nArgNum & 0x01) )
1587 m_bTabIncChain =
true;
1591 m_bTabIncChain =
false;
1597 snprintf(buf,
sizeof(buf),
"%d", m_nTabServoId);
1598 buf[
sizeof(buf)-1] = 0;
1602 if( !strncmp(buf, sText, uTextLen) )
1608 if( m_bTabIncChain )
1610 m_bTabIncChain =
false;
1611 if( !strncmp(
"chain", sText, uTextLen) )
1648 uVal = (uint_t)tup[i].m_nVal;
1655 "Servo %d: Write maximum torque limit at 0x%02x with %u failed.",
1656 nServoId, uAddr, uVal);
1679 m_sCmdName =
"torqueth";
1680 m_sCmdHelpBrief =
"Get servo soft torque thresholds.";
1681 m_sCmdHelpArgs =
"<servo_id> [servo_id...]\nchain";
1682 m_sCmdHelpDesc =
"Get servo soft torque hysteresis thresholds. When a " 1683 "servo exceeds the over torque limit " 1684 "threshold, it is placed in the over torque limit " 1685 "condition which limits servo actuation. " 1686 "When a servo drops below the clear threshold, the " 1687 "servo torque over limit condition is cleared. " 1688 "If the keyword 'chain' is specified, then " 1689 "the thresholds for all of the servos in the " 1690 "chain are retrieved.\n" 1691 " <servo_id> Servo id [0-253].";
1709 uint_t uOverTorqueTh;
1710 uint_t uClearTorqueTh;
1714 shell.
Response(
"Servo %3d: over_th %5d, " 1716 pServo->
GetServoId(), uOverTorqueTh, uClearTorqueTh);
1737 m_sCmdName =
"torqueth";
1738 m_sCmdHelpBrief =
"Set servo soft torque thresholds.";
1739 m_sCmdHelpArgs =
"<servo_id> <over_th> <clear_th>";
1740 m_sCmdHelpDesc =
"Set servo soft torque hysteresis thresholds.\n" 1741 " <servo_id> Servo id [0-253].\n" 1742 " <over_th> Threshold to set the torque over " 1743 "limit condition.\n" 1744 " <clear_th> Theshold to clear the torque over " 1745 "limit condition. The clear\n" 1746 " threshold must be lower " 1747 "than the over threshold.";
1765 uint_t uOverTorqueTh;
1766 uint_t uClearTorqueTh;
1770 TRY( ChkArgCnt(shell, argc) );
1772 TRY( ChkComm(shell) );
1773 TRY( ChkChainNotEmpty(shell) );
1775 TRY( ToInt(shell, argv[0], &nServoId) );
1776 TRY( ToUInt(shell, argv[1], &uOverTorqueTh) );
1777 TRY( ToUInt(shell, argv[2], &uClearTorqueTh) );
1778 TRY( ChkChainHasServo(shell, nServoId) );
1779 TRY( ChkChainIsMasterServo(shell, nServoId) );
1783 if( pServo == NULL )
1785 shell.
Error(
"Servo %d: Servo not found.\n");
1814 m_sCmdName =
"curpos";
1815 m_sCmdHelpBrief =
"Read current odometer positions.";
1816 m_sCmdHelpArgs =
"<servo_id> [servo_id...]\nchain";
1817 m_sCmdHelpDesc =
"Read the current odometer positions for the " 1818 "specified servos. If the keyword 'chain' is specified, " 1819 "then the current positions for all of the servos in " 1820 "the chain are read.\n" 1821 " <servo_id> Servo id [0-253].";
1842 rc = pServo->ReadCurPos(&nCurPos);
1846 shell.
Error(rc,
"Servo %d: Read current position failed.",
1854 shell.
Response(
"Servo %3d: %d (continuous mode)\n",
1882 m_sCmdName =
"curspeed";
1883 m_sCmdHelpBrief =
"Read the current speeds.";
1884 m_sCmdHelpArgs =
"<servo_id> [servo_id...]\nchain";
1885 m_sCmdHelpDesc =
"Read the current speeds for the specified servos. " 1886 "Speeds <0 are clockwise rotations, >0 are " 1887 "conterclockwise. If the keyword 'chain' is specified, " 1888 "then the current speeds for all of the servos in the " 1890 " <servo_id> Servo id [0-253].";
1911 rc = pServo->ReadCurSpeed(&nCurSpeed);
1915 shell.
Error(rc,
"Servo %d: Read current speed failed.",
1920 shell.
Response(
"Servo %3d: %d %s\n",
1942 m_sCmdName =
"dynamics";
1943 m_sCmdHelpBrief =
"Read the current servo dynamics.";
1944 m_sCmdHelpArgs =
"<servo_id> [servo_id...]\nchain";
1945 m_sCmdHelpDesc =
"Read the current dynamics for the specified servos. " 1946 "Dynamics are position, speed, and torque. " 1947 "If the keyword 'chain' is specified, then the dynamics " 1948 "for all of the servos in the chain are read.\n" 1949 " <servo_id> Servo id [0-253].";
1972 rc = pServo->ReadDynamics(&nCurPos, &nCurSpeed, &nCurLoad);
1976 shell.
Error(rc,
"Servo %d: Failed to read the dynamics.",
1981 shell.
Response(
"Servo %3d: pos %5d, speed %5d, load %5d\n",
1982 pServo->
GetServoId(), nCurPos, nCurSpeed, nCurLoad);
2003 m_sCmdName =
"health";
2004 m_sCmdHelpBrief =
"Read the current servo health.";
2005 m_sCmdHelpArgs =
"<servo_id> [servo_id...]\nchain";
2006 m_sCmdHelpDesc =
"Read the current health of the specified servos. " 2007 "Servo health is the combined state of servo alarms, " 2008 "torque, temperature, and voltage. " 2009 "If the keyword 'chain' is specified, then the health " 2010 "for all of the servos in the chain are read.\n" 2011 " <servo_id> Servo id [0-253].";
2036 rc = pServo->ReadHealth(&uAlarms, &nCurLoad, &uCurVolt, &uCurTemp);
2040 shell.
Error(rc,
"Servo %d: Failed to read the health.",
2047 shell.
Response(
"Servo %3d: load %5d, voltage %3u, temperature %3u, " 2048 "alarms(0x%02x) %s\n",
2049 pServo->
GetServoId(), nCurLoad, uCurVolt, uCurTemp, uAlarms,
2071 m_sCmdName =
"ismoving";
2072 m_sCmdHelpBrief =
"Check if servos are moving.";
2073 m_sCmdHelpArgs =
"<servo_id> [servo_id...]\nchain";
2074 m_sCmdHelpDesc =
"Determine if the specified servos are moving. " 2075 "The determination is made by reading the servos states. " 2076 "If the keyword 'chain' is specified, then all servos " 2077 "in the chain are checked.\n" 2078 " <servo_id> Servo id [0-253].";
2099 rc = pServo->ReadIsMoving(&bIsMoving);
2103 shell.
Error(rc,
"Servo %d: Read motion state failed.",
2109 (bIsMoving?
"moving":
"stopped"));
2130 m_sCmdName =
"alarms";
2131 m_sCmdHelpBrief =
"Clear servo alarms (if possible).";
2132 m_sCmdHelpArgs =
"<servo_id> [servo_id...]\nchain";
2133 m_sCmdHelpDesc =
"Clear all clearable alarms raised by serovs. " 2134 "If the keyword 'chain' is specified, then all servos " 2135 "alarms in the chain are cleared.\n" 2136 " <servo_id> Servo id [0-253].";
2166 rc = pServo->ReloadMaxTorqueLimit();
2169 shell.
Error(rc,
"Servo %3d: Failed to reload maximum torque limit.",
2172 else if( uAlarms == DYNA_ALARM_LOAD )
2175 "Over-load alarm cleared");
2180 "Over-load alarm cleared, but other unclearable alarms are present");
2186 "Alarms present, but not clearable");
2208 m_sCmdName =
"byte";
2209 m_sCmdHelpBrief =
"Read a byte from the servo control table.";
2210 m_sCmdHelpArgs =
"<addr> <servo_id> [servo_id...]\n<addr> chain";
2211 m_sCmdHelpDesc =
"Read an 8-bit byte at the address for the specified " 2212 "servos. If the keyword 'chain' is specified, then" 2213 "the byte value at <addr> is read for all servos in the " 2215 " <addr> Servo memory address.\n" 2216 " <servo_id> Servo id [0-253]." 2218 "Caution: This is a low-level function that bypasses all " 2219 "state consistency checks.";
2240 TRY( ChkArgCnt(shell, argc) );
2241 TRY( ChkComm(shell) );
2242 TRY( ChkChainNotEmpty(shell) );
2244 TRY( ToInt(shell, argv[0], (
int *)&uAddr) );
2246 if( !strcmp(argv[1],
"chain") )
2248 TRY( ChkArgCntEQ(shell, argc, 2) );
2254 doExec(shell, nServoId, uAddr);
2260 for(iter=1; iter<argc; ++iter)
2262 TRY( ToInt(shell, argv[iter], &nServoId) );
2263 TRY( ChkChainHasServo(shell, nServoId) );
2265 doExec(shell, nServoId, uAddr);
2289 const char *sContext)
2319 m_bTabIncChain =
true;
2323 m_bTabIncChain =
false;
2329 snprintf(buf,
sizeof(buf),
"%d", m_nTabServoId);
2330 buf[
sizeof(buf)-1] = 0;
2334 if( !strncmp(buf, sText, uTextLen) )
2340 if( m_bTabIncChain )
2342 m_bTabIncChain =
false;
2343 if( !strncmp(
"chain", sText, uTextLen) )
2374 shell.
Error(rc,
"Servo %d: Failed to read byte at 0x%02x.",
2379 shell.
Response(
"Servo %3d: 0x%02x.\n", nServoId, uVal);
2400 m_sCmdName =
"byte";
2401 m_sCmdHelpBrief =
"Write a byte to the servo control table.";
2402 m_sCmdHelpArgs =
"<addr> <servo_id> <val> [<servo_id> <val> ...]\n" 2403 "<addr> chain <val> ";
2404 m_sCmdHelpDesc =
"Write an 8-bit byte to the address for the specified " 2406 "If the keyword 'chain' is specified, then " 2407 "the byte value is written to <addr> for all servos in " 2409 "If more than 1 servo is specified, a synchronous write " 2411 " <addr> Servo memory address.\n" 2412 " <servo_id> Servo id [0-253].\n" 2413 " <val> New servo value." 2415 "Caution: This is a low-level function that bypasses all " 2416 "state consistency checks.";
2441 TRY( ChkArgCnt(shell, argc) );
2442 TRY( ChkComm(shell) );
2443 TRY( ChkChainNotEmpty(shell) );
2445 TRY( ToInt(shell, argv[0], (
int *)&uAddr) );
2449 if( (cnt % 2) != 0 )
2451 shell.
Error(
"Unmatched servo_id,value pairs.");
2455 uNumPairs = (uint_t)(cnt / 2);
2459 shell.
Error(
"%u: Too many servo_id,value pairs.", uNumPairs);
2463 if( !strcmp(argv[1],
"chain") )
2465 TRY( ChkArgCntEQ(shell, argc, 3) );
2467 TRY( ToInt(shell, argv[2], (
int *)&uVal) );
2480 for(iter=1, cnt=0; iter<argc; iter+=2, ++cnt)
2482 TRY( ToInt(shell, argv[iter], &nServoId) );
2483 TRY( ChkChainHasServo(shell, nServoId) );
2484 TRY( ToInt(shell, argv[iter+1], (
int *)&uVal) );
2491 doExec(shell, uAddr, tup, (uint_t)cnt);
2513 const char *sContext)
2535 else if( (nArgNum & 0x01) == 0 )
2548 m_bTabIncChain =
true;
2552 m_bTabIncChain =
false;
2558 snprintf(buf,
sizeof(buf),
"%d", m_nTabServoId);
2559 buf[
sizeof(buf)-1] = 0;
2563 if( !strncmp(buf, sText, uTextLen) )
2569 if( m_bTabIncChain )
2571 m_bTabIncChain =
false;
2572 if( !strncmp(
"chain", sText, uTextLen) )
2609 "Servo %d: Failed to write byte 0x%02x to 0x%02x.",
2610 tup[0].m_nServoId, tup[0].m_uVal, uAddr);
2621 "Failed to syncwrite to 0x%02x for %u servos.",
2648 m_sCmdName =
"word";
2649 m_sCmdHelpBrief =
"Read a word from the servo control table.";
2650 m_sCmdHelpArgs =
"<addr> <servo_id> [servo_id...]\n<addr> chain";
2651 m_sCmdHelpDesc =
"Read a 16-bit word at the address for the specified " 2653 "If the keyword 'chain' is specified, then" 2654 "the word value at <addr> is read for all servos in the " 2656 " <addr> Servo memory address.\n" 2657 " <servo_id> Servo id [0-253]." 2659 "Caution: This is a low-level function that bypasses all " 2660 "state consistency checks.";
2686 shell.
Error(rc,
"Servo %d: Failed to read byte at 0x%02x.",
2691 shell.
Response(
"Servo %3d: 0x%04x.\n", nServoId, uVal);
2712 m_sCmdName =
"word";
2713 m_sCmdHelpBrief =
"Write a word to the servo control table.";
2714 m_sCmdHelpArgs =
"<addr> <servo_id> <val> [<servo_id> <val> ...]\n" 2715 "<addr> chain <val> ";
2716 m_sCmdHelpDesc =
"Write a 16-bit word to the address for the specified " 2718 "If the keyword 'chain' is specified, then " 2719 "the word <val> is written to <addr> for all servos in " 2721 "If more than 1 servo is specified, a synchronous write " 2723 " <addr> Servo memory address.\n" 2724 " <servo_id> Servo id [0-253].\n" 2725 " <val> New servo value." 2727 "Caution: This is a low-level function that bypasses all " 2728 "state consistency checks.";
2759 "Servo %d: Failed to write word 0x%04x to 0x%02x.",
2760 tup[0].m_nServoId, tup[0].m_uVal, uAddr);
2771 "Failed to syncwrite to 0x%02x for %u servos.",
2797 m_sCmdName =
"tables";
2798 m_sCmdHelpBrief =
"Dump servo EEPROM and RAM control tables.";
2799 m_sCmdHelpArgs =
"<servo_id> [servo_id...]\n" 2801 m_sCmdHelpDesc =
"Dump servo control tables " 2802 "for the specified " 2803 "servos. If the keyword 'chain' is specified, then " 2804 "the memory is dumped for all servos in the " 2806 " <servo_id> Servo id [0-253].";
2828 shell.
Response(
"-------------------------" 2829 " Servo %d Control Tables " 2830 "-------------------------\n",
RoadNarrows Dynamixel Bus Communications Abstract Base Class Interface.
bool m_bTabIncChain
tab completion: [do not] include chain keyword
virtual bool ArgToInt(DynaShell &shell, const char *sArg, int *pVal)
Convert command argument into enable state.
void Exec(DynaShell &shell, int argc, char *argv[])
Execute 'write-like' command on servos.
Read servo byte value at address.
Write servos on power-up or run-time maximum torque limits.
virtual uint_t GetServoMode() const
Get the servo operational mode.
Determine if servos are moving.
int m_nTabIter
tab completion: iterator
Synchronous Write Speed Tuple Structure.
bool m_bTabIncChain
tab completion: [do not] include chain keyword
Synchronous Write Speed-Position Tuple Structure.
virtual int SyncWriteGoalSpeed(DynaSpeedTuple_T tuplesSpeed[], uint_t uCount)
Synchronous write new goal speed for servos.
Dynamixel Servo Specification Structure.
void Exec(DynaShell &shell, int argc, char *argv[])
Execute command on servos.
void Exec(DynaShell &shell, int argc, char *argv[])
Emergence stop all servos.
#define DYNA_OK
not an error, success
virtual void doExec(DynaShell &shell, uint_t uAddr, ExecTup_T tup[], uint_t uCount)
Move servos to goal positions.
Determine if servos are moving.
virtual int SyncMoveTo(DynaPosTuple_T tuplesPos[], uint_t uCount)
Synchronous move servos to new goal positions in tuple list.
virtual int Freeze()
Freeze all servos at current position.
virtual void doExec(DynaShell &shell, DynaServo *pServo)
Determine if servo is moving.
virtual void doExec(DynaShell &shell, int nServoId, uint_t uAddr)
Read byte.
#define DYNA_MODE_SERVO
servo mode with limited rotation
virtual void doExec(DynaShell &shell, DynaSpeedPosTuple_T tup[], uint_t uCount)
Move servos to goal positions.
Dynamixel shell utilities.
virtual int MoveAtSpeedTo(int nServoId, int nGoalSpeed, int nGoalOdPos)
Move at speed to the goal postition.
DynaComm * m_pDynaComm
dynamixel bus communication
virtual void doExec(DynaShell &shell, DynaServo *pServo)
Read goal position for servo.
Read servo byte value at address.
uint_t m_uRawPosMin
minimum raw position value (servo mode)
void Exec(DynaShell &shell, int argc, char *argv[])
Execute 'write-like' command on servos.
#define DYNA_ALARM_LOAD
operating load (torque) out of rnge
#define DYNA_ALARM_NONE
no alarms
virtual void Exec(DynaShell &shell, int argc, char *argv[])
Execute write byte command on servos.
virtual void doExec(DynaShell &shell, ExecTup_T tup[], uint_t uCount)
Move servos to goal positions.
virtual int Read8(int nServoId, uint_t uAddr, byte_t *pVal)=0
Read an 8-bit value from Dynamixel servo control table.
Read servos current positions.
Determine if servos are moving.
RoadNarrows Dynamixel Servo Chain Container Base Class Interface.
virtual int MoveTo(int nServoId, int nGoalOdPos)
Move to the goal postition.
static const int FIRST
first state
virtual void doExec(DynaShell &shell, DynaServo *pServo)
Read dynamics for servo.
void Exec(DynaShell &shell, int argc, char *argv[])
Execute command on servos.
virtual int Read16(int nServoId, uint_t uAddr, ushort_t *pVal)=0
Read a 16-bit value from Dynamixel servo control table.
static char * dupstr(const string &str)
Duplicate string.
virtual void SetSoftTorqueThresholds(uint_t uOverTorqueTh, uint_t uClearTorqueTh)
Set soft torque thresholds.
virtual void doExec(DynaShell &shell, DynaServo *pServo)
Read byte.
Dynamixel shell command abstract base class.
Read servos goal positions.
virtual void doExec(DynaShell &shell, int nServoId, uint_t uAddr)
Read goal position for servo.
virtual int IterStartMaster(int *pIter)
Start iteration master servos over of entire servo chain.
virtual bool ArgToInt(DynaShell &shell, const char *sArg, int *pVal)
Convert command argument into servo mode.
#define DYNA_ID_NUMOF
number of unique servo id's
const char * rotdirstr(int nSpeed)
Convert rotation direction to string.
virtual int IterNextMaster(int *pIter)
Next iteration of master servos over of entire servo chain.
virtual uint_t GetNumberInChain() const
Get the number of servos currently in chain.
virtual char * TabCompletion(DynaShell &shell, const char *sText, size_t uTextLen, int nState, const char *sContext)
Command tab completion generator.
Dynamixel Servo Abstract Base Class.
Read servos goal positions.
Execute 2-tuple structure type.
bool m_bTabIncChain
tab completion: [do not] include chain keyword
virtual void doExec(DynaShell &shell, ExecTup_T tup[], uint_t uCount)
Enable/disable servos torques.
int m_nTabIter
tab completion: iterator
virtual int Write8(int nServoId, uint_t uAddr, byte_t byVal)=0
Write an 8-bit value to Dynamixel servo control table.
Read servos current positions.
Determine if servos are moving.
Determine if servos are moving.
virtual char * TabCompletion(DynaShell &shell, const char *sText, size_t uTextLen, int nState, const char *sContext)
Command tab completion generator.
static int wc(const string &str)
Count the words in the string.
Read servos goal positions.
void Response(const char *sFmt,...)
Print formatted success response.
virtual int Write16(int nServoId, uint_t uAddr, ushort_t uhVal)=0
Write a 16-bit value to Dynamixel servo control table.
virtual void doExec(DynaShell &shell, DynaServo *pServo)
Read goal position for servo.
virtual void doExec(DynaShell &shell, DynaServo *pServo)
Derived class specific execution function.
int m_nTabIter
tab completion: servo id iterator
virtual void doExec(DynaShell &shell, DynaServo *pServo)
Determine torque enable state for servo.
virtual void Ok()
Print standard ok success response.
virtual void Exec(DynaShell &shell, int argc, char *argv[])
Execute command on servos.
void PublishShellServoCommands(DynaShell &shell)
Publish shell servo commands to shell.
int m_nTabServoId
tab completion: current servo id
virtual int Release()
Release all servos from any applied torque.
virtual void doExec(DynaShell &shell, DynaServo *pServo)
Determine if servo is moving.
#define DYNA_ADDR_LIM_TORQUE_MAX_LSB
current torque limit lsb (RW)
virtual void doExec(DynaShell &shell, uint_t uAddr, DynaSyncWriteTuple_T tup[], uint_t uCount)
Write byte.
virtual char * TabCompletion(DynaShell &shell, const char *sText, size_t uTextLen, int nState, const char *sContext)
Command tab completion generator.
Read servos goal positions.
int m_nTabServoId
tab completion: current servo id
Determine if servos are moving.
#define DYNA_ADDR_LIM_TORQUE_MAX_ON_LSB
maximum torque lsb (RW)
virtual int IterStart(int *pIter)
Start iteration over of entire servo chain.
virtual DynaServo * GetServo(int nServoId)
virtual void doExec(DynaShell &shell, DynaServo *pServo)
Read current position for servo.
#define DYNA_MODE_CONTINUOUS
continuous mode with/without position
int GetOdometerZeroPt()
Get the virtual odometer zero point.
Read servos goal positions.
Determine if servos are moving.
virtual void doExec(DynaShell &shell, uint_t uAddr, DynaSyncWriteTuple_T tup[], uint_t uCount)
Write word.
static std::string GetAlarmsString(const uint_t uAlarms, const std::string &strSep="; ")
Get a formatted servo alarms string associated with the alarms.
bool IsOdometerReversed()
Test if the virtual odometer is reversed.
virtual void doExec(DynaShell &shell, ExecTup_T tup[], uint_t uCount)
Execute operation.
virtual void doExec(DynaShell &shell, int nServoId, uint_t uAddr)
Read word.
virtual const DynaServoSpec_T & GetSpecification() const
Get servo specification.
DynaShellCmdCfgWriteServoMode()
Default constructor.
Dynamixel chain input command abstract base class.
virtual uint_t GetAlarms() const
Get the current servo alarms.
virtual int SyncWrite(uint_t uAddr, uint_t uValSize, DynaSyncWriteTuple_T tuples[], uint_t uCount)=0
Synchronous Write 8/16-bit values to a list of Dynamixel servos.
#define TRY(boolexpr,...)
Try boolean expression.
Write byte value to servo at address.
virtual void Exec(DynaShell &shell, int argc, char *argv[])
Execute read byte command on servos.
virtual void doExec(DynaShell &shell, DynaServo *pServo)
Read current position for servo.
void PublishCommand(const char *sParent, DynaShellCmd *pNewCmd)
Publish new command to shell.
RoadNarrows Dynamixel Top-Level Package Header File.
Read servo byte value at address.
The dynashell Command Class Interface.
virtual uint_t GetServoId() const
Get servo id.
Dynamixel chain output command abstract base class.
uint_t m_uRawPosMax
maximum raw position value (servo mode)
virtual void doExec(DynaShell &shell, DynaServo *pServo)
Determine torque enable state for servo.
virtual ~DynaShellCmdCfgWriteServoMode()
Default destructor.
#define DYNA_ID_NONE
no servo id
Read servos goal positions.
int m_nTabServoId
tab completion: current servo id
virtual int EStop()
Emergency stop all servos.
virtual char * TabCompletion(DynaShell &shell, const char *sText, size_t uTextLen, int nState, const char *sContext)
Command tab completion generator.
void Exec(DynaShell &shell, int argc, char *argv[])
Freeze servos.
Write EEPROM configuration to put servos into the given modes.
virtual int IterNext(int *pIter)
Next iteration over of entire servo chain.
virtual int ResetOdometer(int nEncZeroPt, bool bIsReverse)
Reset the servo's virtual odometer.
DynaChain * m_pDynaChain
dynamixel chain
void Error(int rc, const char *sFmt,...)
Raise error on dynamixel error code.
int m_nTabIter
tab completion: servo id iterator
Write byte value to servo at address.
Position Tuple Structure.
virtual void doExec(DynaShell &shell, ExecTup_T tup[], uint_t uCount)
Write goal speeds.
virtual void doExec(DynaShell &shell, DynaServo *pServo)
Determine torque enable state for servo.
void Exec(DynaShell &shell, int argc, char *argv[])
Release servos.
Read servos goal positions.
virtual int SyncMoveAtSpeedTo(DynaSpeedPosTuple_T tuplesSpeedPos[], uint_t uCount)
Synchronous move servos to new goal positions at the given speeds.
The simple dynashell declarations.
virtual void doExec(DynaShell &shell, DynaServo *pServo)
Read dynamics for servo.
int GetOdometer()
Get the current virtual odometer value.
int m_nTabServoId
tab completion: current servo id
virtual void GetSoftTorqueThresholds(uint_t &uOverTorqueTh, uint_t &uClearTorqueTh)
Get soft torque thresholds.
bool m_bTabIncChain
tab completion: [do not] include chain keyword
Determine if servos are moving.
Read servos on power-up or run-time maximum torque limits.