check I/O bit numbers; don't send output pulses at artificially split trajectory segments; modified the way 'done moving' check requires two 'done moving' indicators

This commit is contained in:
timmmooney
2011-02-28 17:10:39 +00:00
parent 161b50c5f7
commit b6a3a73fd9
+44 -35
View File
@@ -27,6 +27,7 @@ program MAX_trajectoryScan("P=13IDC:,R=traj1,M1=M1,M2=M2,M3=M3,M4=M4,M5=M5,M6=M6
#define MIN(a,b) ((a) > (b) ? (b) : (a))
#define NINT(f) (int)((f)>0 ? (f)+0.5 : (f)-0.5)
#define USE_VID 1
#define DEBUG_VA 10
/* This program must be compiled with the recursive option */
option +r;
@@ -87,9 +88,10 @@ int cardNumber;
#define MAX_STRING_SIZE 40
/* Polling interval in seconds for waiting for motors to reach their targets */
#define POLL_INTERVAL (1/10.)
#define POLL_INTERVAL (1/5.)
#define READ_INTERVAL (1/60.)
%%char axis_name[] = "XYZTUVRS";
char stringOut[MAX_MESSAGE_STRING];
char sbuf[MAX_MESSAGE_STRING];
char stringIn[MAX_MESSAGE_STRING];
@@ -102,6 +104,7 @@ int k;
int n;
double delay;
int anyMoving;
int anyMovingPrev;
int ncomplete;
int nextra;
int npoints;
@@ -317,7 +320,7 @@ ss maxTrajectoryScan {
%%if (pVar->simMode==0) writeOnly(ssId, pVar, pVar->stringOut);
/* digital I/O commands */
if (outBitNum >= 0) {
if ((outBitNum >= 0) && (outBitNum <= 15)) {
onMask = 1<<outBitNum;
offMask = 0;
outMask = 1<<outBitNum;
@@ -327,7 +330,7 @@ ss maxTrajectoryScan {
sprintf(stringOut, "BL%d;", outBitNum); /* set output bit low */
%%if (pVar->simMode==0) writeOnly(ssId, pVar, pVar->stringOut);
}
if (inBitNum >= 0) {
if ((inBitNum >= 0) && (inBitNum <= 15)) {
sprintf(stringOut, "IO%d,0;", inBitNum); /* set bit as input */
%%if (pVar->simMode==0) writeOnly(ssId, pVar, pVar->stringOut);
}
@@ -359,24 +362,25 @@ ss maxTrajectoryScan {
if (moveAxis[j]) {
/* we may need current raw positions to mock up relative mode */
%%epicsTimeGetCurrent(&eStartTime); /* not actually the start time, we just need a value */
%%epicsTimeGetCurrent(&eStartTime); /* not actually the start time, getMotorPositions just needs a value */
%%getMotorPositions(ssId, pVar, pVar->motorCurrent, pVar->motorCurrentRaw, &(pVar->dtime));
if (debugLevel >= 1) printf("\n");
/* output bit */
if (firstTask && (outBitNum >= 0)) {
if (firstTask && ((outBitNum >= 0) && (outBitNum <= 15))) {
/* Tell controller to output a pulse at the beginning of every trajectory segment. */
sprintf(stringOut, "AM; VIO[%d]%04x,%04x,%04x;", j+1, onMask, offMask, outMask);
%%if (pVar->simMode==0) writeOnly(ssId, pVar, pVar->stringOut);
} else {
/* Tell controller NOT to output a pulse at the beginning of every trajectory segment. */
sprintf(stringOut, "AM; VIO[%d];", j+1);
sprintf(stringOut, "AM; VIO[%d]0,0,0;", j+1);
%%if (pVar->simMode==0) writeOnly(ssId, pVar, pVar->stringOut);
}
/* done flag and interrupt */
#if USE_VID
sprintf(stringOut, "AM; VID[%d]1;", j+1);
%%if (pVar->simMode==0) writeOnly(ssId, pVar, pVar->stringOut);
#endif
/* Don't start until I tell you to start */
sprintf(stringOut, "AM; VH[%d]0;", j+1);
%%if (pVar->simMode==0) writeOnly(ssId, pVar, pVar->stringOut);
@@ -384,9 +388,10 @@ ss maxTrajectoryScan {
/* Arm the trajectories to start on an input trigger bit.
* If no input trigger bit, then start now.
*/
if (inBitNum >= 0) {
if ((inBitNum >= 0) && (inBitNum <= 15)) {
/* Wait for input bit to go high before processing any more commands. */
sprintf(stringOut, "AM; SW%d;", inBitNum);
/*sprintf(stringOut, "AM; SW%d;", inBitNum);*/
%%sprintf(pVar->stringOut, "A%c; SW%d;", axis_name[pVar->j], pVar->inBitNum);
%%if (pVar->simMode==0) writeOnly(ssId, pVar, pVar->stringOut);
}
@@ -443,6 +448,11 @@ ss maxTrajectoryScan {
if (moveMode != MOVE_MODE_ABSOLUTE) position[j][i] += motorCurrentRaw[j];
if (do_split) {
if (firstTask && ((outBitNum >= 0) && (outBitNum <= 15))) {
/* Disable output pulses */
sprintf(stringOut, "AM; VIO[%d]0,0,0;", j+1);
%%if (pVar->simMode==0) writeOnly(ssId, pVar, pVar->stringOut);
}
/* we have to split this segment into two where velocity goes through zero. */
n = sprintf(stringOut, "AM; VA[%d]%d;", j+1, segment_accel);
n += sprintf(&stringOut[n], "VV[%d]%d,%d;", j+1, segment_v_start, v1);
@@ -453,6 +463,11 @@ ss maxTrajectoryScan {
strcat(stringOut, ";");
%%if (pVar->simMode==0) writeOnly(ssId, pVar, pVar->stringOut);
if (firstTask && ((outBitNum >= 0) && (outBitNum <= 15))) {
/* Enable output pulses */
sprintf(stringOut, "AM; VIO[%d]%04x,%04x,%04x;", j+1, onMask, offMask, outMask);
%%if (pVar->simMode==0) writeOnly(ssId, pVar, pVar->stringOut);
}
n = sprintf(stringOut, "AM; VA[%d]%d;", j+1, segment_accel);
if (i<npoints-1) {
n += sprintf(&stringOut[n], "VV[%d]%d;", j+1, segment_v_end);
@@ -560,7 +575,11 @@ ss maxTrajectoryScan {
lastRealTimePoint = 0;
/* KLUDGE: coopt variable 'accel' as test velocity-override factor */
vOverrideFactor = accel;
waitingForTrigger = (inBitNum >= 0);
waitingForTrigger = ((inBitNum >= 0) && (inBitNum <= 15));
for (j=0, movingMask = 0; j<numAxes; j++) {
if (moveAxis[j]) movingMask |= (1<<j);
}
anyMoving = movingMask;
} state wait_execute
}
@@ -604,10 +623,9 @@ ss maxTrajectoryScan {
doPoll = (dtime - lastPollTime) > POLL_INTERVAL;
if (doPoll) pvPut(elapsedTime);
for (j=0, movingMask = 0; j<numAxes; j++) {
for (j=0; j<numAxes; j++) {
if (moveAxis[j]) {
pvPut(motorCurrent[j]);
movingMask |= (1<<j);
/* MAXV has no readback function, so we read while it's moving. */
if (currPulse < MAX_PULSES-1) {
motorReadbacks[j][currPulse] = motorCurrent[j];
@@ -658,9 +676,10 @@ ss maxTrajectoryScan {
lastRealTimePoint = i;
if (doPoll) {
lastPollTime = dtime;
anyMovingPrev = anyMoving;
%%pVar->anyMoving = getMotorMoving(ssId, pVar);
if (debugLevel >= 10) printf("movingMask=0x%x, anyMoving=0x%x\n", movingMask, anyMoving);
if (!(anyMoving&movingMask)) {
if (!(anyMoving&movingMask) && !(anyMovingPrev&movingMask)) {
execState = EXECUTE_STATE_FLYBACK;
execStatus = STATUS_SUCCESS;
strcpy(execMessage, " ");
@@ -862,13 +881,15 @@ static int writeOnly(SS_ID ssId, struct UserVar *pVar, char *command)
static int writeRead(SS_ID ssId, struct UserVar *pVar, char *command, char *reply)
{
asynStatus status;
char buffer[MAX_MESSAGE_STRING];
#if USE_ASYN
size_t nwrite, nread;
int eomReason;
char buffer[MAX_MESSAGE_STRING];
#endif
/* Copy command so we can add terminator */
strncpy(buffer, command, MAX_MESSAGE_STRING-3);
#if USE_ASYN
strcat(buffer, "\r");
/* Use 30 second timeout, some commands take a long time to reply */
status = pasynOctetSyncIO->writeRead((asynUser *)pVar->pasynUser, buffer,
@@ -878,8 +899,8 @@ static int writeRead(SS_ID ssId, struct UserVar *pVar, char *command, char *repl
status = (asynStatus) MAXV_send_mess(pVar->cardNumber, command, (char *) NULL);
status |= (asynStatus) MAXV_recv_mess(pVar->cardNumber, reply, 1);
#endif
if (pVar->debugLevel >= 10) {
printf(" writeRead:command='%s', reply='%s'\n", command, reply);
if (pVar->debugLevel >= 5) {
printf(" writeRead:command='%s', reply='%s'\n", buffer, reply);
}
return(status);
}
@@ -955,22 +976,10 @@ static int getMotorPositionsRB(SS_ID ssId, struct UserVar *pVar, double *pos, ep
static int getMotorMoving(SS_ID ssId, struct UserVar *pVar)
{
int i, mask=1, result=0;
char s[MAX_MESSAGE_STRING];
for (i=0; i==0;) {
/* Read the current status of all the axes */
writeRead(ssId, pVar, "QI", pVar->stringIn);
strcpy(s, pVar->stringIn);
writeRead(ssId, pVar, "QI", pVar->stringIn);
if (strcmp(s, pVar->stringIn) != 0) {
if (pVar->debugLevel >= 10) {
printf("getMotorMoving: inconsistent replies:\n");
printf("r1:'%s', r2:'%s'\n", s, pVar->stringIn);
}
} else {
i = 1;
}
}
/* Read the current status of all the axes */
writeRead(ssId, pVar, "QI", pVar->stringIn);
/* Parse the return string which is of the form
* MDNN,MDNN,PNLN,PNNN,PNLN,PNNN,PNNN,PNNN,<LF>
* The second character of each status word is 'D' (done) or 'N' (not done)
@@ -981,7 +990,7 @@ static int getMotorMoving(SS_ID ssId, struct UserVar *pVar)
}
pVar->stringIn[40] = '\0';
if (pVar->debugLevel >= 10) {
if (pVar->debugLevel >= 7) {
printf("getMotorMoving: reply = '%s', movingMask = %2x\n", pVar->stringIn, result);
}
return(result);
@@ -1095,7 +1104,7 @@ static int buildTrajectory(SS_ID ssId, struct UserVar *pVar, double *realTimeTra
if (pVar->debugLevel >= 10) printf("v_lin=%f, v_spline=%f\n", v_lin, v_spline);
/* the acceleration that will get us to the ideal velocity */
if (1) {
if (0) {
v_ideal = v_spline;
} else {
v_ideal = v_lin;