Updated to sinqMotor 1.5 to get deadband feature
This commit is contained in:
@@ -27,18 +27,6 @@ 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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -88,8 +76,6 @@ turboPmacAxis::turboPmacAxis(turboPmacController *pC, int axisNo,
|
|||||||
.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
|
||||||
@@ -147,8 +133,16 @@ asynStatus turboPmacAxis::init() {
|
|||||||
double motorVelocity = 0.0;
|
double motorVelocity = 0.0;
|
||||||
double motorVmax = 0.0;
|
double motorVmax = 0.0;
|
||||||
double motorAccel = 0.0;
|
double motorAccel = 0.0;
|
||||||
int acoDelay = 0.0; // Offset time for the movement watchdog caused by
|
|
||||||
// the air cushions in milliseconds.
|
// Conversion factor between engineering units (EU) and encoder counts
|
||||||
|
double eu_to_counts = 0.0;
|
||||||
|
|
||||||
|
// Deadband in counts. Can be a fraction of a count, hence double.
|
||||||
|
double deadband_counts = 0.0;
|
||||||
|
|
||||||
|
// Offset time for the movement watchdog caused by the air cushions in
|
||||||
|
// milliseconds.
|
||||||
|
int acoDelay = 0.0;
|
||||||
int axStatus = 0;
|
int axStatus = 0;
|
||||||
|
|
||||||
// The parameter library takes some time to be initialized. Therefore we
|
// The parameter library takes some time to be initialized. Therefore we
|
||||||
@@ -199,10 +193,9 @@ asynStatus turboPmacAxis::init() {
|
|||||||
pC_->portName, axisNo(), __PRETTY_FUNCTION__, __LINE__);
|
pC_->portName, axisNo(), __PRETTY_FUNCTION__, __LINE__);
|
||||||
pTurboPmacA_->needInit = true;
|
pTurboPmacA_->needInit = true;
|
||||||
}
|
}
|
||||||
nvals =
|
nvals = sscanf(response, "%d %lf %lf %lf %lf %d %lf %lf", &axStatus,
|
||||||
sscanf(response, "%d %lf %lf %lf %lf %d %lf %lf", &axStatus, &motorPos,
|
&motorPos, &motorVmax, &motorVelocity, &motorAccel,
|
||||||
&motorVmax, &motorVelocity, &motorAccel, &acoDelay,
|
&acoDelay, &eu_to_counts, &deadband_counts);
|
||||||
&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));
|
||||||
@@ -236,6 +229,26 @@ asynStatus turboPmacAxis::init() {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if the new target position is within the range current position +/-
|
||||||
|
deadband. If that is the case, no movement command should be sent. This
|
||||||
|
functionality is implemented within the motor record itself, we just need to
|
||||||
|
populate the field SPDP (see record PushSPDB2Field in db/turboPmac.db)
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
setAxisParamChecked(this, motorPositionDeadband,
|
||||||
|
deadband_counts / (16.0 * eu_to_counts));
|
||||||
|
|
||||||
// Update the parameter library immediately
|
// Update the parameter library immediately
|
||||||
status = callParamCallbacks();
|
status = callParamCallbacks();
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
@@ -797,45 +810,11 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
|
|||||||
motorTargetPosition = 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__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
motorCurrentPosition);
|
motorTargetPosition);
|
||||||
|
|
||||||
// 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);
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ struct turboPmacControllerImpl {
|
|||||||
int flushHardware;
|
int flushHardware;
|
||||||
int limFromHardware;
|
int limFromHardware;
|
||||||
};
|
};
|
||||||
#define NUM_turboPmac_DRIVER_PARAMS 3
|
#define NUM_turboPmac_DRIVER_PARAMS 5
|
||||||
|
|
||||||
turboPmacController::turboPmacController(const char *portName,
|
turboPmacController::turboPmacController(const char *portName,
|
||||||
const char *ipPortConfigName,
|
const char *ipPortConfigName,
|
||||||
|
|||||||
Reference in New Issue
Block a user