Removed exit(-1) from init

When the initialization fails, the motor will now try again during each
poll.
This commit is contained in:
2025-05-23 11:51:33 +02:00
parent 738780f897
commit 18bc3dfc5f
4 changed files with 200 additions and 73 deletions

View File

@@ -13,6 +13,14 @@
#include <unistd.h>
#include <vector>
struct turboPmacAxisImpl {
bool waitForHandshake;
time_t timeAtHandshake;
// The axis status is used when enabling / disabling the motor
int axisStatus;
bool needInit;
};
/*
Contains all instances of turboPmacAxis which have been created and is used in
the initialization hook function.
@@ -54,10 +62,11 @@ turboPmacAxis::turboPmacAxis(turboPmacController *pC, int axisNo,
axes.push_back(this);
}
// Initialize all member variables
waitForHandshake_ = false;
timeAtHandshake_ = 0;
axisStatus_ = 0;
pTurboPmacA_ = std::make_unique<turboPmacAxisImpl>(
(turboPmacAxisImpl){.waitForHandshake = false,
.timeAtHandshake = 0,
.axisStatus = 0,
.needInit = false});
// Provide initial values for some parameter library entries
status = pC_->setIntegerParam(axisNo_, pC_->rereadEncoderPosition(), 0);
@@ -158,9 +167,9 @@ asynStatus turboPmacAxis::init() {
"with controller during IOC initialization. Check if you used "
"\"pmacAsynIPPortConfigure\" instead of the standard "
"\"drvAsynIPPortConfigure\" function in the .cmd file in order to "
"create the port driver.\nTerminating IOC.\n",
"create the port driver.\n",
pC_->portName, axisNo(), __PRETTY_FUNCTION__, __LINE__);
exit(-1);
pTurboPmacA_->needInit = true;
}
nvals = sscanf(response, "%d %lf %lf %lf %lf %d", &axStatus, &motorPos,
&motorVmax, &motorVelocity, &motorAccel, &acoDelay);
@@ -215,7 +224,12 @@ asynStatus turboPmacAxis::init() {
return status;
}
return this->readEncoderType();
status = this->readEncoderType();
if (status == asynSuccess) {
pTurboPmacA_->needInit = false;
}
return status;
}
// Perform the actual poll
@@ -251,13 +265,20 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
// =========================================================================
if (pTurboPmacA_->needInit) {
rw_status = init();
if (rw_status != asynSuccess) {
return rw_status;
}
}
// Are we currently waiting for a handshake?
if (waitForHandshake_) {
if (pTurboPmacA_->waitForHandshake) {
// Check if the handshake takes too long and communicate an error in
// this case. A handshake should not take more than 5 seconds.
time_t currentTime = time(NULL);
bool timedOut = (currentTime > timeAtHandshake_ + 5);
bool timedOut = (currentTime > pTurboPmacA_->timeAtHandshake + 5);
if (pC_->getMsgPrintControl().shouldBePrinted(
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, timedOut,
@@ -267,7 +288,7 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
"handshake at %ld s and didn't get a positive reply yet "
"(current time is %ld s).\n",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
timeAtHandshake_, currentTime);
pTurboPmacA_->timeAtHandshake, currentTime);
}
if (timedOut) {
@@ -279,6 +300,7 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
pTurboPmacA_->waitForHandshake = false;
}
snprintf(command, sizeof(command), "P%2.2d23 P%2.2d01", axisNo_,
@@ -298,11 +320,11 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
// If an error occurred while waiting for the handshake, abort the
// waiting procedure and continue with the poll in order to handle
// the error.
waitForHandshake_ = false;
pTurboPmacA_->waitForHandshake = false;
} else if (handshakePerformed == 1) {
// Handshake has been performed successfully -> Continue with the
// poll
waitForHandshake_ = false;
pTurboPmacA_->waitForHandshake = false;
} else {
// Still waiting for the handshake - try again in the next busy
// poll. This is already part of the movement procedure.
@@ -386,7 +408,7 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
lowLimit = lowLimit + limitsOffset;
// Store the axis status
axisStatus_ = axStatus;
pTurboPmacA_->axisStatus = axStatus;
// Update the enablement PV
pl_status = setIntegerParam(pC_->motorEnableRBV(),
@@ -459,13 +481,53 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
*moving = true;
break;
case 5:
// Motor is moving normally
*moving = true;
break;
case 6:
// Jog start
*moving = true;
break;
case 7:
// Jog forward
*moving = true;
break;
case 8:
// Jog backward
*moving = true;
break;
case 9:
// Jog break
*moving = true;
break;
case 10:
// Jog step forward
*moving = true;
break;
case 11:
// Jog step backward
*moving = true;
break;
case 12:
// Jog stop
*moving = true;
break;
case 13:
// Backlash
*moving = true;
break;
case 14:
// Move order out of range - this is also handled as an error
*moving = false;
break;
case 15:
// Move is interrupted, but the motor is not ready to receive another
// move command. Therefore it is treated as still moving.
*moving = true;
break;
case 16:
// Move is resumed
*moving = true;
asynPrint(
pC_->pasynUser(), ASYN_TRACE_FLOW,
"Controller \"%s\", axis %d => %s, line %d\nAxis is moving\n",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
break;
default:
*moving = false;
@@ -962,8 +1024,8 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
// In the next poll, we will check if the handshake has been performed in a
// reasonable time
waitForHandshake_ = true;
timeAtHandshake_ = time(NULL);
pTurboPmacA_->waitForHandshake = true;
pTurboPmacA_->timeAtHandshake = time(NULL);
// Waiting for a handshake is already part of the movement procedure =>
// Start the watchdog
@@ -1007,7 +1069,7 @@ asynStatus turboPmacAxis::stop(double acceleration) {
// Reset the driver to idle state and move out of the handshake wait loop,
// if we're currently inside it.
waitForHandshake_ = false;
pTurboPmacA_->waitForHandshake = false;
return rw_status;
}
@@ -1045,7 +1107,7 @@ asynStatus turboPmacAxis::doReset() {
// Reset the driver to idle state and move out of the handshake wait loop,
// if we're currently inside it.
waitForHandshake_ = false;
pTurboPmacA_->waitForHandshake = false;
return rw_status;
}
@@ -1276,8 +1338,11 @@ asynStatus turboPmacAxis::enable(bool on) {
// command and inform the user. We check the last known status of the axis
// instead of "moving", since status -6 is also moving, but the motor can
// actually be disabled in this state!
if (axisStatus_ == 1 || axisStatus_ == 2 || axisStatus_ == 3 ||
axisStatus_ == 4 || axisStatus_ == 5) {
int axStatus = pTurboPmacA_->axisStatus;
if (axStatus == 1 || axStatus == 2 || axStatus == 3 || axStatus == 4 ||
axStatus == 5 || axStatus == 6 || axStatus == 7 || axStatus == 8 ||
axStatus == 9 || axStatus == 10 || axStatus == 11 || axStatus == 12 ||
axStatus == 13 || axStatus == 15 || axStatus == 16) {
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d\nAxis is not "
"idle and can therefore not be enabled / disabled.\n",
@@ -1297,7 +1362,7 @@ asynStatus turboPmacAxis::enable(bool on) {
// Axis is already enabled / disabled and a new enable / disable command
// was sent => Do nothing
if ((axisStatus_ != -3) == on) {
if ((axStatus != -3) == on) {
asynPrint(
pC_->pasynUser(), ASYN_TRACE_WARNING,
"Controller \"%s\", axis %d => %s, line %d\nAxis is already %s.\n",
@@ -1338,13 +1403,13 @@ asynStatus turboPmacAxis::enable(bool on) {
if (rw_status != asynSuccess) {
return rw_status;
}
nvals = sscanf(response, "%d", &axisStatus_);
nvals = sscanf(response, "%d", &pTurboPmacA_->axisStatus);
if (nvals != 1) {
return pC_->couldNotParseResponse(command, response, axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
if ((axisStatus_ != -3) == on) {
if ((pTurboPmacA_->axisStatus != -3) == on) {
bool moving = false;
// Perform a poll to update the parameter library
poll(&moving);
@@ -1372,6 +1437,17 @@ asynStatus turboPmacAxis::enable(bool on) {
return asynError;
}
bool turboPmacAxis::needInit() { return pTurboPmacA_->needInit; }
/**
* @brief Instruct the axis to run its init() function during the next poll
*
* @param needInit
*/
void turboPmacAxis::setNeedInit(bool needInit) {
pTurboPmacA_->needInit = needInit;
}
/*************************************************************************************/
/** The following functions are C-wrappers, and can be called directly from
* iocsh */