Applied PIMPL by moving members to internal struct sinqAxisImpl
This change makes sinqMotor ready for 1.x releases where ABI stability and backwards compatibility is guaranteed.
This commit is contained in:
+60
-25
@@ -3,11 +3,31 @@
|
||||
#include "sinqAxis.h"
|
||||
#include "epicsExport.h"
|
||||
#include "iocsh.h"
|
||||
#include "msgPrintControl.h"
|
||||
#include "sinqController.h"
|
||||
#include <epicsTime.h>
|
||||
#include <errlog.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct sinqAxisImpl {
|
||||
// Internal variables used in the movement timeout watchdog
|
||||
time_t expectedArrivalTime;
|
||||
time_t offsetMovTimeout;
|
||||
|
||||
double scaleMovTimeout;
|
||||
bool watchdogMovActive;
|
||||
// Store the motor target position for the movement time calculation
|
||||
double targetPosition;
|
||||
|
||||
bool wasMoving;
|
||||
|
||||
/*
|
||||
Store the time since the last poll
|
||||
*/
|
||||
epicsTimeStamp lastPollTime;
|
||||
};
|
||||
|
||||
// Generic fallback - if the compiler tries to compile this function, it fails.
|
||||
template <typename T>
|
||||
asynStatus setAxisParam(sinqAxis *axis, const char *indexName,
|
||||
@@ -184,13 +204,17 @@ sinqAxis::sinqAxis(class sinqController *pC, int axisNo)
|
||||
: asynMotorAxis((asynMotorController *)pC, axisNo), pC_(pC) {
|
||||
asynStatus status = asynSuccess;
|
||||
|
||||
watchdogMovActive_ = false;
|
||||
scaleMovTimeout_ = 2.0;
|
||||
offsetMovTimeout_ = 30;
|
||||
targetPosition_ = 0.0;
|
||||
wasMoving_ = false;
|
||||
epicsTimeStamp lastPollTime;
|
||||
epicsTimeGetCurrent(&lastPollTime);
|
||||
|
||||
epicsTimeGetCurrent(&lastPollTime_);
|
||||
pSinqA_ = std::make_unique<sinqAxisImpl>(
|
||||
(sinqAxisImpl){.expectedArrivalTime = 0,
|
||||
.offsetMovTimeout = 30,
|
||||
.scaleMovTimeout = 2.0,
|
||||
.watchdogMovActive = false,
|
||||
.targetPosition = 0.0,
|
||||
.wasMoving = false,
|
||||
.lastPollTime = lastPollTime});
|
||||
|
||||
// This check is also done in asynMotorAxis, but there the IOC continues
|
||||
// running even though the configuration is incorrect. When failing this
|
||||
@@ -346,10 +370,10 @@ asynStatus sinqAxis::poll(bool *moving) {
|
||||
*/
|
||||
if (adaptivePolling != 0 && pC_->outstandingForcedFastPolls() == 0) {
|
||||
// Motor wasn't moving during the last poll
|
||||
if (!wasMoving_) {
|
||||
if (!pSinqA_->wasMoving) {
|
||||
|
||||
// Add the idle poll period
|
||||
epicsTimeStamp earliestTimeNextPoll = lastPollTime_;
|
||||
epicsTimeStamp earliestTimeNextPoll = pSinqA_->lastPollTime;
|
||||
epicsTimeAddSeconds(&earliestTimeNextPoll, pC_->idlePollPeriod());
|
||||
|
||||
if (epicsTimeLessThanEqual(&earliestTimeNextPoll, &ts) == 0) {
|
||||
@@ -360,7 +384,7 @@ asynStatus sinqAxis::poll(bool *moving) {
|
||||
}
|
||||
|
||||
// Update the start time of the last poll
|
||||
lastPollTime_ = ts;
|
||||
pSinqA_->lastPollTime = ts;
|
||||
|
||||
/*
|
||||
If the "motorMessageText" record currently contains an error message, it
|
||||
@@ -411,7 +435,7 @@ asynStatus sinqAxis::poll(bool *moving) {
|
||||
assumed that the homing procedure is done.
|
||||
*/
|
||||
getAxisParamChecked(this, motorStatusHome, &homing);
|
||||
if (homing == 1 && !(*moving) && wasMoving_) {
|
||||
if (homing == 1 && !(*moving) && pSinqA_->wasMoving) {
|
||||
setAxisParamChecked(this, motorStatusHome, false);
|
||||
setAxisParamChecked(this, motorStatusHomed, true);
|
||||
setAxisParamChecked(this, motorStatusAtHome, true);
|
||||
@@ -419,7 +443,7 @@ asynStatus sinqAxis::poll(bool *moving) {
|
||||
|
||||
// Update the wasMoving status
|
||||
if (pC_->outstandingForcedFastPolls() == 0) {
|
||||
wasMoving_ = *moving;
|
||||
pSinqA_->wasMoving = *moving;
|
||||
}
|
||||
|
||||
// Check and update the watchdog
|
||||
@@ -467,7 +491,7 @@ asynStatus sinqAxis::move(double position, int relative, double minVelocity,
|
||||
|
||||
// Store the target position internally
|
||||
getAxisParamChecked(this, motorRecResolution, &motorRecRes);
|
||||
targetPosition_ = position * motorRecRes;
|
||||
pSinqA_->targetPosition = position * motorRecRes;
|
||||
|
||||
status = doMove(position, relative, minVelocity, maxVelocity, acceleration);
|
||||
if (status != asynSuccess) {
|
||||
@@ -485,7 +509,7 @@ asynStatus sinqAxis::move(double position, int relative, double minVelocity,
|
||||
setAxisParamChecked(this, motorStatusAtHome, false);
|
||||
|
||||
// Needed for adaptive polling
|
||||
wasMoving_ = true;
|
||||
pSinqA_->wasMoving = true;
|
||||
|
||||
return pC_->callParamCallbacks();
|
||||
}
|
||||
@@ -507,7 +531,7 @@ asynStatus sinqAxis::home(double minVelocity, double maxVelocity,
|
||||
setAxisParamChecked(this, motorStatusHome, true);
|
||||
setAxisParamChecked(this, motorStatusHomed, false);
|
||||
setAxisParamChecked(this, motorStatusAtHome, false);
|
||||
wasMoving_ = true;
|
||||
pSinqA_->wasMoving = true;
|
||||
|
||||
status = assertConnected();
|
||||
if (status != asynSuccess) {
|
||||
@@ -681,7 +705,7 @@ asynStatus sinqAxis::startMovTimeoutWatchdog() {
|
||||
time_t timeAccel = 0;
|
||||
|
||||
// Activate the watchdog
|
||||
watchdogMovActive_ = true;
|
||||
pSinqA_->watchdogMovActive = true;
|
||||
|
||||
/*
|
||||
NOTE: This function must not be called in the constructor (e.g. in order
|
||||
@@ -717,8 +741,9 @@ asynStatus sinqAxis::startMovTimeoutWatchdog() {
|
||||
motorVelocity = motorVelocityRec * motorRecRes;
|
||||
if (pl_status == asynSuccess) {
|
||||
|
||||
timeContSpeed = std::ceil(
|
||||
std::fabs(targetPosition_ - motorPos) / motorVelocity);
|
||||
timeContSpeed =
|
||||
std::ceil(std::fabs(pSinqA_->targetPosition - motorPos) /
|
||||
motorVelocity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -734,11 +759,11 @@ asynStatus sinqAxis::startMovTimeoutWatchdog() {
|
||||
}
|
||||
|
||||
// Calculate the expected arrival time
|
||||
expectedArrivalTime_ =
|
||||
time(NULL) + offsetMovTimeout_ +
|
||||
scaleMovTimeout_ * (timeContSpeed + 2 * timeAccel);
|
||||
pSinqA_->expectedArrivalTime =
|
||||
time(NULL) + pSinqA_->offsetMovTimeout +
|
||||
pSinqA_->scaleMovTimeout * (timeContSpeed + 2 * timeAccel);
|
||||
} else {
|
||||
watchdogMovActive_ = false;
|
||||
pSinqA_->watchdogMovActive = false;
|
||||
}
|
||||
return asynSuccess;
|
||||
}
|
||||
@@ -749,8 +774,8 @@ asynStatus sinqAxis::checkMovTimeoutWatchdog(bool moving) {
|
||||
getAxisParamChecked(this, motorEnableMovWatchdog, &enableMovWatchdog);
|
||||
|
||||
// Not moving or watchdog not active / enabled
|
||||
if (enableMovWatchdog == 0 || !moving || !watchdogMovActive_) {
|
||||
watchdogMovActive_ = false;
|
||||
if (enableMovWatchdog == 0 || !moving || !pSinqA_->watchdogMovActive) {
|
||||
pSinqA_->watchdogMovActive = false;
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
@@ -760,7 +785,7 @@ asynStatus sinqAxis::checkMovTimeoutWatchdog(bool moving) {
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
|
||||
// Check if the expected time of arrival has been exceeded.
|
||||
if (expectedArrivalTime_ < time(NULL)) {
|
||||
if (pSinqA_->expectedArrivalTime < time(NULL)) {
|
||||
// Check the watchdog
|
||||
if (pC_->getMsgPrintControl().shouldBePrinted(key, true,
|
||||
pC_->pasynUser())) {
|
||||
@@ -768,7 +793,7 @@ asynStatus sinqAxis::checkMovTimeoutWatchdog(bool moving) {
|
||||
"Controller \"%s\", axis %d => %s, line %d:\nExceeded "
|
||||
"expected arrival time %ld (current time is %ld).\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
expectedArrivalTime_, time(NULL));
|
||||
pSinqA_->expectedArrivalTime, time(NULL));
|
||||
}
|
||||
|
||||
setAxisParamChecked(
|
||||
@@ -783,6 +808,16 @@ asynStatus sinqAxis::checkMovTimeoutWatchdog(bool moving) {
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
asynStatus sinqAxis::setOffsetMovTimeout(time_t offsetMovTimeout) {
|
||||
pSinqA_->offsetMovTimeout = offsetMovTimeout;
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
asynStatus sinqAxis::setScaleMovTimeout(time_t scaleMovTimeout) {
|
||||
pSinqA_->scaleMovTimeout = scaleMovTimeout;
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// IOC shell functions
|
||||
extern "C" {
|
||||
|
||||
Reference in New Issue
Block a user