From 2376e2adfd14a54234cffb3104f7125380196f0d Mon Sep 17 00:00:00 2001 From: smathis Date: Tue, 10 Feb 2026 08:10:56 +0100 Subject: [PATCH] Roll head back to 1.5.7 --- README.md | 43 ++++---------------------- db/sinqMotor.db | 34 -------------------- src/sinqAxis.cpp | 69 ++++++++--------------------------------- src/sinqAxis.h | 57 ++++------------------------------ src/sinqController.cpp | 70 ------------------------------------------ src/sinqController.h | 8 ++--- 6 files changed, 26 insertions(+), 255 deletions(-) diff --git a/README.md b/README.md index fb577bd..5613b84 100644 --- a/README.md +++ b/README.md @@ -117,11 +117,11 @@ does not matter): file "$(SINQDBPATH)" { pattern -{ AXIS, M, DESC, EGU, DIR, MRES, MSGTEXTSIZE, ENABLEMOVWATCHDOG, LIMITSOFFSET, CANSETSPEED, ADAPTPOLL, CANSETMODE } -{ 1, "lin1", "Linear motor doing whatever", mm, Pos, 0.001, 200, 1, 1.0, 1, 1, 0 } -{ 2, "rot1", "First rotary motor", degree, Neg, 0.001, 200, 0, 1.0, 0, 1, 0 } -{ 3, "rot2", "Second rotary motor", degree, Pos, 0.001, 200, 0, 0.0, 1, 0, 0 } -{ 5, "rot3", "Surprise: Third rotary motor", degree, Pos, 0.001, 200, 1, 2.0, 0, 0, 1 } +{ AXIS, M, DESC, EGU, DIR, MRES, MSGTEXTSIZE, ENABLEMOVWATCHDOG, LIMITSOFFSET, CANSETSPEED, ADAPTPOLL } +{ 1, "lin1", "Linear motor doing whatever", mm, Pos, 0.001, 200, 1, 1.0, 1, 1 } +{ 2, "rot1", "First rotary motor", degree, Neg, 0.001, 200, 0, 1.0, 0, 1 } +{ 3, "rot2", "Second rotary motor", degree, Pos, 0.001, 200, 0, 0.0, 1, 0 } +{ 5, "rot3", "Surprise: Third rotary motor", degree, Pos, 0.001, 200, 1, 2.0, 0, 0 } } ``` The variable `SINQDBPATH` has been set in "mcu1.cmd" before calling `dbLoadTemplate`. @@ -166,9 +166,6 @@ behaviour so that the affected axis is only polled with the busy / moving poll period if it itself is moving. This setting is ignored for "forced fast polls" (when the poller is woken up, e.g. after an axis received a move command). Defaults to 1. -- `CANSETMODE`: If set to any value other than 0, the operation mode of the -motor can be changed. See section [Velocity mode](#velocity-mode). - ### Motor record resolution MRES @@ -215,29 +212,6 @@ transferred to (motor_record_pv_name).MRES or to `sinqMotor` provides a variety of additional records. See `db/sinqMotor.db` for the complete list and the documentation. -### Velocity mode - -The motor record was originally designed for motors which operate in _position_ -mode: They are given a certain position, move to that position and then stop -on their own. Some motors however operate in a continuous _velocity_ mode, where -they move (usually rotate) with a fixed velocity until told to stop or change -the velocity. To support this operation mode, `sinqMotor` provides three -additional records: - -- `$(INSTR)$(M):Mode`: This read-only record returns 0 if the motor is in -position mode and 1 if it is in velocity mode. Defaults to 0. -- `$(INSTR)$(M):CanSetMode`: If the value of this record is other than zero, the -motor mode can be changed during operation. Defaults to 0, but can be -overwritten in the substitution file with `CANSETMODE` or from within the driver -(e.g. by reading out a parameter from the hardware). -- `$(INSTR)$(M):SetMode`: This record can be used to switch between operation -modes if `$(INSTR)$(M):CanSetMode` is not zero. Currently accepted values are -`0` for position mode and `1` for velocity mode. - -When in velocity mode, writing to the `VELO` field of the motor record directly -triggers the corresponding velocity change if the driver supports it. Writing -to the `VAL` field does nothing in velocity mode. - ## Developer guide ### File structure @@ -277,10 +251,7 @@ This is an empty function which should be overwritten by concrete driver impleme - `reset`: This function is called when the `$(INSTR)$(M):Reset` PV from `db/sinqMotor.db` is set. It calls `doReset` and performs some fast polls after `doReset` returns. - `doReset`: This is an empty function which should be overwritten by concrete driver implementations. -- `moveVelocity`: This function checks if the motor is in velocity mode. If that is the case, it calls `doMoveVelocity`. -- `doMoveVelocity`: This is an empty function which should be overwritten by concrete driver implementations. -- `move`: This function checks if the motor is in position mode. If that is the -case, it then sets the absolute target position in the parameter library and then calls `doMove`. +- `move`: This function sets the absolute target position in the parameter library and then calls `doMove`. - `doMove`: This is an empty function which should be overwritten by concrete driver implementations. - `home`: This function sets the internal status flags for the homing process and then calls doHome. - `doHome`: This is an empty function which should be overwritten by concrete driver implementations. @@ -331,8 +302,6 @@ available in the IOC shell. This function is also available in the IOC shell. - `setScaleMovTimeout`: Set a scaling factor for the expected movement time. This function is also available in the IOC shell. -- `setMode`: This is an empty function which should be overwritten by concrete -driver implementations. #### msgPrintControl.h In addition to the two extension classes this library also includes a mechanism diff --git a/db/sinqMotor.db b/db/sinqMotor.db index 35d2977..011f76c 100755 --- a/db/sinqMotor.db +++ b/db/sinqMotor.db @@ -347,37 +347,3 @@ record(waveform, "$(INSTR)$(M):EncoderType") { field(NELM, "80") field(SCAN, "I/O Intr") } - -# Motors can operate either in position mode (0) or velocity mode (1). If the -# mode is stored within the controller, the driver writes the corresponding mode -# value into this record. If not, motors are always assumed to operate in -# position mode. -record(longin, "$(INSTR)$(M):Mode") -{ - field(DTYP, "asynInt32") - field(INP, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_MODE") - field(SCAN, "I/O Intr") - field(PINI, "NO") - field(VAL, "0") -} - -# Motors can operate either in position mode (0) or velocity mode (1). If it is -# possible to switch between the two, this record has a value of 1, otherwise -# its value is 0. -record(longin, "$(INSTR)$(M):CanSetMode") -{ - field(DTYP, "asynInt32") - field(INP, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_CAN_SET_MODE") - field(SCAN, "I/O Intr") - field(PINI, "NO") - field(VAL, "$(CANSETMODE=0)") -} - -# Set the operation mode of the motor to position mode (0) or velocity mode (1). -# If CanSetMode is 0, the mode cannot be changed and writing to this record -# will have no effect. -record(longout, "$(INSTR)$(M):SetMode") { - field(DTYP, "asynInt32") - field(OUT, "@asyn($(CONTROLLER),$(AXIS),1) MOTOR_SET_MODE") - field(PINI, "NO") -} \ No newline at end of file diff --git a/src/sinqAxis.cpp b/src/sinqAxis.cpp index 3247db0..46111cc 100644 --- a/src/sinqAxis.cpp +++ b/src/sinqAxis.cpp @@ -245,10 +245,6 @@ asynStatus sinqAxis::forcedPoll(bool *moving) { // Clear the communication setAxisParamChecked(this, motorStatusCommsError, false); - // Assume the motor is initially connected. During the poll, this value will - // be set to false if the motor is not connected. - setAxisParamChecked(this, motorConnected, true); - /* The poll function is just a wrapper around doPoll and handles mainly the callParamCallbacks() function. This wrapper is used to make sure @@ -256,11 +252,6 @@ asynStatus sinqAxis::forcedPoll(bool *moving) { */ poll_status = doPoll(moving); - // Motor is not connected - if (poll_status == asynDisconnected) { - setAxisParamChecked(this, motorConnected, false); - } - /* If the poll did not succeed OR if an error message is waiting, something went wrong and the motor has a status problem. Otherwise, delete the error @@ -342,49 +333,18 @@ asynStatus sinqAxis::doPoll(bool *moving) { return asynSuccess; } -asynStatus sinqAxis::moveVelocity(double minVelocity, double maxVelocity, - double acceleration) { - - int motMode = 0; - - // If the motor is not in velocity mode, do nothing - getAxisParamChecked(this, motorMode, &motMode); - if (motMode != 0) { - return asynSuccess; - } - - return doMoveVelocity(minVelocity, maxVelocity, acceleration); -} - -asynStatus sinqAxis::doMoveVelocity(double minVelocity, double maxVelocity, - double acceleration) { - // Suppress unused variable warning - this is just a default fallback - // function. - (void)minVelocity; - (void)maxVelocity; - (void)acceleration; - return asynSuccess; -} - asynStatus sinqAxis::move(double position, int relative, double minVelocity, double maxVelocity, double acceleration) { // Status of parameter library operations asynStatus status = asynSuccess; - double motRecRes = 0.0; - int motMode = 0; + double motorRecRes = 0.0; // ========================================================================= - // If the motor is not in position mode, do nothing - getAxisParamChecked(this, motorMode, &motMode); - if (motMode != 0) { - return asynSuccess; - } - // Store the target position internally - getAxisParamChecked(this, motorRecResolution, &motRecRes); - pSinqA_->targetPosition = position * motRecRes; + getAxisParamChecked(this, motorRecResolution, &motorRecRes); + pSinqA_->targetPosition = position * motorRecRes; status = doMove(position, relative, minVelocity, maxVelocity, acceleration); if (status != asynSuccess) { @@ -495,9 +455,9 @@ asynStatus sinqAxis::enable(bool on) { asynStatus sinqAxis::motorPosition(double *motorPos) { asynStatus status = asynSuccess; - double motRecRes = 0.0; + double motorRecRes = 0.0; - getAxisParamChecked(this, motorRecResolution, &motRecRes); + getAxisParamChecked(this, motorRecResolution, &motorRecRes); /* We cannot use getAxisParamChecked checked here, since the name of the index @@ -510,16 +470,16 @@ asynStatus sinqAxis::motorPosition(double *motorPos) { __PRETTY_FUNCTION__, __LINE__); } - *motorPos = *motorPos * motRecRes; + *motorPos = *motorPos * motorRecRes; return status; } asynStatus sinqAxis::setMotorPosition(double motorPos) { asynStatus status = asynSuccess; - double motRecRes = 0.0; + double motorRecRes = 0.0; - getAxisParamChecked(this, motorRecResolution, &motRecRes); - setAxisParamChecked(this, motorPosition, motorPos / motRecRes); + getAxisParamChecked(this, motorRecResolution, &motorRecRes); + setAxisParamChecked(this, motorPosition, motorPos / motorRecRes); return status; } @@ -613,7 +573,7 @@ asynStatus sinqAxis::startMovTimeoutWatchdog() { double motorVelocityRec = 0.0; double motorAccel = 0.0; double motorAccelRec = 0.0; - double motRecRes = 0.0; + double motorRecRes = 0.0; time_t timeContSpeed = 0; time_t timeAccel = 0; @@ -642,7 +602,7 @@ asynStatus sinqAxis::startMovTimeoutWatchdog() { = VELO / MRES motorAccel = (motorVelocity - motorVelBase) / ACCL Therefore, we need to correct the values from the parameter library. */ - getAxisParamChecked(this, motorRecResolution, &motRecRes); + getAxisParamChecked(this, motorRecResolution, &motorRecRes); // Read the velocity getAxisParamChecked(this, motorVelocity, &motorVelocityRec); @@ -651,7 +611,7 @@ asynStatus sinqAxis::startMovTimeoutWatchdog() { // with a sensible value (e.g. > 0) if (pl_status == asynSuccess && motorVelocityRec > 0.0) { // Convert back to the value in the VELO field - motorVelocity = motorVelocityRec * motRecRes; + motorVelocity = motorVelocityRec * motorRecRes; if (pl_status == asynSuccess) { timeContSpeed = @@ -741,11 +701,6 @@ void sinqAxis::setTargetPosition(double targetPosition) { pSinqA_->targetPosition = targetPosition; } -asynStatus sinqAxis::setMode(int mode) { - (void)mode; - return asynSuccess; -} - // ============================================================================= // IOC shell functions extern "C" { diff --git a/src/sinqAxis.h b/src/sinqAxis.h index f9adaa7..212334f 100644 --- a/src/sinqAxis.h +++ b/src/sinqAxis.h @@ -107,46 +107,14 @@ class HIDDEN sinqAxis : public asynMotorAxis { */ virtual asynStatus doPoll(bool *moving); - /** - * @brief Perform some standardized operations before and after the concrete - `doMoveVelocity` implementation. - - * Wrapper around `doMoveVelocity` which checks if the motor is in velocity - mode. If that is the case, it, it calls and returns `doMoveVelocity`. - Otherwise, it just returns `asynSuccess`. - * - * @param minVelocity Forwarded to `doMoveVelocity`. - * @param maxVelocity Forwarded to `doMoveVelocity`. - * @param acceleration Forwarded to `doMoveVelocity`. - * @return asynStatus Forward the status of `doMove`, unless one of - the parameter library operation fails (in that case, returns the failed - operation status). - */ - virtual asynStatus moveVelocity(double minVelocity, double maxVelocity, - double acceleration); - - /** - * @brief Implementation of the "proper", device-specific move method. This - method should be implemented by a child class of sinqAxis. - * - * @param minVelocity Minimum velocity VBAS from the motor record - * @param maxVelocity Actual velocity VELO from the motor record - (yes, this is named badly. This is not VMAX!) - * @param acceleration Acceleration ACCEL from the motor record - * @return asynStatus - */ - virtual asynStatus doMoveVelocity(double minVelocity, double maxVelocity, - double acceleration); - /** * @brief Perform some standardized operations before and after the concrete `doMove` implementation. - * Wrapper around `doMove` which checks if the motor is in position - mode. If that is the case, the function calculates the (absolute) target - position and stores it in the member variable `targetPosition_`. This member - variable is e.g. used for the movement watchdog. Afterwards, it calls and - returns `doMove`. Otherwise, it just returns `asynSuccess`. + * Wrapper around `doMove` which calculates the (absolute) target position + and stores it in the member variable `targetPosition_`. This member variable + is e.g. used for the movement watchdog. Afterwards, it calls and returns + `doMove`. * * @param position Forwarded to `doMove`. * @param relative Forwarded to `doMove`. @@ -167,9 +135,8 @@ class HIDDEN sinqAxis : public asynMotorAxis { * @param position Target position `VAL` from the motor record * @param relative Specifies, whether the target position is relative or absolute. - * @param minVelocity Minimum velocity VBAS from the motor record - * @param maxVelocity Actual velocity VELO from the motor record - (yes, this is named badly. This is not VMAX!) + * @param minVelocity Minimum velocity VMIN from the motor record + * @param maxVelocity Maximum velocity VMAX from the motor record * @param acceleration Acceleration ACCEL from the motor record * @return asynStatus */ @@ -434,18 +401,6 @@ class HIDDEN sinqAxis : public asynMotorAxis { */ asynStatus assertConnected(); - /** - * @brief Set the operation mode (position or velocity) of the axis. It - * should be implemented by a child class of sinqAxis. - * - * This function is called from within sinqController::writeInt32 if a new - * operation mode has been set. - * - * @param mode: New operation mode. 0 is position mode, 1 is velocity mode. - * @return asynStatus - */ - virtual asynStatus setMode(int mode); - /** * @brief Return a pointer to the axis controller. * diff --git a/src/sinqController.cpp b/src/sinqController.cpp index 09f530b..03f4324 100644 --- a/src/sinqController.cpp +++ b/src/sinqController.cpp @@ -100,9 +100,6 @@ struct sinqControllerImpl { int motorHighLimitFromDriver; int motorLowLimitFromDriver; int motorPositionDeadband; - int motorMode; - int motorCanSetMode; - int motorSetMode; int adaptivePolling; int encoderType; }; @@ -150,9 +147,6 @@ sinqController::sinqController(const char *portName, .motorHighLimitFromDriver = 0, .motorLowLimitFromDriver = 0, .motorPositionDeadband = 0, - .motorMode = 0, - .motorCanSetMode = 0, - .motorSetMode = 0, .adaptivePolling = 0, .encoderType = 0, })) { @@ -396,38 +390,6 @@ sinqController::sinqController(const char *portName, exit(-1); } - status = createParam("MOTOR_MODE", asynParamInt32, &pSinqC_->motorMode); - if (status != asynSuccess) { - asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, - "Controller \"%s\" => %s, line %d:\nFATAL ERROR (creating a " - "parameter failed with %s).\nTerminating IOC", - portName, __PRETTY_FUNCTION__, __LINE__, - stringifyAsynStatus(status)); - exit(-1); - } - - status = createParam("MOTOR_CAN_SET_MODE", asynParamInt32, - &pSinqC_->motorCanSetMode); - if (status != asynSuccess) { - asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, - "Controller \"%s\" => %s, line %d:\nFATAL ERROR (creating a " - "parameter failed with %s).\nTerminating IOC", - portName, __PRETTY_FUNCTION__, __LINE__, - stringifyAsynStatus(status)); - exit(-1); - } - - status = - createParam("MOTOR_SET_MODE", asynParamInt32, &pSinqC_->motorSetMode); - if (status != asynSuccess) { - asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, - "Controller \"%s\" => %s, line %d:\nFATAL ERROR (creating a " - "parameter failed with %s).\nTerminating IOC", - portName, __PRETTY_FUNCTION__, __LINE__, - stringifyAsynStatus(status)); - exit(-1); - } - // Register the hook function during construction of the first axis object if (controller.empty()) { initHookRegister(&epicsInithookFunction); @@ -493,35 +455,6 @@ asynStatus sinqController::writeInt32(asynUser *pasynUser, epicsInt32 value) { return axis->reset(); } else if (function == motorForceStop()) { return axis->stop(0.0); - } else if (function == motorSetMode()) { - // Check if it is allowed to set the mode - int canSetMode = 0; - getAxisParamChecked(axis, motorCanSetMode, &canSetMode); - if (canSetMode == 0) { - int axisNo; - getAddress(pasynUser, &axisNo); - asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, - "Controller \"%s\", axis %d => %s, line %d:\ncannot " - "change operation mode of the motor", - portName, axisNo, __PRETTY_FUNCTION__, __LINE__); - return asynError; - } else { - // Check if the given value is valid (i.e. 0 for position mode or 1 - // for velocity mode): - if (value == 0 || value == 1) { - setAxisParamChecked(axis, motorMode, value); - return axis->setMode(value); - } else { - int axisNo; - getAddress(pasynUser, &axisNo); - asynPrint( - this->pasynUserSelf, ASYN_TRACE_ERROR, - "Controller \"%s\", axis %d => %s, line %d:\n given motor " - "mode must be 0 (position mode) or 1 (velocity mode).", - portName, axisNo, __PRETTY_FUNCTION__, __LINE__); - return asynError; - } - } } else { return asynMotorController::writeInt32(pasynUser, value); } @@ -809,9 +742,6 @@ int sinqController::motorLowLimitFromDriver() { int sinqController::motorPositionDeadband() { return pSinqC_->motorPositionDeadband; } -int sinqController::motorMode() { return pSinqC_->motorMode; } -int sinqController::motorCanSetMode() { return pSinqC_->motorCanSetMode; } -int sinqController::motorSetMode() { return pSinqC_->motorSetMode; } int sinqController::adaptivePolling() { return pSinqC_->adaptivePolling; } int sinqController::encoderType() { return pSinqC_->encoderType; } diff --git a/src/sinqController.h b/src/sinqController.h index ebac70b..022c738 100644 --- a/src/sinqController.h +++ b/src/sinqController.h @@ -76,8 +76,7 @@ class HIDDEN sinqController : public asynMotorController { /** * @brief Overloaded function of asynMotorController * - * The function is overloaded to allow enabling / disabling the motor and - * setting the operation mode of the motor. + * The function is overloaded to allow enabling / disabling the motor. * * @param pasynUser Specify the axis via the asynUser * @param value New value @@ -314,7 +313,7 @@ class HIDDEN sinqController : public asynMotorController { int motorRecOffset() { return motorRecOffset_; } // Accessors for additional PVs defined in sinqController (which are hidden - // behind pSinqC_) + // in pSinqC_) int motorMessageText(); int motorReset(); int motorEnable(); @@ -332,9 +331,6 @@ class HIDDEN sinqController : public asynMotorController { int motorHighLimitFromDriver(); int motorLowLimitFromDriver(); int motorPositionDeadband(); - int motorMode(); - int motorCanSetMode(); - int motorSetMode(); int adaptivePolling(); int encoderType();