diff --git a/site_ansto/instrument/hipd/config/commands/commands.tcl b/site_ansto/instrument/hipd/config/commands/commands.tcl index 8d986538..75bd42d8 100644 --- a/site_ansto/instrument/hipd/config/commands/commands.tcl +++ b/site_ansto/instrument/hipd/config/commands/commands.tcl @@ -17,8 +17,9 @@ catch { #ffr Changed 0.5 to 0.2 on 30/06/2014 because # oct hits upper limit switch at about 1.27 degrees # with new "oct oscillate" command. - oct oscillate_low [expr -abs($range/2.0) - 0.2] - oct oscillate_high [expr abs($range/2.0) + 0.2] +#dcl Removed 0.2 because old osc limits it to +/-1.0 + oct oscillate_low [expr -abs($range/2.0)] + oct oscillate_high [expr abs($range/2.0)] set spd [expr 2.0*$range / $time] oct maxretry 5 diff --git a/site_ansto/motor_dmc2280.c b/site_ansto/motor_dmc2280.c index 0b530e3d..4640a517 100644 --- a/site_ansto/motor_dmc2280.c +++ b/site_ansto/motor_dmc2280.c @@ -285,6 +285,7 @@ struct __MoDriv { bool doReportMotion; /**< flag for reporting motion when not driving */ bool doOscillate; /**< flag for motor oscillation */ bool oscillate_up; /**< next oscillation move is to high position */ + bool oscillate_up_first; /**< first oscillation move is to high position */ bool oscillate_init; /**< initial move is not counted */ int oscillate_count; /**< number of moves to make or -1 for continuous */ int oscillate_counter; /**< number of moves made - half-oscillations */ @@ -3284,15 +3285,9 @@ static void DMCState_Oscillate(pDMC2280Driv self, pEvtEvent event) { switch (event->event_type) { case eStateEvent: + /* Cancel any return address */ self->myNextState = NULL; - /* handle termination conditions (e.g. count) */ - if (self->oscillate_count > 0 && self->oscillate_counter >= self->oscillate_count) - self->doOscillate = false; - if (!self->doOscillate) { - (void) report_motion(self, eReportFinal); - change_state(self, DMCState_OffTimer); /* TODO: check this is OK */ - return; - } + /* Calculate our next move */ if (self->oscillate_up) { double fHard; if (getHardFromSoft(self, NULL, self->oscillate_high, &fHard)) @@ -3304,6 +3299,49 @@ static void DMCState_Oscillate(pDMC2280Driv self, pEvtEvent event) { self->fTarget = fHard; self->oscillate_up = true; } + /* + * We do not want to count the first move-to-end. + * We want to count each time we are at the same point as the first time. + * So, we remember what we were doing the first time + * And we count each time it is the same. + */ + if (self->oscillate_init) { + if (true /*self->verbose*/) { + SICSLogPrintf(eLog, "Motor=%s oscillate: first move is to %f, next is %s", + self->name, + self->fTarget, + self->oscillate_up ? "UP" : "DOWN"); + } + self->oscillate_up_first = self->oscillate_up; + self->oscillate_init = false; + } else { + if (self->oscillate_up_first == self->oscillate_up ? false : true) { + self->oscillate_counter++; + } + /* handle termination conditions (e.g. count) */ + if (self->oscillate_count > 0 && self->oscillate_counter >= self->oscillate_count) { + self->doOscillate = false; + } else { + if (true /*self->verbose*/) { + SICSLogPrintf(eLog, "Motor=%s oscillate: count %d move is to %f, next is %s", + self->name, + self->oscillate_counter, + self->fTarget, + self->oscillate_up ? "UP" : "DOWN"); + } + } + } + /* handle termination conditions (e.g. count) */ + if (!self->doOscillate) { + if (true /*self->verbose*/) { + SICSLogPrintf(eLog, "Motor=%s oscillate: stopped at count %d", + self->name, + self->oscillate_counter); + } + (void) report_motion(self, eReportFinal); + change_state(self, DMCState_OffTimer); /* TODO: check this is OK */ + return; + } /* TODO: set timer for optional pause */ /* Note: fallthrough is intentional */ case eTimerEvent: @@ -3320,9 +3358,6 @@ static void DMCState_Oscillate(pDMC2280Driv self, pEvtEvent event) { } /* set the next state after this move */ self->myNextState = DMCState_Oscillate; - if (!self->oscillate_init) - self->oscillate_counter++; - self->oscillate_init = false; change_state(self, DMCState_StepMove); return; case eCommandEvent: @@ -5684,6 +5719,7 @@ int DMC2280Action(SConnection *pCon, SicsInterp *pSics, void *pData, } else if (strcasecmp("oscillate_counter", argv[1]) == 0) { SCPrintf(pCon, eValue, "%s.oscillate_counter = %d", self->name, self->oscillate_counter); + return 1; } else if(strcasecmp("osc", argv[1]) == 0 || strcasecmp("oscillate", argv[1]) == 0) { if (argc > 2) { @@ -5698,6 +5734,7 @@ int DMC2280Action(SConnection *pCon, SicsInterp *pSics, void *pData, if (strcasecmp("start", argv[2]) == 0) { float fFixed; double fHard; + /* Check that it is OK to do this */ MotorGetPar(self->pMot, "fixed", &fFixed); if (fFixed >= 0) { SCPrintf(pCon, eWarning, "Motor %s is Fixed", self->name); @@ -5711,14 +5748,20 @@ int DMC2280Action(SConnection *pCon, SicsInterp *pSics, void *pData, SCPrintf(pCon, eWarning, "Oscillate high point is in error"); return 1; } - if (fabs(self->oscillate_high - motPosit(self)) < fabs(self->oscillate_low - motPosit(self))) + /* choose the starting end, either as told or the nearest */ + if (argc > 3 && strcasecmp("high", argv[3]) == 0) + self->oscillate_up = true; + else if (argc > 3 && strcasecmp("low", argv[3]) == 0) + self->oscillate_up = false; + else if (fabs(self->oscillate_high - motPosit(self)) < fabs(self->oscillate_low - motPosit(self))) self->oscillate_up = true; else self->oscillate_up = false; + /* Set up the initial conditions */ self->doOscillate = true; self->doReportMotion = true; self->oscillate_init = true; - self->oscillate_counter = 0; + self->oscillate_counter = -1 /* allow for move-to-start */; state_cmd_execute(self, CMD_RUN); return 1; }