Deadband check in driver code
This commit is contained in:
@@ -27,6 +27,18 @@ struct turboPmacAxisImpl {
|
|||||||
// The axis status is used when enabling / disabling the motor
|
// The axis status is used when enabling / disabling the motor
|
||||||
int axisStatus;
|
int axisStatus;
|
||||||
bool needInit;
|
bool needInit;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Deadband is defined in enconder units / 16 (a value of 16 is 1 actual
|
||||||
|
encoder count, see Turbo PMAC Manula, p.160)
|
||||||
|
*/
|
||||||
|
double deadband;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Scaling factor Ixx08, see Turbo PMAC User Manual, p. 268f:
|
||||||
|
[Ixx08] = counts / engineering units (eu)
|
||||||
|
*/
|
||||||
|
double eu_to_counts;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -70,12 +82,15 @@ turboPmacAxis::turboPmacAxis(turboPmacController *pC, int axisNo,
|
|||||||
axes.push_back(this);
|
axes.push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
pTurboPmacA_ = std::make_unique<turboPmacAxisImpl>(
|
pTurboPmacA_ = std::make_unique<turboPmacAxisImpl>((turboPmacAxisImpl){
|
||||||
(turboPmacAxisImpl){.waitForHandshake = false,
|
.waitForHandshake = false,
|
||||||
.enableDisable = false,
|
.enableDisable = false,
|
||||||
.timeAtHandshake = 0,
|
.timeAtHandshake = 0,
|
||||||
.axisStatus = 0,
|
.axisStatus = 0,
|
||||||
.needInit = false});
|
.needInit = false,
|
||||||
|
.deadband = 0.0,
|
||||||
|
.eu_to_counts = 0.0,
|
||||||
|
});
|
||||||
|
|
||||||
// Provide initial values for some parameter library entries
|
// Provide initial values for some parameter library entries
|
||||||
status = pC_->setIntegerParam(axisNo_, pC_->rereadEncoderPosition(), 0);
|
status = pC_->setIntegerParam(axisNo_, pC_->rereadEncoderPosition(), 0);
|
||||||
@@ -163,12 +178,16 @@ asynStatus turboPmacAxis::init() {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Read out the axis status, the current position, current and maximum speed,
|
Read out the axis status, the current position, current and maximum speed,
|
||||||
acceleration and the air cushion delay.
|
acceleration, the air cushion delay, the scaling factor between counts and
|
||||||
|
engineering units ([Ixx08] = counts / engineering units) and the deadband
|
||||||
|
Ixx65.
|
||||||
*/
|
*/
|
||||||
snprintf(command, sizeof(command),
|
snprintf(command, sizeof(command),
|
||||||
"P%2.2d00 Q%2.2d10 Q%2.2d03 Q%2.2d04 Q%2.2d06 P%2.2d22", axisNo_,
|
"P%2.2d00 Q%2.2d10 Q%2.2d03 Q%2.2d04 Q%2.2d06 P%2.2d22 I%2.2d08 "
|
||||||
axisNo_, axisNo_, axisNo_, axisNo_, axisNo_);
|
"I%2.2d65",
|
||||||
status = pC_->writeRead(axisNo_, command, response, 6);
|
axisNo_, axisNo_, axisNo_, axisNo_, axisNo_, axisNo_, axisNo_,
|
||||||
|
axisNo_);
|
||||||
|
status = pC_->writeRead(axisNo_, command, response, 8);
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
asynPrint(
|
asynPrint(
|
||||||
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
@@ -180,8 +199,10 @@ asynStatus turboPmacAxis::init() {
|
|||||||
pC_->portName, axisNo(), __PRETTY_FUNCTION__, __LINE__);
|
pC_->portName, axisNo(), __PRETTY_FUNCTION__, __LINE__);
|
||||||
pTurboPmacA_->needInit = true;
|
pTurboPmacA_->needInit = true;
|
||||||
}
|
}
|
||||||
nvals = sscanf(response, "%d %lf %lf %lf %lf %d", &axStatus, &motorPos,
|
nvals =
|
||||||
&motorVmax, &motorVelocity, &motorAccel, &acoDelay);
|
sscanf(response, "%d %lf %lf %lf %lf %d %lf %lf", &axStatus, &motorPos,
|
||||||
|
&motorVmax, &motorVelocity, &motorAccel, &acoDelay,
|
||||||
|
&pTurboPmacA_->eu_to_counts, &pTurboPmacA_->deadband);
|
||||||
|
|
||||||
// The acoDelay is given in milliseconds -> Convert to seconds, rounded up
|
// The acoDelay is given in milliseconds -> Convert to seconds, rounded up
|
||||||
setOffsetMovTimeout(std::ceil(acoDelay / 1000.0));
|
setOffsetMovTimeout(std::ceil(acoDelay / 1000.0));
|
||||||
@@ -191,7 +212,7 @@ asynStatus turboPmacAxis::init() {
|
|||||||
// here to mm/s^2.
|
// here to mm/s^2.
|
||||||
motorAccel = motorAccel * 1000;
|
motorAccel = motorAccel * 1000;
|
||||||
|
|
||||||
if (nvals != 6) {
|
if (nvals != 8) {
|
||||||
return pC_->couldNotParseResponse(command, response, axisNo_,
|
return pC_->couldNotParseResponse(command, response, axisNo_,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
@@ -752,7 +773,7 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
|
|||||||
|
|
||||||
char command[pC_->MAXBUF_] = {0};
|
char command[pC_->MAXBUF_] = {0};
|
||||||
char response[pC_->MAXBUF_] = {0};
|
char response[pC_->MAXBUF_] = {0};
|
||||||
double motorCoordinatesPosition = 0.0;
|
double motorTargetPosition = 0.0;
|
||||||
double motorRecResolution = 0.0;
|
double motorRecResolution = 0.0;
|
||||||
double motorVelocity = 0.0;
|
double motorVelocity = 0.0;
|
||||||
int enabled = 0;
|
int enabled = 0;
|
||||||
@@ -773,13 +794,48 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert from EPICS to user / motor units
|
// Convert from EPICS to user / motor units
|
||||||
motorCoordinatesPosition = position * motorRecResolution;
|
motorTargetPosition = position * motorRecResolution;
|
||||||
motorVelocity = maxVelocity * motorRecResolution;
|
motorVelocity = maxVelocity * motorRecResolution;
|
||||||
|
|
||||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_FLOW,
|
/*
|
||||||
|
Check if the new target position is within the range current position +/-
|
||||||
|
deadband. If that is the case, no movement command should be sent.
|
||||||
|
|
||||||
|
First, the deadband is read out (Ixx65, see Turbo PMAC User Manual, p.
|
||||||
|
160.). This value then needs to be converted into counts (by dividing it by
|
||||||
|
16). After words, the deadband in counts then need to be converted into
|
||||||
|
engineering units. For this, the scaling factor Ixx08 needs to be applied
|
||||||
|
(see Turbo PMAC User Manual, p. 268f):
|
||||||
|
[Ixx08] = counts / engineering units (eu)
|
||||||
|
deadband_eu = deadband_counts / Ixx08 = Ixx65 / (16 * Ixx08)
|
||||||
|
|
||||||
|
The values of Ixx08 and Ixx65 are read out during initialization and are
|
||||||
|
assumed to not change during operation.
|
||||||
|
*/
|
||||||
|
double motorCurrentPosition = 0.0;
|
||||||
|
motorPosition(&motorCurrentPosition);
|
||||||
|
double deadband_eu = pTurboPmacA_->deadband / (pTurboPmacA_->eu_to_counts);
|
||||||
|
double deadband_lower = motorCurrentPosition - deadband_eu;
|
||||||
|
double deadband_upper = motorCurrentPosition + deadband_eu;
|
||||||
|
|
||||||
|
if (motorTargetPosition > deadband_lower &&
|
||||||
|
motorTargetPosition < deadband_upper) {
|
||||||
|
|
||||||
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\", axis %d => %s, line %d\nNew target "
|
||||||
|
"position %lf within deadband around current position %lf "
|
||||||
|
"(deadband %lf to %lf). No move command sent.\n",
|
||||||
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
motorTargetPosition, motorCurrentPosition, deadband_lower,
|
||||||
|
deadband_upper);
|
||||||
|
return asynSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nStart of axis to "
|
"Controller \"%s\", axis %d => %s, line %d\nStart of axis to "
|
||||||
"position %lf.\n",
|
"position %lf.\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, position);
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
motorCurrentPosition);
|
||||||
|
|
||||||
// Check if the speed is allowed to be changed
|
// Check if the speed is allowed to be changed
|
||||||
getAxisParamChecked(this, motorCanSetSpeed, &motorCanSetSpeed);
|
getAxisParamChecked(this, motorCanSetSpeed, &motorCanSetSpeed);
|
||||||
@@ -804,11 +860,11 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
|
|||||||
if (relative) {
|
if (relative) {
|
||||||
snprintf(&command[writeOffset], sizeof(command) - writeOffset,
|
snprintf(&command[writeOffset], sizeof(command) - writeOffset,
|
||||||
"P%2.2d23=0 Q%2.2d02=%lf M%2.2d=2", axisNo_, axisNo_,
|
"P%2.2d23=0 Q%2.2d02=%lf M%2.2d=2", axisNo_, axisNo_,
|
||||||
motorCoordinatesPosition, axisNo_);
|
motorTargetPosition, axisNo_);
|
||||||
} else {
|
} else {
|
||||||
snprintf(&command[writeOffset], sizeof(command) - writeOffset,
|
snprintf(&command[writeOffset], sizeof(command) - writeOffset,
|
||||||
"P%2.2d23=0 Q%2.2d01=%lf M%2.2d=1", axisNo_, axisNo_,
|
"P%2.2d23=0 Q%2.2d01=%lf M%2.2d=1", axisNo_, axisNo_,
|
||||||
motorCoordinatesPosition, axisNo_);
|
motorTargetPosition, axisNo_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't expect an answer
|
// We don't expect an answer
|
||||||
@@ -820,7 +876,7 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
|
|||||||
"Controller \"%s\", axis %d => %s, line %d\nStarting movement to "
|
"Controller \"%s\", axis %d => %s, line %d\nStarting movement to "
|
||||||
"target position %lf failed.\n",
|
"target position %lf failed.\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
motorCoordinatesPosition);
|
motorTargetPosition);
|
||||||
setAxisParamChecked(this, motorStatusProblem, true);
|
setAxisParamChecked(this, motorStatusProblem, true);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user