diff --git a/Makefile b/Makefile index e93cf38..c180db5 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ EPICS_VERSIONS=7.0.7 ARCH_FILTER=RHEL% # Specify the version of asynMotor we want to build against -motorBase_VERSION=7.2.2 +motorBase_VERSION=7.3.2 # These headers allow to depend on this library for derived drivers. HEADERS += src/masterMacsAxis.h diff --git a/src/masterMacsAxis.cpp b/src/masterMacsAxis.cpp index 67ceedd..a2d9a85 100644 --- a/src/masterMacsAxis.cpp +++ b/src/masterMacsAxis.cpp @@ -11,6 +11,11 @@ #include #include +enum moveMode { + positionMode, + velocityMode, +}; + struct masterMacsAxisImpl { /* The axis status and axis error of MasterMACS are given as an integer from @@ -24,6 +29,7 @@ struct masterMacsAxisImpl { bool needInit = true; bool targetReachedUninitialized; bool dynamicLimits; + moveMode lastMoveCommand; }; /* @@ -94,6 +100,7 @@ masterMacsAxis::masterMacsAxis(masterMacsController *pC, int axisNo) .timeAtHandshake = 0, .targetReachedUninitialized = true, .dynamicLimits = false, + .lastMoveCommand = positionMode, })) { asynStatus status = asynSuccess; @@ -260,7 +267,7 @@ asynStatus masterMacsAxis::init() { __PRETTY_FUNCTION__, __LINE__); } - status = setVeloFields(motVelocity, 0.0, motVmax); + status = setVeloFields(abs(motVelocity), 0.0, motVmax); if (status != asynSuccess) { return status; } @@ -386,10 +393,7 @@ asynStatus masterMacsAxis::readLimits() { highLimit = highLimit - limitsOffset; lowLimit = lowLimit + limitsOffset; - setAxisParamChecked(this, motorHighLimitFromDriver, highLimit); - setAxisParamChecked(this, motorLowLimitFromDriver, lowLimit); - - return status; + return setLimits(highLimit, lowLimit); } // Perform the actual poll @@ -399,10 +403,10 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { asynStatus poll_status = asynSuccess; // Status of read-write-operations of ASCII commands to the controller - asynStatus rw_status = asynSuccess; + asynStatus rwStatus = asynSuccess; // Status of parameter library operations - asynStatus pl_status = asynSuccess; + asynStatus plStatus = asynSuccess; char response[pC_->MAXBUF_] = {0}; int nvals = 0; @@ -451,8 +455,8 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { } pC_->read(axisNo_, 86, response); - if (rw_status != asynSuccess) { - return rw_status; + if (rwStatus != asynSuccess) { + return rwStatus; } nvals = sscanf(response, "%lf", &handshakePerformed); @@ -478,38 +482,20 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { getAxisParamChecked(this, motorRecResolution, &motorRecResolution); // Read the previous motor position - pl_status = motorPosition(&previousPosition); - if (pl_status != asynSuccess) { - return pl_status; + plStatus = motorPosition(&previousPosition); + if (plStatus != asynSuccess) { + return plStatus; } // Update the axis status - rw_status = readAxisStatus(); - if (rw_status != asynSuccess) { - return rw_status; + rwStatus = readAxisStatus(); + if (rwStatus != asynSuccess) { + return rwStatus; } - // If we wait for a handshake, but the motor was moving in its last poll - // cycle and has reached its target, it is not moving. Otherwise it is - // considered moving, even if we're still waiting for the handshake. - if (pMasterMacsA_->targetReachedUninitialized) { - *moving = false; - } else { - if (targetReached() || !switchedOn()) { - *moving = false; - } else { - *moving = true; - } - } - - if (targetReached()) { - pMasterMacsA_->targetReachedUninitialized = false; - } - - // Read the current position - rw_status = pC_->read(axisNo_, 12, response); - if (rw_status != asynSuccess) { - return rw_status; + rwStatus = pC_->read(axisNo_, 12, response); + if (rwStatus != asynSuccess) { + return rwStatus; } nvals = sscanf(response, "%lf", ¤tPosition); if (nvals != 1) { @@ -517,12 +503,60 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { __PRETTY_FUNCTION__, __LINE__); } + plStatus = setMotorPosition(currentPosition); + if (plStatus != asynSuccess) { + return plStatus; + } + setAxisParamChecked(this, motorEncoderPosition, currentPosition); + + if (pMasterMacsA_->lastMoveCommand == velocityMode && !speedEqualZero()) { + + // TODO: Not sure whether the RVEL field of the motor record does not + // work - has to be clarified + double actualVelocity = 0.0; + + rwStatus = pC_->read(axisNo_, 14, response); + if (rwStatus != asynSuccess) { + return rwStatus; + } + nvals = sscanf(response, "%lf", &actualVelocity); + if (nvals != 1) { + return pC_->couldNotParseResponse("R14", response, axisNo_, + __PRETTY_FUNCTION__, __LINE__); + } + + // Write the actual velocity to the paramLib (TODO: does it though?) + setAxisParamChecked(this, motorVelocity, actualVelocity); + + // Motor is moving in velocity mode + *moving = true; + + } else { + + // If we wait for a handshake, but the motor was moving in its last poll + // cycle and has reached its target, it is not moving. Otherwise it is + // considered moving, even if we're still waiting for the handshake. + if (pMasterMacsA_->targetReachedUninitialized) { + *moving = false; + } else { + if (targetReached() || !switchedOn()) { + *moving = false; + } else { + *moving = true; + } + } + + if (targetReached()) { + pMasterMacsA_->targetReachedUninitialized = false; + } + } + /* - Read out the error if either a fault condition status flag has been set or - if a movement has just ended. + Read out the error if either a fault condition status flag has been set + or if a movement has just ended. */ if (faultConditionSet() || !(*moving)) { - rw_status = readAxisError(); + rwStatus = readAxisError(); } msgPrintControlKey keyError = msgPrintControlKey( @@ -743,9 +777,9 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { // Read out the limits, if the motor is not moving and if the limits are // dynamic if (pMasterMacsA_->dynamicLimits && !(*moving)) { - rw_status = readLimits(); - if (rw_status != asynSuccess) { - return rw_status; + rwStatus = readLimits(); + if (rwStatus != asynSuccess) { + return rwStatus; } } @@ -770,16 +804,11 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { setAxisParamChecked(this, motorStatusDone, !(*moving)); setAxisParamChecked(this, motorStatusDirection, direction); - pl_status = setMotorPosition(currentPosition); - if (pl_status != asynSuccess) { - return pl_status; - } return poll_status; } -asynStatus masterMacsAxis::doMoveVelocity(double minVelocity, - double maxVelocity, - double acceleration) { +asynStatus masterMacsAxis::moveVelocity(double minVelocity, double maxVelocity, + double acceleration) { // Suppress unused variable warning (void)minVelocity; (void)acceleration; @@ -830,7 +859,14 @@ asynStatus masterMacsAxis::doMoveVelocity(double minVelocity, // Start the move. We do not use the MovTimeout watchdog here, because the // motor can move for any time in velocity mode. - return pC_->write(axisNo_, 00, "3", timeout); + status = pC_->write(axisNo_, 00, "3", timeout); + if (status != asynSuccess) { + return status; + } + + // Cache the information that the current movement is in velocity mode + pMasterMacsA_->lastMoveCommand = velocityMode; + return status; } asynStatus masterMacsAxis::doMove(double position, int relative, @@ -938,6 +974,8 @@ asynStatus masterMacsAxis::doMove(double position, int relative, return asynError; } + // Cache the information that the current movement is in position mode + pMasterMacsA_->lastMoveCommand = positionMode; return status; } @@ -1238,8 +1276,8 @@ asynStatus masterMacsAxis::readAxisStatus() { // ========================================================================= - asynStatus rw_status = pC_->read(axisNo_, 10, response); - if (rw_status == asynSuccess) { + asynStatus rwStatus = pC_->read(axisNo_, 10, response); + if (rwStatus == asynSuccess) { float axisStatus = 0; int nvals = sscanf(response, "%f", &axisStatus); @@ -1251,7 +1289,7 @@ asynStatus masterMacsAxis::readAxisStatus() { pMasterMacsA_->axisStatus = toBitset(axisStatus); } - return rw_status; + return rwStatus; } asynStatus masterMacsAxis::readAxisError() { @@ -1259,8 +1297,8 @@ asynStatus masterMacsAxis::readAxisError() { // ========================================================================= - asynStatus rw_status = pC_->read(axisNo_, 11, response); - if (rw_status == asynSuccess) { + asynStatus rwStatus = pC_->read(axisNo_, 11, response); + if (rwStatus == asynSuccess) { float axisError = 0; int nvals = sscanf(response, "%f", &axisError); @@ -1270,7 +1308,7 @@ asynStatus masterMacsAxis::readAxisError() { } pMasterMacsA_->axisError = toBitset(axisError); } - return rw_status; + return rwStatus; } bool masterMacsAxis::readyToBeSwitchedOn() { @@ -1297,6 +1335,8 @@ bool masterMacsAxis::remoteMode() { return pMasterMacsA_->axisStatus[9]; } bool masterMacsAxis::targetReached() { return pMasterMacsA_->axisStatus[10]; } +bool masterMacsAxis::speedEqualZero() { return pMasterMacsA_->axisStatus[12]; } + bool masterMacsAxis::internalLimitActive() { return pMasterMacsA_->axisStatus[11]; } diff --git a/src/masterMacsAxis.h b/src/masterMacsAxis.h index 13f1dc5..eff68cf 100644 --- a/src/masterMacsAxis.h +++ b/src/masterMacsAxis.h @@ -52,17 +52,15 @@ class HIDDEN masterMacsAxis : public sinqAxis { asynStatus doPoll(bool *moving); /** - * @brief Implementation of the `doMoveVelocity` function from sinqAxis. The - * parameters are described in the documentation of - * `sinqAxis::doMoveVelocity`. + * @brief TODO * * @param minVelocity * @param maxVelocity * @param acceleration * @return asynStatus */ - asynStatus doMoveVelocity(double minVelocity, double maxVelocity, - double acceleration); + asynStatus moveVelocity(double minVelocity, double maxVelocity, + double acceleration); /** * @brief Implementation of the `doMove` function from sinqAxis. The @@ -252,6 +250,12 @@ class HIDDEN masterMacsAxis : public sinqAxis { */ bool internalLimitActive(); + /** + * @brief Read the property from axisStatus (see masterMacsAxisImpl + * redefinition in masterMacsAxis.cpp) + */ + bool speedEqualZero(); + // Bits 12 and 13 are unused /**