Added adaptive polling
See documentation in README.md for parameter ADAPTPOLL
This commit is contained in:
+71
-23
@@ -15,6 +15,8 @@ sinqAxis::sinqAxis(class sinqController *pC, int axisNo)
|
||||
offsetMovTimeout_ = 30;
|
||||
targetPosition_ = 0.0;
|
||||
|
||||
epicsTimeGetCurrent(&lastPollTime_);
|
||||
|
||||
// This check is also done in asynMotorAxis, but there the IOC continues
|
||||
// running even though the configuration is incorrect. When failing this
|
||||
// check, the IOC is stopped, since this is definitely a configuration
|
||||
@@ -115,6 +117,46 @@ asynStatus sinqAxis::poll(bool *moving) {
|
||||
asynStatus poll_status = asynSuccess;
|
||||
int homing = 0;
|
||||
int homed = 0;
|
||||
int adaptivePolling = 0;
|
||||
|
||||
/*
|
||||
If adaptive polling is enabled:
|
||||
- Check if the motor was moving during the last poll
|
||||
- If yes, perform the poll
|
||||
- If no, check if the last poll was at least an idlePollPeriod ago
|
||||
- If yes, perform the poll
|
||||
- If no, skip it
|
||||
*/
|
||||
|
||||
pl_status =
|
||||
pC_->getIntegerParam(axisNo_, pC_->adaptivePolling(), &adaptivePolling);
|
||||
if (pl_status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(pl_status, "adaptivePolling", axisNo_,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
};
|
||||
|
||||
// Using the EPICS timestamp here, see
|
||||
// https://docs.epics-controls.org/projects/base/en/latest/epicsTime_h.html#_CPPv414epicsTimeStamp
|
||||
|
||||
// Get the current time
|
||||
epicsTimeStamp ts;
|
||||
epicsTimeGetCurrent(&ts);
|
||||
|
||||
if (adaptivePolling != 0) {
|
||||
// Motor wasn't moving during the last poll
|
||||
if (getWasMovingFlag() == 0) {
|
||||
|
||||
// Add the idle poll period
|
||||
epicsTimeStamp earliestTimeNextPoll = lastPollTime_;
|
||||
epicsTimeAddSeconds(&earliestTimeNextPoll, pC_->idlePollPeriod());
|
||||
if (epicsTimeLessThan(&earliestTimeNextPoll, &ts) == 1) {
|
||||
*moving = false;
|
||||
return asynSuccess;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Update the start time of the last poll
|
||||
lastPollTime_ = ts;
|
||||
|
||||
/*
|
||||
At the beginning of the poll, it is assumed that the axis has no status
|
||||
@@ -223,36 +265,42 @@ asynStatus sinqAxis::move(double position, int relative, double minVelocity,
|
||||
double maxVelocity, double acceleration) {
|
||||
|
||||
// Status of parameter library operations
|
||||
asynStatus pl_status = asynSuccess;
|
||||
asynStatus status = asynSuccess;
|
||||
double motorRecResolution = 0.0;
|
||||
|
||||
// =========================================================================
|
||||
|
||||
// When a new move is done, the motor is not homed anymore
|
||||
pl_status = setIntegerParam(pC_->motorStatusHomed(), 0);
|
||||
if (pl_status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(pl_status, "motorStatusHomed_",
|
||||
axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
pl_status = setIntegerParam(pC_->motorStatusAtHome(), 0);
|
||||
if (pl_status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(pl_status, "motorStatusAtHome_",
|
||||
axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
pl_status = pC_->getDoubleParam(axisNo_, pC_->motorRecResolution(),
|
||||
&motorRecResolution);
|
||||
if (pl_status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(pl_status, "motorRecResolution_",
|
||||
axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
// Store the target position internally
|
||||
targetPosition_ = position * motorRecResolution;
|
||||
|
||||
return doMove(position, relative, minVelocity, maxVelocity, acceleration);
|
||||
status = doMove(position, relative, minVelocity, maxVelocity, acceleration);
|
||||
if (status != asynSuccess) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Since the move command was successfull, we assume that the motor has
|
||||
// started its movement.
|
||||
status = setIntegerParam(pC_->motorStatusHomed(), 0);
|
||||
if (status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(status, "motorStatusHomed_", axisNo_,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
status = setIntegerParam(pC_->motorStatusAtHome(), 0);
|
||||
if (status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(status, "motorStatusAtHome_", axisNo_,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
status = pC_->getDoubleParam(axisNo_, pC_->motorRecResolution(),
|
||||
&motorRecResolution);
|
||||
if (status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(status, "motorRecResolution_", axisNo_,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
// Needed for adaptive polling
|
||||
setWasMovingFlag(1);
|
||||
|
||||
return pC_->callParamCallbacks();
|
||||
}
|
||||
|
||||
asynStatus sinqAxis::doMove(double position, int relative, double minVelocity,
|
||||
|
||||
Reference in New Issue
Block a user