Added adaptive polling

See documentation in README.md for parameter ADAPTPOLL
This commit is contained in:
2025-04-16 13:05:48 +02:00
parent 4c3254687d
commit db03ffea0e
6 changed files with 126 additions and 46 deletions
+71 -23
View File
@@ -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,