implement settle timer on creep positioning

detect position overrun error and stop runaway motor
implement deferred fault reporting until after motor stopped
save and report timer period in debug output (DMC_SetTimer)
handle leading '-' on numeric galil response
more comment documentation
remove unused variables

r2423 | dcl | 2008-04-14 09:38:41 +1000 (Mon, 14 Apr 2008) | 8 lines
This commit is contained in:
Douglas Clowes
2008-04-14 09:38:41 +10:00
parent 149d825a3a
commit a0c6945bb6

View File

@@ -57,7 +57,10 @@ typedef struct EvtEvent_s EvtEvent, *pEvtEvent;
typedef void (*StateFunc)(pDMC2280Driv self, pEvtEvent event);
typedef struct EvtState_s { } EvtState;
typedef struct EvtTimer_s { } EvtTimer;
typedef struct EvtTimer_s {
int timerValue;
} EvtTimer;
typedef struct EvtMessage_s {
pAsyncTxn cmd;
@@ -172,23 +175,20 @@ struct __MoDriv {
double fPreseek; /**< preseek target when preseek is active */
int settle; /**< motor settling time in seconds */
struct timeval time_settle_done; /**< time when settling will be over */
int airpad_state; /**< state of the airpads finite state machine */
int airpad_counter; /**< airpad timer retry counter */
pNWTimer airpad_timer; /**< timer waiting for airpad action to complete */
pNWTimer motoff_timer; /**< motor off timer */
int debug;
int stepCount; /**< number of step operations for this move cycle */
float creep_offset; /**< last little bit to creep in units */
float creep_precision;
float creep_precision; /**< how far away we can stop creeping */
int creep_val;
int preseek; /**< Flag = 1 if current move is a backlash preseek */
int has_fsm; /**< Flag = 1 if motor has finite state machine driver model */
int run_flag; /**< Flag = 1 if RUN command has been issued and deferred */
/**< Flag = -1 if HALT command has been issued and deferred */
int driver_status;
StateFunc myState;
StateFunc myPrevState;
int subState;
bool faultPending; /**< set when waiting for a failing motor to stop */
int timerValue; /**< save for debug printing */
StateFunc myState; /**< pointer to state action method */
StateFunc myPrevState; /**< save for debug printing */
int subState; /**< tracks substate within state method */
bool waitResponse; /**< true is a message sent and we wait for response */
pNWTimer state_timer; /**< motor state timer */
SConnection *trace;
@@ -868,8 +868,9 @@ static int SendCallback(pAsyncTxn pCmd) {
}
else {
switch (resp[0]) {
case ':':
case ' ':
case ':': /* prompt */
case ' ': /* leading blank */
case '-': /* leading minus sign */
if (self->debug) {
SICSLogWrite(cmnd, eStatus);
SICSLogWrite(resp, eStatus);
@@ -973,6 +974,11 @@ static int DMC_SendReceive(pDMC2280Driv self, char *cmd, char* reply) {
return OKOK;
}
static void DMC_SetTimer(pDMC2280Driv self, int msecs) {
self->timerValue = msecs;
NetWatchRegisterTimer(&self->state_timer, msecs, state_tmr_callback, self);
}
/** \brief Record the given posn and timestamp it.
*
* \param *pData provides access to a motor's data
@@ -1084,6 +1090,51 @@ static int RunHomeRoutine(pDMC2280Driv self, float newValue) {
return SUCCESS;
}
/** \brief Check if the axis is still within all the limits
*
* The position is checked against upper and lower limits
*
* \param *pData provides access to a motor's data
* \return
* - 1 MOTOR OK, position is within the specified limits
* - 0 MOTOR BAD, position is not within hard and soft limits
*/
static int checkPosition(pDMC2280Driv self) {
int iRet = 1;
float fTarget;
float fPrecision;
bool moving_forward = false;
float fLower = self->fLower;
float fUpper = self->fUpper;
MotorGetPar(self->pMot, "softlowerlim", &fLower);
MotorGetPar(self->pMot, "softupperlim", &fUpper);
MotorGetPar(self->pMot, "precision", &fPrecision);
if (self->preseek)
fTarget = self->fPreseek;
else
fTarget = self->fTarget;
if (fTarget > self->lastPosition)
moving_forward = true;
else
moving_forward = false;
if (moving_forward) {
if ((self->currPosition > self->fUpper + fPrecision)
|| (self->currPosition > fUpper + fPrecision)
|| (self->currPosition > fTarget + fPrecision))
iRet = 0;
}
else {
if ((self->currPosition < self->fLower - fPrecision)
|| (self->currPosition < fLower - fPrecision)
|| (self->currPosition < fTarget - fPrecision))
iRet = 0;
}
return iRet;
}
/** \brief Check if the axis has moved significantly since
* the last check.
*
@@ -1095,13 +1146,12 @@ static int RunHomeRoutine(pDMC2280Driv self, float newValue) {
* - 1 MOTOR OK, position has changed significantly during move
* - 0 MOTOR BLOCKED, no significant change in position detected.
*/
static int checkMotion(void *pData) {
static int checkMotion(pDMC2280Driv self) {
int iRet = 1;
double ratio_obs, ratio_exp, ratio_cmp;
long int usec_TimeDiff;
struct timeval now;
pDMC2280Driv self;
self = (pDMC2280Driv)pData;
assert(self != NULL);
/* we can only test if there is an absolute encoder */
if (!self->abs_encoder)
@@ -1150,9 +1200,9 @@ static int checkMotion(void *pData) {
self->stepsPerX, self->cntsPerX);
SICSLogWrite(msg, eError);
if (self->blockage_fail)
return 0;
iRet = 0;
else
set_lastMotion(self, self->currSteps, self->currCounts);
return 1;
} else {
if (self->debug) {
char msg[132];
@@ -1164,9 +1214,8 @@ static int checkMotion(void *pData) {
SICSLogWrite(msg, eError);
}
set_lastMotion(self, self->currSteps, self->currCounts);
return 1;
}
return 1;
return iRet;
}
/**
@@ -1254,6 +1303,7 @@ static int cmdOn(pDMC2280Driv self) {
static int cmdPosition(pDMC2280Driv self, int target) {
char cmd[CMDLEN];
self->lastPosition = motPosit(self);
if (self->protocol == 3)
snprintf(cmd, CMDLEN, "DST%c=%d", self->axisLabel, target);
else
@@ -1285,6 +1335,7 @@ static void cmdHalt(pDMC2280Driv self) {
(void) DMC_Send(self, cmd);
if (self->variables & VAR_HLT) {
snprintf(cmd, CMDLEN, "HLT%c=1", self->axisLabel);
/* Note that this does not expect a reply or confirmation */
(void) DMC_Send(self, cmd);
}
}
@@ -1454,7 +1505,7 @@ static char* event_name(pEvtEvent event, char* text, int length) {
snprintf(text, length, "eStateEvent");
return text;
case eTimerEvent:
snprintf(text, length, "eTimerEvent");
snprintf(text, length, "eTimerEvent (%d mSec)", event->event.tmr.timerValue);
return text;
case eMessageEvent:
snprintf(text, length, "eMessageEvent:");
@@ -1620,6 +1671,7 @@ static int state_tmr_callback(void* ctx, int mode) {
EvtEvent event;
self->state_timer = 0;
event.event_type = eTimerEvent;
event.event.tmr.timerValue = self->timerValue;
handle_event(self, &event);
return 0;
}
@@ -1670,9 +1722,7 @@ static void DMCState_Unknown(pDMC2280Driv self, pEvtEvent event) {
change_state(self, DMCState_Idle);
return;
}
NetWatchRegisterTimer(&self->state_timer,
MOTOR_POLL_SLOW,
state_tmr_callback, self);
DMC_SetTimer(self, MOTOR_POLL_SLOW);
return;
case eMessageEvent:
do {
@@ -1689,9 +1739,7 @@ static void DMCState_Unknown(pDMC2280Driv self, pEvtEvent event) {
if (iRet == 0)
break;
set_lastMotion(self, self->currSteps, self->currCounts);
NetWatchRegisterTimer(&self->state_timer,
0,
state_tmr_callback, self);
DMC_SetTimer(self, 0);
self->subState = 0;
return;
}
@@ -1733,9 +1781,7 @@ static void DMCState_Idle(pDMC2280Driv self, pEvtEvent event) {
snprintf(cmd, CMDLEN, "RUN%c=0", self->axisLabel);
(void) DMC_Send(self, cmd);
}
NetWatchRegisterTimer(&self->state_timer,
0,
state_tmr_callback, self);
DMC_SetTimer(self, 0);
self->subState = 0;
return;
case eTimerEvent:
@@ -1766,9 +1812,7 @@ static void DMCState_Idle(pDMC2280Driv self, pEvtEvent event) {
set_lastMotion(self, self->currSteps, self->currCounts);
report_motion(self);
}
NetWatchRegisterTimer(&self->state_timer,
MOTOR_POLL_SLOW,
state_tmr_callback, self);
DMC_SetTimer(self, MOTOR_POLL_SLOW);
self->subState = 0;
return;
}
@@ -1797,9 +1841,7 @@ static void DMCState_Idle(pDMC2280Driv self, pEvtEvent event) {
strncpy(self->lastCmd, event->event.msg.cmd->out_buf, CMDLEN);
self->errorCode = MOTCMDTMO;
self->driver_status = HWFault;
NetWatchRegisterTimer(&self->state_timer,
MOTOR_POLL_SLOW,
state_tmr_callback, self);
DMC_SetTimer(self, MOTOR_POLL_SLOW);
self->subState = 0;
return;
}
@@ -1886,9 +1928,7 @@ static void DMCState_MotorStart(pDMC2280Driv self, pEvtEvent event) {
return;
}
else {
NetWatchRegisterTimer(&self->state_timer,
AIR_POLL_TIMER,
state_tmr_callback, self);
DMC_SetTimer(self, AIR_POLL_TIMER);
self->subState = 0;
return;
}
@@ -1908,9 +1948,7 @@ static void DMCState_MotorStart(pDMC2280Driv self, pEvtEvent event) {
return;
}
/* TODO handle airpad timeout */
NetWatchRegisterTimer(&self->state_timer,
AIR_POLL_TIMER,
state_tmr_callback, self);
DMC_SetTimer(self, AIR_POLL_TIMER);
self->subState = 0;
return;
}
@@ -1957,9 +1995,7 @@ static void DMCState_MotorStart(pDMC2280Driv self, pEvtEvent event) {
static void DMCState_MotorOn(pDMC2280Driv self, pEvtEvent event) {
switch (event->event_type) {
case eStateEvent:
NetWatchRegisterTimer(&self->state_timer,
ON_SETTLE_TIMER,
state_tmr_callback, self);
DMC_SetTimer(self, ON_SETTLE_TIMER);
return;
case eTimerEvent:
cmdStatus(self);
@@ -2105,8 +2141,8 @@ static void DMCState_Moving(pDMC2280Driv self, pEvtEvent event) {
self->subState = 1;
return;
case eTimerEvent:
/* Note that the substate has already been set */
cmdStatus(self);
self->subState = 2;
return;
case eMessageEvent:
if (self->run_flag != 0) {
@@ -2117,9 +2153,8 @@ static void DMCState_Moving(pDMC2280Driv self, pEvtEvent event) {
pAsyncTxn pCmd = event->event.msg.cmd;
if (self->subState == 1) { /* BG */
/* TODO: Check if BG worked (reply != '?') */
NetWatchRegisterTimer(&self->state_timer,
MOTOR_POLL_FAST,
state_tmr_callback, self);
self->subState = 2;
DMC_SetTimer(self, MOTOR_POLL_FAST);
return;
}
else if (self->subState == 3) { /* PA */
@@ -2128,12 +2163,16 @@ static void DMCState_Moving(pDMC2280Driv self, pEvtEvent event) {
self->subState = 1;
return;
}
else if (self->subState == 2) { /* MG */
else if (self->subState == 2 || self->subState == 4) { /* Status */
int iRet, iFlags;
bool fwd_limit_active, rvrs_limit_active, errorlimit;
iRet = rspStatus(self, pCmd->inp_buf);
if (iRet == 0)
break;
iFlags = self->currFlags;
fwd_limit_active = !(iFlags & STATUSFWDLIMIT);
rvrs_limit_active = !(iFlags & STATUSRVRSLIMIT);
errorlimit = (iFlags & STATUSERRORLIMIT);
if (self->threadError) {
self->errorCode = THREADZERO;
self->driver_status = HWFault;
@@ -2160,13 +2199,31 @@ static void DMCState_Moving(pDMC2280Driv self, pEvtEvent event) {
self->driver_status = HWFault;
change_state(self, DMCState_OffTimer);
return;
} else if (self->stopCode == 3) {
}
else if (self->stopCode == 3) {
self->errorCode = RVRSLIM;
self->driver_status = HWFault;
change_state(self, DMCState_OffTimer);
return;
}
else {
else if (self->stopCode == 4) {
if (fwd_limit_active && rvrs_limit_active) {
self->errorCode = IMPOSSIBLE_LIM_SW;
self->driver_status = HWFault;
}
else if (fwd_limit_active) {
self->errorCode = FWDLIM;
self->driver_status = HWFault;
}
else if (rvrs_limit_active) {
self->errorCode = RVRSLIM;
self->driver_status = HWFault;
}
if (self->driver_status == HWFault) {
change_state(self, DMCState_OffTimer);
return;
}
}
self->errorCode = RUNERROR;
snprintf(self->dmc2280Error, CMDLEN, "BAD Stop Code %d",
self->stopCode);
@@ -2174,7 +2231,6 @@ static void DMCState_Moving(pDMC2280Driv self, pEvtEvent event) {
change_state(self, DMCState_OffTimer);
return;
}
}
if (self->moving) {
/* If Motion Control is off, report HWFault */
if (DMC2280MotionControl != 1) {
@@ -2186,26 +2242,28 @@ static void DMCState_Moving(pDMC2280Driv self, pEvtEvent event) {
change_state(self, DMCState_MotorHalt);
return;
}
if (self->abs_encoder && checkMotion(self) == 0)
{
if (self->abs_encoder) {
if (checkMotion(self) == 0) {
/* handle blocked */
self->errorCode = BLOCKED;
self->driver_status = HWFault;
change_state(self, DMCState_MotorHalt);
return;
}
NetWatchRegisterTimer(&self->state_timer,
MOTOR_POLL_FAST,
state_tmr_callback, self);
self->subState = 0;
if (checkPosition(self) == 0) {
/* handle runaway */
self->errorCode = POSFAULT;
self->faultPending = true; /* defer recoverable fault */
change_state(self, DMCState_MotorHalt);
return;
}
}
self->subState = 2;
DMC_SetTimer(self, MOTOR_POLL_FAST);
return;
}
/* Motor has stopped */
/* Handle limit switches */
iFlags = self->currFlags;
fwd_limit_active = !(iFlags & STATUSFWDLIMIT);
rvrs_limit_active = !(iFlags & STATUSRVRSLIMIT);
errorlimit = (iFlags & STATUSERRORLIMIT);
if (fwd_limit_active && rvrs_limit_active) {
self->errorCode = IMPOSSIBLE_LIM_SW;
self->driver_status = HWFault;
@@ -2227,12 +2285,10 @@ static void DMCState_Moving(pDMC2280Driv self, pEvtEvent event) {
target = self->fTarget;
self->fPreseek = target;
/* if we are not creeping it is backlash correction */
/* TODO: ensure minimum progress so it doesn't stall */
/* TODO: handle edge conditions like limits */
if (self->creep_val == 0) {
float precision;
/* take precision into account */
MotorGetPar(self->pMot, "precision", &precision);
/* TODO: take precision into account */
if (self->backlash_offset > 0) {
if (target + self->backlash_offset > self->currPosition + precision) {
self->preseek = 1;
@@ -2304,6 +2360,14 @@ static void DMCState_Moving(pDMC2280Driv self, pEvtEvent event) {
self->preseek = 0;
}
else {
if (self->settle
&& self->subState == 2
&& abs(absolute - self->currSteps) < 100)
{
self->subState = 4;
DMC_SetTimer(self, self->settle);
return;
}
cmdPosition(self, absolute);
self->subState = 3;
return;
@@ -2317,9 +2381,8 @@ static void DMCState_Moving(pDMC2280Driv self, pEvtEvent event) {
if (self->settle && self->time_settle_done.tv_sec == 0) {
gettimeofday(&self->time_settle_done, NULL);
self->time_settle_done.tv_sec += self->settle;
NetWatchRegisterTimer(&self->state_timer,
self->settle,
state_tmr_callback, self);
self->subState = 2;
DMC_SetTimer(self, self->settle);
return;
}
change_state(self, DMCState_OffTimer);
@@ -2381,11 +2444,12 @@ static void DMCState_MotorHalt(pDMC2280Driv self, pEvtEvent event) {
if (iRet == 0)
break;
if (self->moving) {
NetWatchRegisterTimer(&self->state_timer,
MOTOR_POLL_FAST,
state_tmr_callback, self);
DMC_SetTimer(self, MOTOR_POLL_FAST);
return;
}
if (self->faultPending) {
self->run_flag = 0;
}
if (self->run_flag == 1)
change_state(self, DMCState_MotorStart);
else
@@ -2427,15 +2491,11 @@ static void DMCState_OffTimer(pDMC2280Driv self, pEvtEvent event) {
if (self->driver_status == HWBusy)
self->driver_status = HWIdle;
if (self->motOffDelay) {
NetWatchRegisterTimer(&self->state_timer,
self->motOffDelay,
state_tmr_callback, self);
DMC_SetTimer(self, self->motOffDelay);
return;
}
}
NetWatchRegisterTimer(&self->state_timer,
0,
state_tmr_callback, self);
DMC_SetTimer(self, 0);
return;
case eTimerEvent:
if (self->run_flag <= 0)
@@ -2487,15 +2547,19 @@ static void DMCState_MotorStop(pDMC2280Driv self, pEvtEvent event) {
self->subState = 1;
return;
case eMessageEvent:
if (self->run_flag == 1) {
self->run_flag = 0;
change_state(self, DMCState_MotorStart);
return;
}
do {
pAsyncTxn pCmd = event->event.msg.cmd;
if (self->subState == 0) { /* Off command */
if (self->protocol == 0) {
if (self->faultPending) {
self->faultPending = false;
self->driver_status = HWFault;
}
if (self->driver_status != HWFault && self->run_flag == 1) {
self->run_flag = 0;
change_state(self, DMCState_MotorStart);
return;
}
change_state(self, DMCState_Idle);
return;
}
@@ -2504,6 +2568,15 @@ static void DMCState_MotorStop(pDMC2280Driv self, pEvtEvent event) {
int iRet;
iRet = rspPoll(self, pCmd->inp_buf);
if (iRet == 0) { /* state has changed to OFF */
if (self->faultPending) {
self->faultPending = false;
self->driver_status = HWFault;
}
if (self->driver_status != HWFault && self->run_flag == 1) {
self->run_flag = 0;
change_state(self, DMCState_MotorStart);
return;
}
change_state(self, DMCState_Idle);
return;
}
@@ -2516,22 +2589,17 @@ static void DMCState_MotorStop(pDMC2280Driv self, pEvtEvent event) {
}
/* TODO handle airpad timeout */
}
NetWatchRegisterTimer(&self->state_timer,
AIR_POLL_TIMER,
state_tmr_callback, self);
DMC_SetTimer(self, AIR_POLL_TIMER);
} while (0);
return;
case eCommandEvent:
switch (event->event.cmd.cmd_type) {
case CMD_RUN:
/* handle run command */
if (self->faultPending)
return;
if (self->driver_status == HWIdle)
self->driver_status = HWBusy;
if (self->waitResponse == false) {
self->run_flag = 0;
change_state(self, DMCState_MotorStart);
return;
}
self->run_flag = 1;
return;
case CMD_HALT:
@@ -2595,12 +2663,7 @@ static int DMC2280GetPos(void *pData, float *fPos){
self = (pDMC2280Driv)pData;
assert(self != NULL);
if (self->has_fsm) {
// if (self->myState == DMCState_Unknown)
// SicsWait(1);
*fPos = motPosit(self);
return OKOK;
}
return OKOK;
}
@@ -2629,19 +2692,13 @@ static int DMC2280Run(void *pData,float fValue){
return HWFault;
}
if (self->motoff_timer)
NetWatchRemoveTimer(self->motoff_timer);
self->motoff_timer = NULL;
if (self->settle)
self->time_settle_done.tv_sec = 0;
/*
* Note: this will read the current position which will block
*/
do {
float currPos;
DMC2280GetPos(pData, &currPos);
self->currPosition = currPos;
self->lastPosition = currPos;
self->time_lastPos_set.tv_sec = 0;
} while (0);
@@ -2695,14 +2752,6 @@ static void DMC2280Error(void *pData, int *iCode, char *error, int errLen){
}
*iCode = self->errorCode;
switch(*iCode){
#ifdef HAS_RS232
case NOTCONNECTED:
case BADSEND:
case BADMEMORY:
case INCOMPLETE:
strncpy(error, "General Error(TODO)", (size_t)errLen); /* TODO */
break;
#endif
case MOTCMDTMO:
strncpy(error, "Command Timeout", (size_t)errLen);
break;
@@ -2812,24 +2861,14 @@ static int DMC2280Fix(void *pData, int iCode,/*@unused@*/ float fValue){
case RUNERROR:
return MOTFAIL;
case POSFAULT:
#if HAS_RS232
case BADSEND:
case TIMEOUT:
case BADMEMORY: /* Won't happen if MonConnect sets the send terminator */
case INCOMPLETE:
self->faultPending = false;
return MOTREDO;
case NOTCONNECTED:
#endif
return MOTREDO;
break;
case STATEERROR:
/* TODO: recover state error */
if (self->has_fsm) {
/* recover state error */
if (self->state_timer)
NetWatchRemoveTimer(self->state_timer);
self->state_timer = 0;
change_state(self, DMCState_Unknown);
}
return MOTFAIL;
default:
return MOTFAIL;
@@ -2986,7 +3025,6 @@ static int DMC2280GetPar(void *pData, char *name,
*fValue = self->cntsPerX;
return 1;
}
if (self->has_fsm) {
if(strcasecmp(name,"creep_offset") == 0) {
*fValue = self->creep_offset;
return 1;
@@ -2996,7 +3034,6 @@ static int DMC2280GetPar(void *pData, char *name,
return 1;
}
}
}
else {
if (strcasecmp(name,"homerun") == 0) {
if (readHomeRun(self, fValue) == SUCCESS)
@@ -3174,7 +3211,6 @@ static int DMC2280SetPar(void *pData, SConnection *pCon,
}
if (self->abs_encoder) { /* If we DO have an absolute encoder */
if (self->has_fsm) { /* If we DO have a finite state machine */
/* Set creep offset */
if (strcasecmp(name,"creep_offset") == 0) {
if(!SCMatchRights(pCon,usMugger)) /* managers only */
@@ -3195,7 +3231,6 @@ static int DMC2280SetPar(void *pData, SConnection *pCon,
}
}
}
}
else { /* If we do NOT have an absolute encoder */
/* Invoke Home Run routine in controller */
@@ -3357,13 +3392,11 @@ static void DMC2280List(void *pData, char *name, SConnection *pCon){
SCWrite(pCon, buffer, eStatus);
snprintf(buffer, BUFFLEN, "%s.cntsPerX = %f\n", name, self->cntsPerX);
SCWrite(pCon, buffer, eStatus);
if (self->has_fsm) {
snprintf(buffer, BUFFLEN, "%s.Creep_Offset = %f\n", name, self->creep_offset);
SCWrite(pCon, buffer, eStatus);
snprintf(buffer, BUFFLEN, "%s.Creep_Precision = %f\n", name, self->creep_precision);
SCWrite(pCon, buffer, eStatus);
}
}
if (self->posit_count > 0) {
int i;
snprintf(buffer, BUFFLEN, "%s.posit_count = %d\n", name,
@@ -3394,13 +3427,11 @@ static void DMC_Notify(void* context, int event) {
snprintf(line, 132, "Reconnect on Motor '%s'", self->name);
SICSLogWrite(line, eStatus);
/* TODO: reconnect */
if (self->has_fsm) {
/* Reset the state machine */
if (self->state_timer)
NetWatchRemoveTimer(self->state_timer);
self->state_timer = 0;
change_state(self, DMCState_Unknown);
}
break;
}
return;
@@ -3570,14 +3601,6 @@ MotorDriver *CreateDMC2280(SConnection *pCon, char *motor, char *params) {
sscanf(pPtr,"%d",&(pNew->debug));
}
/* FSM: this driver uses the finite state machine model */
if ((pPtr=getParam(pCon, interp, params,"fsm",_OPTIONAL)) == NULL)
pNew->has_fsm=1;
else {
sscanf(pPtr,"%d",&(pNew->has_fsm));
assert(pNew->has_fsm); /* DEPRECATED */
}
if ((pPtr=getParam(pCon, interp, params, LONG_NAME, _OPTIONAL)) != NULL) {
strncpy(pNew->long_name, pPtr, sizeof(pNew->long_name));
pNew->long_name[sizeof(pNew->long_name) - 1] = '\0';
@@ -3702,7 +3725,7 @@ MotorDriver *CreateDMC2280(SConnection *pCon, char *motor, char *params) {
pNew->cntsPerX = 1.0;
else
sscanf(pPtr,"%lg",&(pNew->cntsPerX));
if (pNew->has_fsm) {
/* CREEP_OFFSET: this controls unidirectional driving */
if ((pPtr=getParam(pCon, interp, params,"creep_offset",_OPTIONAL)) == NULL)
pNew->creep_offset = 0.0;
@@ -3720,7 +3743,6 @@ MotorDriver *CreateDMC2280(SConnection *pCon, char *motor, char *params) {
if (pNew->creep_precision < 0)
pNew->creep_precision = -pNew->creep_precision;
}
}
if ((pPtr=getParam(pCon, interp, params,"posit_count",_OPTIONAL)) == NULL)
pNew->posit_count = 0;
@@ -3922,18 +3944,16 @@ int DMC2280Action(SConnection *pCon, SicsInterp *pSics, void *pData,
return MotorSetPar(self->pMot, pCon, "softzero", newZero);
}
else if(strcasecmp("reset", argv[1]) == 0) {
if (self->has_fsm) {
/* Reset the state machine */
if (self->state_timer)
NetWatchRemoveTimer(self->state_timer);
self->state_timer = 0;
self->driver_status = HWIdle;
change_state(self, DMCState_Unknown);
}
/* Handle further in generic motor driver */
return MotorAction(pCon, pSics, pData, argc, argv);
}
else if(self->has_fsm && strcasecmp("state", argv[1]) == 0) {
else if(strcasecmp("state", argv[1]) == 0) {
char line[132];
snprintf(line, 132, "%s.state = %s(%d) (timer=%s)",
self->name,
@@ -3943,7 +3963,7 @@ int DMC2280Action(SConnection *pCon, SicsInterp *pSics, void *pData,
SCWrite(pCon, line, eValue);
return 1;
}
else if(self->has_fsm && strcasecmp("trace", argv[1]) == 0) {
else if(strcasecmp("trace", argv[1]) == 0) {
if (argc > 2 && strcasecmp("on", argv[2]) == 0) {
self->trace = pCon;
SCWrite(pCon, "TRACE ON", eValue);