|
|
|
@ -36,7 +36,7 @@ static void deferredMovementCollectorLoop(void *drvPvt) {
|
|
|
|
|
// Wait for 100 ms and then start the movement with the information
|
|
|
|
|
// available
|
|
|
|
|
axis->startingDeferredMovement_ = true;
|
|
|
|
|
epicsThreadSleep(0.1);
|
|
|
|
|
epicsThreadSleep(axis->deferredMovementWait_);
|
|
|
|
|
axis->startCombinedMove();
|
|
|
|
|
|
|
|
|
|
// After the movement command has been send, reset the flag
|
|
|
|
@ -81,6 +81,7 @@ detectorTowerAxis::detectorTowerAxis(detectorTowerController *pC, int axisNo,
|
|
|
|
|
targetPosition_ = 0.0;
|
|
|
|
|
receivedTarget_ = false;
|
|
|
|
|
startingDeferredMovement_ = false;
|
|
|
|
|
deferredMovementWait_ = 0.1; // seconds
|
|
|
|
|
liftOffsetAxis_ = liftOffsetAxis;
|
|
|
|
|
tiltOffsetAxis_ = tiltOffsetAxis;
|
|
|
|
|
liftOffsetAxis->dTA_ = this;
|
|
|
|
@ -297,28 +298,10 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|
|
|
|
// Axis ready
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyPosState, true,
|
|
|
|
|
pC_->asynUserSelf())) {
|
|
|
|
|
|
|
|
|
|
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_FLOW,
|
|
|
|
|
"Controller \"%s\", axis %d => %s, line %d\nAxis moving "
|
|
|
|
|
"to or in change "
|
|
|
|
|
"position.%s\n",
|
|
|
|
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
|
|
|
|
pC_->getMsgPrintControl().getSuffix());
|
|
|
|
|
}
|
|
|
|
|
resetCountPosState = false;
|
|
|
|
|
// Axis is moving to or in changing position
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyPosState, true,
|
|
|
|
|
pC_->asynUserSelf())) {
|
|
|
|
|
|
|
|
|
|
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_FLOW,
|
|
|
|
|
"Controller \"%s\", axis %d => %s, line %d\nAxis moving "
|
|
|
|
|
"to working position.%s\n",
|
|
|
|
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
|
|
|
|
pC_->getMsgPrintControl().getSuffix());
|
|
|
|
|
}
|
|
|
|
|
// Axis is moving to working state
|
|
|
|
|
resetCountPosState = false;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
@ -857,9 +840,6 @@ asynStatus detectorTowerAxis::startCombinedMove() {
|
|
|
|
|
targetPosition_, liftOffsetAxis_->targetPosition_,
|
|
|
|
|
tiltOffsetAxis_->targetPosition_);
|
|
|
|
|
|
|
|
|
|
// DEBUG
|
|
|
|
|
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR, "%s\n", command);
|
|
|
|
|
|
|
|
|
|
// Lock the access to the controller since this function runs in another
|
|
|
|
|
// thread than the poll method.
|
|
|
|
|
pC_->lock();
|
|
|
|
@ -980,17 +960,13 @@ detectorTowerAxis::toggleWorkingChangerState(bool toChangingPosition) {
|
|
|
|
|
bool isAlreadyThere = (toChangingPosition == false && positionState == 1) ||
|
|
|
|
|
(toChangingPosition == true && positionState == 2);
|
|
|
|
|
|
|
|
|
|
if (pC_->getMsgPrintControl().shouldBePrinted(
|
|
|
|
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
|
|
|
|
isAlreadyThere, pC_->asynUserSelf())) {
|
|
|
|
|
if (isAlreadyThere) {
|
|
|
|
|
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_WARNING,
|
|
|
|
|
"Controller \"%s\", axis %d => %s, line %d\nAxis is already "
|
|
|
|
|
"in %s position.%s\n",
|
|
|
|
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
|
|
|
|
toChangingPosition ? "changer" : "working",
|
|
|
|
|
pC_->getMsgPrintControl().getSuffix());
|
|
|
|
|
}
|
|
|
|
|
if (isAlreadyThere) {
|
|
|
|
|
return asynSuccess;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1155,11 +1131,66 @@ static void configDetectorTowerCreateAxisCallFunc(const iocshArgBuf *args) {
|
|
|
|
|
args[3].ival);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This function is made known to EPICS in detectorTower.dbd and is called by
|
|
|
|
|
// EPICS in order to register both functions in the IOC shell
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Set the setDeferredMovementWait (FFI implementation)
|
|
|
|
|
*
|
|
|
|
|
* @param portName Name of the controller
|
|
|
|
|
* @param axisNo Axis number
|
|
|
|
|
* @param scaleMovTimeout Scaling factor (in seconds)
|
|
|
|
|
* @return asynStatus
|
|
|
|
|
*/
|
|
|
|
|
asynStatus setDeferredMovementWait(const char *portName, int axisNo,
|
|
|
|
|
double deferredMovementWait) {
|
|
|
|
|
|
|
|
|
|
sinqController *pC;
|
|
|
|
|
pC = (sinqController *)findAsynPortDriver(portName);
|
|
|
|
|
if (pC == nullptr) {
|
|
|
|
|
errlogPrintf("Controller \"%s\" => %s, line %d:\nPort %s not found.",
|
|
|
|
|
portName, __PRETTY_FUNCTION__, __LINE__, portName);
|
|
|
|
|
return asynError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
asynMotorAxis *asynAxis = pC->getAxis(axisNo);
|
|
|
|
|
detectorTowerAxis *axis = dynamic_cast<detectorTowerAxis *>(asynAxis);
|
|
|
|
|
if (axis == nullptr) {
|
|
|
|
|
errlogPrintf("Controller \"%s\" => %s, line %d:\nAxis %d does not "
|
|
|
|
|
"exist or is not an instance of detectorTowerAxis.",
|
|
|
|
|
portName, __PRETTY_FUNCTION__, __LINE__, axisNo);
|
|
|
|
|
return asynError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
axis->deferredMovementWait_ = deferredMovementWait;
|
|
|
|
|
return asynSuccess;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const iocshArg setDeferredMovementWaitArg0 = {"Controller port name",
|
|
|
|
|
iocshArgString};
|
|
|
|
|
static const iocshArg setDeferredMovementWaitArg1 = {"Axis number",
|
|
|
|
|
iocshArgInt};
|
|
|
|
|
static const iocshArg setDeferredMovementWaitArg2 = {
|
|
|
|
|
"Minimum time a deferred movement will be delayed in order to collect "
|
|
|
|
|
"commands in seconds",
|
|
|
|
|
iocshArgDouble};
|
|
|
|
|
static const iocshArg *const setDeferredMovementWaitArgs[] = {
|
|
|
|
|
&setDeferredMovementWaitArg0, &setDeferredMovementWaitArg1,
|
|
|
|
|
&setDeferredMovementWaitArg2};
|
|
|
|
|
static const iocshFuncDef setDeferredMovementWaitDef = {
|
|
|
|
|
"setDeferredMovementWait", 3, setDeferredMovementWaitArgs};
|
|
|
|
|
|
|
|
|
|
static void setDeferredMovementWaitCallFunc(const iocshArgBuf *args) {
|
|
|
|
|
setDeferredMovementWait(args[0].sval, args[1].ival, args[2].dval);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
// This function is made known to EPICS in detectorTower.dbd and is
|
|
|
|
|
// called by EPICS in order to register both functions in the IOC shell
|
|
|
|
|
static void detectorTowerAxisRegister(void) {
|
|
|
|
|
iocshRegister(&configDetectorTowerCreateAxis,
|
|
|
|
|
configDetectorTowerCreateAxisCallFunc);
|
|
|
|
|
iocshRegister(&setDeferredMovementWaitDef, setDeferredMovementWaitCallFunc);
|
|
|
|
|
}
|
|
|
|
|
epicsExportRegistrar(detectorTowerAxisRegister);
|
|
|
|
|
|
|
|
|
|