diff --git a/README.md b/README.md index 015eee8..e410191 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,10 @@ coupling, changes to the parameter library via setDoubleParam are NOT transferred to (motor_record_pv_name).MRES or to (motor_record_pv_name):Resolution. +### Additional records + +`sinqMotor` provides a variety of additional records. See `db/sinqMotor.db` for the complete list and the documentation. + ## Developer guide ### Base classes diff --git a/db/sinqMotor.db b/db/sinqMotor.db index b074118..6016a27 100755 --- a/db/sinqMotor.db +++ b/db/sinqMotor.db @@ -34,6 +34,8 @@ record(motor,"$(INSTR)$(M)") field(EGU,"$(EGU)") field(INIT,"") field(PINI,"NO") + field(DHLM, "$(DHLM=0)") + field(DLLM, "$(DLLM=0)") field(TWV,"1") field(RTRY,"0") field(RDBD,"0") @@ -189,11 +191,13 @@ record(ai, "$(INSTR)$(M):DHLM_RBV") field(INP, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_HIGH_LIMIT_FROM_DRIVER") field(SCAN, "I/O Intr") field(FLNK, "$(INSTR)$(M):PushDHLM2Field") + field(PINI, "NO") } record(ao, "$(INSTR)$(M):PushDHLM2Field") { field(DOL, "$(INSTR)$(M):DHLM_RBV NPP") field(OUT, "$(INSTR)$(M).DHLM") field(OMSL, "closed_loop") + field(PINI, "NO") } # This record pair reads the parameter library value for "motorLowLimitFromDriver_" @@ -208,11 +212,13 @@ record(ai, "$(INSTR)$(M):DLLM_RBV") field(INP, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_LOW_LIMIT_FROM_DRIVER") field(SCAN, "I/O Intr") field(FLNK, "$(INSTR)$(M):PushDLLM2Field") + field(PINI, "NO") } record(ao, "$(INSTR)$(M):PushDLLM2Field") { field(DOL, "$(INSTR)$(M):DLLM_RBV NPP") field(OUT, "$(INSTR)$(M).DLLM") field(OMSL, "closed_loop") + field(PINI, "NO") } # This record pair reads the parameter library value for "motorVeloFromDriver_" diff --git a/src/sinqAxis.cpp b/src/sinqAxis.cpp index c925217..bb9c045 100644 --- a/src/sinqAxis.cpp +++ b/src/sinqAxis.cpp @@ -14,6 +14,7 @@ sinqAxis::sinqAxis(class sinqController *pC, int axisNo) scaleMovTimeout_ = 2.0; offsetMovTimeout_ = 30; targetPosition_ = 0.0; + wasMoving_ = false; epicsTimeGetCurrent(&lastPollTime_); @@ -22,7 +23,7 @@ sinqAxis::sinqAxis(class sinqController *pC, int axisNo) // check, the IOC is stopped, since this is definitely a configuration // problem. if ((axisNo < 0) || (axisNo >= pC->numAxes())) { - asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR, + asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR " "(axis index %d is not in range 0 to %d)\n. Terminating IOC", pC->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo, @@ -33,7 +34,7 @@ sinqAxis::sinqAxis(class sinqController *pC, int axisNo) // Motor is assumed to be enabled status = setIntegerParam(pC_->motorEnableRBV(), 1); if (status != asynSuccess) { - asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR, + asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR " "(setting a parameter value failed " "with %s)\n. Terminating IOC", @@ -45,7 +46,7 @@ sinqAxis::sinqAxis(class sinqController *pC, int axisNo) // By default, motors cannot be disabled status = setIntegerParam(pC_->motorCanDisable(), 0); if (status != asynSuccess) { - asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR, + asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR " "(setting a parameter value failed " "with %s)\n. Terminating IOC", @@ -57,7 +58,7 @@ sinqAxis::sinqAxis(class sinqController *pC, int axisNo) // Provide a default value for the motor position. status = setDoubleParam(pC_->motorPosition(), 0.0); if (status != asynSuccess) { - asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR, + asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR " "(setting a parameter value failed " "with %s)\n. Terminating IOC", @@ -69,7 +70,7 @@ sinqAxis::sinqAxis(class sinqController *pC, int axisNo) // We assume that the motor has no status problems initially status = setIntegerParam(pC_->motorStatusProblem(), 0); if (status != asynSuccess) { - asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR, + asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR " "(setting a parameter value failed " "with %s)\n. Terminating IOC", @@ -81,7 +82,7 @@ sinqAxis::sinqAxis(class sinqController *pC, int axisNo) // Set the homing-related flags status = setIntegerParam(pC_->motorStatusHome(), 0); if (status != asynSuccess) { - asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR, + asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR " "(setting a parameter value failed " "with %s)\n. Terminating IOC", @@ -91,7 +92,7 @@ sinqAxis::sinqAxis(class sinqController *pC, int axisNo) } status = setIntegerParam(pC_->motorStatusHomed(), 0); if (status != asynSuccess) { - asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR, + asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR " "(setting a parameter value failed " "with %s)\n. Terminating IOC", @@ -101,7 +102,7 @@ sinqAxis::sinqAxis(class sinqController *pC, int axisNo) } status = setIntegerParam(pC_->motorStatusAtHome(), 0); if (status != asynSuccess) { - asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR, + asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR " "(setting a parameter value failed " "with %s)\n. Terminating IOC", @@ -144,12 +145,13 @@ asynStatus sinqAxis::poll(bool *moving) { if (adaptivePolling != 0) { // Motor wasn't moving during the last poll - if (getWasMovingFlag() == 0) { + if (!wasMoving_) { // Add the idle poll period epicsTimeStamp earliestTimeNextPoll = lastPollTime_; epicsTimeAddSeconds(&earliestTimeNextPoll, pC_->idlePollPeriod()); - if (epicsTimeLessThan(&earliestTimeNextPoll, &ts) == 1) { + + if (epicsTimeLessThanEqual(&earliestTimeNextPoll, &ts) == 0) { *moving = false; return asynSuccess; } @@ -188,6 +190,9 @@ asynStatus sinqAxis::poll(bool *moving) { // return. poll_status = doPoll(moving); + // Motor was moving during this poll + wasMoving_ = *moving; + // The poll did not succeed: Something went wrong and the motor has a status // problem. if (poll_status != asynSuccess) { @@ -244,8 +249,8 @@ asynStatus sinqAxis::poll(bool *moving) { bool wantToPrint = pl_status != asynSuccess; if (pC_->getMsgPrintControl().shouldBePrinted( pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, wantToPrint, - pC_->asynUserSelf())) { - asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR, + pC_->pasynUser())) { + asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line " "%d:\ncallParamCallbacks failed with %s.%s\n", pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, @@ -298,7 +303,7 @@ asynStatus sinqAxis::move(double position, int relative, double minVelocity, } // Needed for adaptive polling - setWasMovingFlag(1); + wasMoving_ = true; return pC_->callParamCallbacks(); } @@ -453,7 +458,7 @@ asynStatus sinqAxis::setVeloFields(double velo, double vbas, double vmax) { // Check the inputs and create corresponding error messages if (vbas > vmax) { - asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR, + asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line %d:\nLower speed " "limit vbas=%lf must not be smaller than upper limit " "vmax=%lf.\n", @@ -471,7 +476,7 @@ asynStatus sinqAxis::setVeloFields(double velo, double vbas, double vmax) { return asynError; } if (velo < vbas || velo > vmax) { - asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR, + asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line %d:\nActual " "speed velo=%lf must be between lower limit vbas=%lf and " "upper limit vmax=%lf.\n", @@ -668,7 +673,7 @@ asynStatus sinqAxis::checkMovTimeoutWatchdog(bool moving) { // Check if the expected time of arrival has been exceeded. if (expectedArrivalTime_ < time(NULL)) { // Check the watchdog - asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR, + asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line %d:\nExceeded " "expected arrival time %ld (current time is %ld).\n", pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, diff --git a/src/sinqAxis.h b/src/sinqAxis.h index 16fa710..56f141e 100644 --- a/src/sinqAxis.h +++ b/src/sinqAxis.h @@ -357,6 +357,8 @@ class epicsShareClass sinqAxis : public asynMotorAxis { bool watchdogMovActive_; // Store the motor target position for the movement time calculation double targetPosition_; + + bool wasMoving_; /* Store the time since the last poll diff --git a/src/sinqController.h b/src/sinqController.h index b9a0b42..ef88351 100644 --- a/src/sinqController.h +++ b/src/sinqController.h @@ -298,7 +298,19 @@ class epicsShareClass sinqController : public asynMotorController { int numAxes() { return numAxes_; } double idlePollPeriod() { return idlePollPeriod_; } double movingPollPeriod() { return movingPollPeriod_; } - asynUser *asynUserSelf() { return pasynUserSelf; } + + /** + * @brief Return a pointer to the asynUser of the controller + * + * @return asynUser* + */ + asynUser *pasynUser() { return pasynUserSelf; } + + /** + * @brief Return a pointer to the low-level octet (string) IP Port + * + * @return asynUser* + */ asynUser *pasynOctetSyncIOipPort() { return pasynOctetSyncIOipPort_; } // =========================================================================