From 566e3c950e6951d1f8abcc5832c05f1a762062d1 Mon Sep 17 00:00:00 2001 From: smathis Date: Thu, 20 Mar 2025 16:27:28 +0100 Subject: [PATCH] Main movements implemented Main movement of detector guide angle, angle offset and lift offset as well as switch between working and changer position implemented. --- src/auxiliaryAxis.cpp | 5 ++- src/auxiliaryAxis.h | 6 +-- src/detectorTowerAxis.cpp | 93 ++++++++++++++++++++++++++------------- src/detectorTowerAxis.h | 12 +++-- 4 files changed, 75 insertions(+), 41 deletions(-) diff --git a/src/auxiliaryAxis.cpp b/src/auxiliaryAxis.cpp index a2bd87a..f256dbf 100644 --- a/src/auxiliaryAxis.cpp +++ b/src/auxiliaryAxis.cpp @@ -127,8 +127,9 @@ asynStatus auxiliaryAxis::doPoll(bool *moving) { pl_status = pC_->getIntegerParam(dTA_->axisNo_, pC_->motorStatusMoving(), &isMoving); if (pl_status != asynSuccess) { - return pC_->paramLibAccessFailed(pl_status, "motorPosition_", axisNo_, - __PRETTY_FUNCTION__, __LINE__); + return pC_->paramLibAccessFailed(pl_status, "motorStatusMoving_", + dTA_->axisNo_, __PRETTY_FUNCTION__, + __LINE__); } *moving = isMoving != 0; diff --git a/src/auxiliaryAxis.h b/src/auxiliaryAxis.h index 22220a9..85c777d 100644 --- a/src/auxiliaryAxis.h +++ b/src/auxiliaryAxis.h @@ -50,10 +50,8 @@ class auxiliaryAxis : public turboPmacAxis { asynStatus doPoll(bool *moving); /** - * @brief Set the target value for the detector angle without starting a - * movement - * - * TODO + * @brief Set the target value for the detector angle and trigger a position + * collection cycle * * @param position * @param relative diff --git a/src/detectorTowerAxis.cpp b/src/detectorTowerAxis.cpp index 88d7b91..faeb247 100644 --- a/src/detectorTowerAxis.cpp +++ b/src/detectorTowerAxis.cpp @@ -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(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); diff --git a/src/detectorTowerAxis.h b/src/detectorTowerAxis.h index d101f2d..7850b07 100644 --- a/src/detectorTowerAxis.h +++ b/src/detectorTowerAxis.h @@ -60,10 +60,8 @@ class detectorTowerAxis : public turboPmacAxis { asynStatus doPoll(bool *moving); /** - * @brief Set the target value for the detector angle without starting a - * movement - * - * TODO + * @brief Set the target value for the detector angle and trigger a position + * collection cycle * * @param position * @param relative @@ -115,6 +113,12 @@ class detectorTowerAxis : public turboPmacAxis { // axes) bool startingDeferredMovement_; + /* + The collector cycle waits until this time in seconds has passed before + starting a deferred movement + */ + double deferredMovementWait_; + protected: detectorTowerController *pC_; double targetPosition_;