Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7a96ed2b71 | |||
| cf43a1c57a | |||
| 85317e24cd |
Submodule sinqMotor updated: 7a0de4e9d9...cff64f5ecf
@@ -70,12 +70,13 @@ turboPmacAxis::turboPmacAxis(turboPmacController *pC, int axisNo,
|
||||
axes.push_back(this);
|
||||
}
|
||||
|
||||
pTurboPmacA_ = std::make_unique<turboPmacAxisImpl>(
|
||||
(turboPmacAxisImpl){.waitForHandshake = false,
|
||||
.enableDisable = false,
|
||||
.timeAtHandshake = 0,
|
||||
.axisStatus = 0,
|
||||
.needInit = false});
|
||||
pTurboPmacA_ = std::make_unique<turboPmacAxisImpl>((turboPmacAxisImpl){
|
||||
.waitForHandshake = false,
|
||||
.enableDisable = false,
|
||||
.timeAtHandshake = 0,
|
||||
.axisStatus = 0,
|
||||
.needInit = false,
|
||||
});
|
||||
|
||||
// Provide initial values for some parameter library entries
|
||||
status = pC_->setIntegerParam(axisNo_, pC_->rereadEncoderPosition(), 0);
|
||||
@@ -132,8 +133,16 @@ asynStatus turboPmacAxis::init() {
|
||||
double motorVelocity = 0.0;
|
||||
double motorVmax = 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 counts_to_eu = 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;
|
||||
|
||||
// The parameter library takes some time to be initialized. Therefore we
|
||||
@@ -163,12 +172,16 @@ asynStatus turboPmacAxis::init() {
|
||||
|
||||
/*
|
||||
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 ([Qxx00] = engineering units / counts) and the deadband
|
||||
Ixx65.
|
||||
*/
|
||||
snprintf(command, sizeof(command),
|
||||
"P%2.2d00 Q%2.2d10 Q%2.2d03 Q%2.2d04 Q%2.2d06 P%2.2d22", axisNo_,
|
||||
axisNo_, axisNo_, axisNo_, axisNo_, axisNo_);
|
||||
status = pC_->writeRead(axisNo_, command, response, 6);
|
||||
"P%2.2d00 Q%2.2d10 Q%2.2d03 Q%2.2d04 Q%2.2d06 P%2.2d22 Q%2.2d00 "
|
||||
"I%2.2d65",
|
||||
axisNo_, axisNo_, axisNo_, axisNo_, axisNo_, axisNo_, axisNo_,
|
||||
axisNo_);
|
||||
status = pC_->writeRead(axisNo_, command, response, 8);
|
||||
if (status != asynSuccess) {
|
||||
asynPrint(
|
||||
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
@@ -180,8 +193,9 @@ asynStatus turboPmacAxis::init() {
|
||||
pC_->portName, axisNo(), __PRETTY_FUNCTION__, __LINE__);
|
||||
pTurboPmacA_->needInit = true;
|
||||
}
|
||||
nvals = sscanf(response, "%d %lf %lf %lf %lf %d", &axStatus, &motorPos,
|
||||
&motorVmax, &motorVelocity, &motorAccel, &acoDelay);
|
||||
nvals = sscanf(response, "%d %lf %lf %lf %lf %d %lf %lf", &axStatus,
|
||||
&motorPos, &motorVmax, &motorVelocity, &motorAccel,
|
||||
&acoDelay, &counts_to_eu, &deadband_counts);
|
||||
|
||||
// The acoDelay is given in milliseconds -> Convert to seconds, rounded up
|
||||
setOffsetMovTimeout(std::ceil(acoDelay / 1000.0));
|
||||
@@ -191,7 +205,7 @@ asynStatus turboPmacAxis::init() {
|
||||
// here to mm/s^2.
|
||||
motorAccel = motorAccel * 1000;
|
||||
|
||||
if (nvals != 6) {
|
||||
if (nvals != 8) {
|
||||
return pC_->couldNotParseResponse(command, response, axisNo_,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
@@ -215,6 +229,26 @@ asynStatus turboPmacAxis::init() {
|
||||
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 Qxx10 needs to be applied
|
||||
(see SINQ_2G_MCU_SW_manual_rev7, p. 17):
|
||||
[Qxx10] = engineering units (eu) / counts
|
||||
deadband_eu = Qxx10 * Ixx65 / 16
|
||||
|
||||
The values of Qxx10 and Ixx65 are read out during initialization and are
|
||||
assumed to not change during operation.
|
||||
*/
|
||||
setAxisParamChecked(this, motorPositionDeadband,
|
||||
counts_to_eu * deadband_counts / 16.0);
|
||||
|
||||
// Update the parameter library immediately
|
||||
status = callParamCallbacks();
|
||||
if (status != asynSuccess) {
|
||||
@@ -752,7 +786,7 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
|
||||
|
||||
char command[pC_->MAXBUF_] = {0};
|
||||
char response[pC_->MAXBUF_] = {0};
|
||||
double motorCoordinatesPosition = 0.0;
|
||||
double motorTargetPosition = 0.0;
|
||||
double motorRecResolution = 0.0;
|
||||
double motorVelocity = 0.0;
|
||||
int enabled = 0;
|
||||
@@ -773,13 +807,14 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
|
||||
}
|
||||
|
||||
// Convert from EPICS to user / motor units
|
||||
motorCoordinatesPosition = position * motorRecResolution;
|
||||
motorTargetPosition = position * motorRecResolution;
|
||||
motorVelocity = maxVelocity * motorRecResolution;
|
||||
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nStart of axis to "
|
||||
"position %lf.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, position);
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
motorTargetPosition);
|
||||
|
||||
// Check if the speed is allowed to be changed
|
||||
getAxisParamChecked(this, motorCanSetSpeed, &motorCanSetSpeed);
|
||||
@@ -804,11 +839,11 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
|
||||
if (relative) {
|
||||
snprintf(&command[writeOffset], sizeof(command) - writeOffset,
|
||||
"P%2.2d23=0 Q%2.2d02=%lf M%2.2d=2", axisNo_, axisNo_,
|
||||
motorCoordinatesPosition, axisNo_);
|
||||
motorTargetPosition, axisNo_);
|
||||
} else {
|
||||
snprintf(&command[writeOffset], sizeof(command) - writeOffset,
|
||||
"P%2.2d23=0 Q%2.2d01=%lf M%2.2d=1", axisNo_, axisNo_,
|
||||
motorCoordinatesPosition, axisNo_);
|
||||
motorTargetPosition, axisNo_);
|
||||
}
|
||||
|
||||
// We don't expect an answer
|
||||
@@ -820,7 +855,7 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nStarting movement to "
|
||||
"target position %lf failed.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
motorCoordinatesPosition);
|
||||
motorTargetPosition);
|
||||
setAxisParamChecked(this, motorStatusProblem, true);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ struct turboPmacControllerImpl {
|
||||
int flushHardware;
|
||||
int limFromHardware;
|
||||
};
|
||||
#define NUM_turboPmac_DRIVER_PARAMS 3
|
||||
#define NUM_turboPmac_DRIVER_PARAMS 5
|
||||
|
||||
turboPmacController::turboPmacController(const char *portName,
|
||||
const char *ipPortConfigName,
|
||||
|
||||
Reference in New Issue
Block a user