Updated turboPmac dependency to 0.15.1
This commit is contained in:
6
Makefile
6
Makefile
@ -16,14 +16,20 @@ motorBase_VERSION=7.2.2
|
||||
HEADERS += src/detectorTowerAngleAxis.h
|
||||
HEADERS += src/detectorTowerController.h
|
||||
HEADERS += src/detectorTowerLiftAxis.h
|
||||
HEADERS += src/detectorTowerSupportAxis.h
|
||||
|
||||
# Source files to build
|
||||
SOURCES += turboPmac/sinqMotor/src/msgPrintControl.cpp
|
||||
SOURCES += turboPmac/sinqMotor/src/sinqAxis.cpp
|
||||
SOURCES += turboPmac/sinqMotor/src/sinqController.cpp
|
||||
SOURCES += turboPmac/src/pmacAsynIPPort.c
|
||||
SOURCES += turboPmac/src/turboPmacAxis.cpp
|
||||
SOURCES += turboPmac/src/turboPmacController.cpp
|
||||
SOURCES += turboPmac/src/pmacAsynIPPort.c
|
||||
SOURCES += src/detectorTowerAngleAxis.cpp
|
||||
SOURCES += src/detectorTowerController.cpp
|
||||
SOURCES += src/detectorTowerLiftAxis.cpp
|
||||
SOURCES += src/detectorTowerSupportAxis.cpp
|
||||
|
||||
# Store the record files
|
||||
TEMPLATES += turboPmac/sinqMotor/db/asynRecord.db
|
||||
|
@ -89,47 +89,6 @@ record(ao, "$(INSTR)$(M):WriteAO") {
|
||||
field(VAL, "0")
|
||||
}
|
||||
|
||||
# Read out the origin of the lift axis support motor (FTZ at AMOR).
|
||||
# This PV does nothing for "normal" Turbo PMAC axes or the angle axis.
|
||||
record(ai, "$(INSTR)$(M):SupportOrigin") {
|
||||
field(DTYP, "asynFloat64")
|
||||
field(INP, "@asyn($(CONTROLLER),$(AXIS)) SUPPORT_ORIGIN")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(PINI, "NO")
|
||||
field(VAL, "0")
|
||||
}
|
||||
|
||||
# Shift the origin of the lift support axis by the given value. The axis will
|
||||
# move to this position and the hardware controller will internally set this
|
||||
# position as the new "0" value. This PV does nothing for "normal" Turbo PMAC
|
||||
# axes or the angle axis.
|
||||
record(ao, "$(INSTR)$(M):AdjustSupportOrigin") {
|
||||
field(DTYP, "Raw Soft Channel")
|
||||
field(PINI, "NO")
|
||||
field(DRVH, "200") # Limit in encoder steps (not mm!)
|
||||
field(DRVL, "-200") # Limit in encoder steps (not mm!)
|
||||
field(FLNK, "$(INSTR)$(M):ResetASO")
|
||||
field(VAL, "0")
|
||||
}
|
||||
|
||||
# Reset the PV $(INSTR)$(M):AdjustOrigin to zero after it has been written to and
|
||||
# forward the value to $(INSTR)$(M):WriteAO which does the actual writing.
|
||||
record(seq, "$(INSTR)$(M):ResetASO") {
|
||||
field(DESC, "Write value to hardware then reset to 0")
|
||||
field(DOL1, "$(INSTR)$(M):AdjustSupportOrigin")
|
||||
field(LNK1, "$(INSTR)$(M):WriteASO.VAL PP") # Perform write to hardware
|
||||
field(DOL2, "0.0")
|
||||
field(LNK2, "$(INSTR)$(M):AdjustSupportOrigin.VAL PP") # Reset to zero
|
||||
}
|
||||
|
||||
# This record forwards the adjustment of the origin to the asyn driver.
|
||||
record(ao, "$(INSTR)$(M):WriteASO") {
|
||||
field(DTYP, "asynFloat64")
|
||||
field(OUT, "@asyn($(CONTROLLER),$(AXIS),1) SUPPORT_ADJUST_ORIGIN")
|
||||
field(PINI, "NO")
|
||||
field(VAL, "0")
|
||||
}
|
||||
|
||||
# This record pair reads the parameter library value for "AdjustOriginHighLimitFromDriver_"
|
||||
# and pushes it to the high limit field of the "$(INSTR)$(M):AdjustOrigin" PV.
|
||||
# This can be used to read limits from the hardware and correspondingly update the motor record from the driver.
|
||||
|
@ -47,8 +47,7 @@ static void deferredMovementCollectorLoop(void *drvPvt) {
|
||||
}
|
||||
|
||||
detectorTowerAngleAxis::detectorTowerAngleAxis(detectorTowerController *pC,
|
||||
int axisNo,
|
||||
detectorTowerLiftAxis *liftAxis)
|
||||
int axisNo)
|
||||
: turboPmacAxis(pC, axisNo, false), pC_(pC) {
|
||||
|
||||
/*
|
||||
@ -80,8 +79,6 @@ detectorTowerAngleAxis::detectorTowerAngleAxis(detectorTowerController *pC,
|
||||
receivedTarget_ = false;
|
||||
startingDeferredMovement_ = false;
|
||||
deferredMovementWait_ = 0.1; // seconds
|
||||
liftAxis_ = liftAxis;
|
||||
liftAxis_->angleAxis_ = this;
|
||||
|
||||
// Will be populated in the init() method
|
||||
beamRadius_ = 0.0;
|
||||
@ -117,6 +114,7 @@ asynStatus detectorTowerAngleAxis::init() {
|
||||
asynStatus status = asynSuccess;
|
||||
double motorRecResolution = 0.0;
|
||||
char response[pC_->MAXBUF_] = {0};
|
||||
int positionState = 0;
|
||||
int nvals = 0;
|
||||
|
||||
// The parameter library takes some time to be initialized. Therefore we
|
||||
@ -146,14 +144,14 @@ asynStatus detectorTowerAngleAxis::init() {
|
||||
}
|
||||
|
||||
// Read the detector radius
|
||||
const char *command = "P459";
|
||||
status = pC_->writeRead(axisNo_, command, response, 1);
|
||||
const char *command = "P459 P358";
|
||||
status = pC_->writeRead(axisNo_, command, response, 2);
|
||||
if (status != asynSuccess) {
|
||||
return status;
|
||||
}
|
||||
|
||||
nvals = sscanf(response, "%lf", &beamRadius_);
|
||||
if (nvals != 1) {
|
||||
nvals = sscanf(response, "%lf %d", &beamRadius_, &positionState);
|
||||
if (nvals != 2) {
|
||||
return pC_->couldNotParseResponse(command, response, axisNo_,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
@ -165,7 +163,13 @@ asynStatus detectorTowerAngleAxis::init() {
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
return status;
|
||||
status = setIntegerParam(pC_->changeStateRBV(), positionState == 2);
|
||||
if (status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(status, "changeStateRBV", axisNo_,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
return callParamCallbacks();
|
||||
}
|
||||
|
||||
// Perform the actual poll
|
||||
@ -174,8 +178,8 @@ asynStatus detectorTowerAngleAxis::poll(bool *moving) {
|
||||
|
||||
// Is this axis the one with the smallest index?
|
||||
// If not, just read out the movement status and update *moving
|
||||
if (axisNo() < liftAxis_->axisNo()) {
|
||||
status = pC_->pollDetectorAxes(moving, this, liftAxis_);
|
||||
if (axisNo() < liftAxis()->axisNo() && axisNo() < supportAxis()->axisNo()) {
|
||||
status = pC_->pollDetectorAxes(moving, this, liftAxis(), supportAxis());
|
||||
} else {
|
||||
status = pC_->getIntegerParam(axisNo(), pC_->motorStatusMoving(),
|
||||
(int *)moving);
|
||||
@ -255,6 +259,23 @@ asynStatus detectorTowerAngleAxis::startCombinedMove() {
|
||||
pC_->getMsgPrintControl().getSuffix());
|
||||
}
|
||||
if (isInChangerPos) {
|
||||
|
||||
plStatus = setStringParam(
|
||||
pC_->motorMessageText(),
|
||||
"Move the axis to working state first.");
|
||||
if (plStatus != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(plStatus, "motorMessageText",
|
||||
axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
plStatus = setIntegerParam(pC_->motorStatusProblem(), true);
|
||||
if (plStatus != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(plStatus, "motorStatusProblem_",
|
||||
axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
callParamCallbacks();
|
||||
startingDeferredMovement_ = false;
|
||||
return asynError;
|
||||
}
|
||||
@ -287,6 +308,7 @@ asynStatus detectorTowerAngleAxis::startCombinedMove() {
|
||||
axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
callParamCallbacks();
|
||||
}
|
||||
|
||||
return rwStatus;
|
||||
@ -416,13 +438,10 @@ detectorTowerAngleAxis::toggleWorkingChangerState(bool toChangingPosition) {
|
||||
// Move the axis into changer or working position
|
||||
if (toChangingPosition) {
|
||||
rwStatus = pC_->writeRead(axisNo_, "P350=2", response, 0);
|
||||
plStatus = setStringParam(pC_->motorMessageText(),
|
||||
"Moving to changer position ...");
|
||||
} else {
|
||||
rwStatus = pC_->writeRead(axisNo_, "P350=3", response, 0);
|
||||
plStatus = setStringParam(pC_->motorMessageText(),
|
||||
"Moving to working state ...");
|
||||
}
|
||||
|
||||
if (plStatus != asynSuccess) {
|
||||
plStatus = setIntegerParam(pC_->changeStateRBV(), !toChangingPosition);
|
||||
if (plStatus != asynSuccess) {
|
||||
@ -444,34 +463,6 @@ detectorTowerAngleAxis::toggleWorkingChangerState(bool toChangingPosition) {
|
||||
return rwStatus;
|
||||
}
|
||||
|
||||
asynStatus detectorTowerAngleAxis::doReset() {
|
||||
|
||||
char response[pC_->MAXBUF_] = {0};
|
||||
asynStatus plStatus = asynSuccess;
|
||||
int positionState = 0;
|
||||
|
||||
plStatus =
|
||||
pC_->getIntegerParam(axisNo_, pC_->positionStateRBV(), &positionState);
|
||||
if (plStatus != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(plStatus, "positionStateRBV_", axisNo_,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
/*
|
||||
Check which action should be performed:
|
||||
- If error_ == 10 or 11 (FTZ motor error): P352 = 3 (Recover FTZ)
|
||||
- If any other error: P352 = 2 (Reset error)
|
||||
- Otherwise: P352 = 1 (Set axis in closed-loop mode)
|
||||
*/
|
||||
if (error_ == 10 || error_ == 11) {
|
||||
return pC_->writeRead(axisNo_, "P352=3", response, 0);
|
||||
} else if (error_ != 0) {
|
||||
return pC_->writeRead(axisNo_, "P352=2", response, 0);
|
||||
} else {
|
||||
return pC_->writeRead(axisNo_, "P352=1", response, 0);
|
||||
}
|
||||
}
|
||||
|
||||
asynStatus detectorTowerAngleAxis::adjustOrigin(double newOrigin) {
|
||||
|
||||
asynStatus status = asynSuccess;
|
||||
@ -526,6 +517,34 @@ asynStatus detectorTowerAngleAxis::adjustOrigin(double newOrigin) {
|
||||
return status;
|
||||
}
|
||||
|
||||
asynStatus detectorTowerAngleAxis::doReset() {
|
||||
|
||||
char response[pC_->MAXBUF_] = {0};
|
||||
asynStatus plStatus = asynSuccess;
|
||||
int positionState = 0;
|
||||
|
||||
plStatus =
|
||||
pC_->getIntegerParam(axisNo_, pC_->positionStateRBV(), &positionState);
|
||||
if (plStatus != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(plStatus, "positionStateRBV_", axisNo_,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
/*
|
||||
Check which action should be performed:
|
||||
- If error_ == 10 or 11 (FTZ motor error): P352 = 3 (Recover FTZ)
|
||||
- If any other error: P352 = 2 (Reset error)
|
||||
- Otherwise: P352 = 1 (Set axis in closed-loop mode)
|
||||
*/
|
||||
if (error_ == 10 || error_ == 11) {
|
||||
return pC_->writeRead(axisNo_, "P352=3", response, 0);
|
||||
} else if (error_ != 0) {
|
||||
return pC_->writeRead(axisNo_, "P352=2", response, 0);
|
||||
} else {
|
||||
return pC_->writeRead(axisNo_, "P352=1", response, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************/
|
||||
/** The following functions are C-wrappers, and can be called directly from
|
||||
* iocsh */
|
||||
@ -537,7 +556,7 @@ C wrapper for the axis constructor. Please refer to the detectorTower
|
||||
constructor documentation. The controller is read from the portName.
|
||||
*/
|
||||
asynStatus detectorTowerCreateAxis(const char *portName, int angleAxisIdx,
|
||||
int liftAxisIdx) {
|
||||
int liftAxisIdx, int supportAxisIdx) {
|
||||
|
||||
/*
|
||||
findAsynPortDriver is a asyn library FFI function which uses the C ABI.
|
||||
@ -597,13 +616,18 @@ asynStatus detectorTowerCreateAxis(const char *portName, int angleAxisIdx,
|
||||
be "leaked" here.
|
||||
*/
|
||||
|
||||
detectorTowerLiftAxis *liftAxis =
|
||||
new detectorTowerLiftAxis(pC, liftAxisIdx);
|
||||
detectorTowerAngleAxis *angleAxis =
|
||||
new detectorTowerAngleAxis(pC, angleAxisIdx);
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
detectorTowerAngleAxis *pAxis =
|
||||
new detectorTowerAngleAxis(pC, angleAxisIdx, liftAxis);
|
||||
detectorTowerLiftAxis *liftAxis =
|
||||
new detectorTowerLiftAxis(pC, liftAxisIdx, angleAxis);
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
detectorTowerSupportAxis *supportAxis =
|
||||
new detectorTowerSupportAxis(pC, supportAxisIdx, angleAxis);
|
||||
|
||||
// Allow manipulation of the controller again
|
||||
pC->unlock();
|
||||
@ -615,15 +639,19 @@ static const iocshArg CreateAxisArg0 = {"Controller name (e.g. mcu1)",
|
||||
static const iocshArg CreateAxisArg1 = {"Number of the detector angle axis",
|
||||
iocshArgInt};
|
||||
static const iocshArg CreateAxisArg2 = {"Number of the lift axis", iocshArgInt};
|
||||
static const iocshArg CreateAxisArg3 = {"Number of the support axis",
|
||||
iocshArgInt};
|
||||
static const iocshArg *const CreateAxisArgs[] = {
|
||||
&CreateAxisArg0,
|
||||
&CreateAxisArg1,
|
||||
&CreateAxisArg2,
|
||||
&CreateAxisArg3,
|
||||
};
|
||||
static const iocshFuncDef configDetectorTowerCreateAxis = {"detectorTowerAxis",
|
||||
3, CreateAxisArgs};
|
||||
4, CreateAxisArgs};
|
||||
static void configDetectorTowerCreateAxisCallFunc(const iocshArgBuf *args) {
|
||||
detectorTowerCreateAxis(args[0].sval, args[1].ival, args[2].ival);
|
||||
detectorTowerCreateAxis(args[0].sval, args[1].ival, args[2].ival,
|
||||
args[3].ival);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
@ -1,12 +1,13 @@
|
||||
#ifndef detectorTowerAngleAxis_H
|
||||
#define detectorTowerAngleAxis_H
|
||||
#include "detectorTowerLiftAxis.h"
|
||||
#include "turboPmacAxis.h"
|
||||
|
||||
// Forward declaration of the controller class to resolve the cyclic dependency
|
||||
// between the controller and the axis .h-file. See
|
||||
// https://en.cppreference.com/w/cpp/language/class.
|
||||
class detectorTowerController;
|
||||
class detectorTowerLiftAxis;
|
||||
class detectorTowerSupportAxis;
|
||||
|
||||
class detectorTowerAngleAxis : public turboPmacAxis {
|
||||
public:
|
||||
@ -15,13 +16,9 @@ class detectorTowerAngleAxis : public turboPmacAxis {
|
||||
*
|
||||
* @param pController Pointer to the associated controller
|
||||
* @param axisNo Index of the axis
|
||||
* @param liftZeroCorrAxis Pointer to the attached axis which controls
|
||||
* the lift offset
|
||||
* @param tiltZeroCorrAxis Pointer to the attached axis which controls
|
||||
* the tilt offset
|
||||
* @param liftAxis Pointer to the associated lift axis
|
||||
*/
|
||||
detectorTowerAngleAxis(detectorTowerController *pController, int axisNo,
|
||||
detectorTowerLiftAxis *liftAxis);
|
||||
detectorTowerAngleAxis(detectorTowerController *pController, int axisNo);
|
||||
|
||||
/**
|
||||
* @brief Destroy the detectorTowerAngleAxis
|
||||
@ -99,7 +96,6 @@ class detectorTowerAngleAxis : public turboPmacAxis {
|
||||
/**
|
||||
* @brief Implementation of the `doReset` method of sinqAxis
|
||||
*
|
||||
* @param on
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus doReset();
|
||||
@ -129,6 +125,13 @@ class detectorTowerAngleAxis : public turboPmacAxis {
|
||||
*/
|
||||
detectorTowerLiftAxis *liftAxis() { return liftAxis_; }
|
||||
|
||||
/**
|
||||
* @brief Return a pointer to the associated support axis
|
||||
*
|
||||
* @return detectorTowerAngleAxis*
|
||||
*/
|
||||
detectorTowerSupportAxis *supportAxis() { return supportAxis_; }
|
||||
|
||||
// If true, either this axis or one of the detectorTowerLiftAxis
|
||||
// attached to it received a movement command.
|
||||
bool receivedTarget_;
|
||||
@ -153,10 +156,12 @@ class detectorTowerAngleAxis : public turboPmacAxis {
|
||||
protected:
|
||||
detectorTowerController *pC_;
|
||||
detectorTowerLiftAxis *liftAxis_;
|
||||
detectorTowerSupportAxis *supportAxis_;
|
||||
double beamRadius_;
|
||||
|
||||
private:
|
||||
friend class detectorTowerLiftAxis;
|
||||
friend class detectorTowerSupportAxis;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -104,43 +104,26 @@ detectorTowerController::detectorTowerController(
|
||||
stringifyAsynStatus(status));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
status =
|
||||
createParam("SUPPORT_ORIGIN", asynParamFloat64, &liftSupportOrigin_);
|
||||
if (status != asynSuccess) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
|
||||
"parameter failed with %s).\nTerminating IOC",
|
||||
portName, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(status));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
status = createParam("SUPPORT_ADJUST_ORIGIN", asynParamFloat64,
|
||||
&liftSupportAdjustOrigin_);
|
||||
if (status != asynSuccess) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
|
||||
"parameter failed with %s).\nTerminating IOC",
|
||||
portName, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(status));
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
asynStatus detectorTowerController::readInt32(asynUser *pasynUser,
|
||||
epicsInt32 *value) {
|
||||
|
||||
// The detector tower or its auxiliary axes cannot be disabled
|
||||
// The detector axes cannot be disabled
|
||||
if (pasynUser->reason == motorCanDisable_) {
|
||||
detectorTowerAngleAxis *angleAxis =
|
||||
getDetectorTowerAngleAxis(pasynUser);
|
||||
if (angleAxis != nullptr) {
|
||||
detectorTowerAngleAxis *aAxis = getDetectorTowerAngleAxis(pasynUser);
|
||||
if (aAxis != nullptr) {
|
||||
*value = 0;
|
||||
return asynSuccess;
|
||||
}
|
||||
detectorTowerLiftAxis *liftAxis = getDetectorTowerLiftAxis(pasynUser);
|
||||
if (liftAxis != nullptr) {
|
||||
detectorTowerLiftAxis *lAxis = getDetectorTowerLiftAxis(pasynUser);
|
||||
if (lAxis != nullptr) {
|
||||
*value = 0;
|
||||
return asynSuccess;
|
||||
}
|
||||
detectorTowerSupportAxis *sAxis =
|
||||
getDetectorTowerSupportAxis(pasynUser);
|
||||
if (sAxis != nullptr) {
|
||||
*value = 0;
|
||||
return asynSuccess;
|
||||
}
|
||||
@ -151,17 +134,19 @@ asynStatus detectorTowerController::readInt32(asynUser *pasynUser,
|
||||
asynStatus detectorTowerController::writeInt32(asynUser *pasynUser,
|
||||
epicsInt32 value) {
|
||||
|
||||
// =====================================================================
|
||||
|
||||
if (pasynUser->reason == changeState_) {
|
||||
detectorTowerAngleAxis *angleAxis =
|
||||
getDetectorTowerAngleAxis(pasynUser);
|
||||
if (angleAxis != nullptr) {
|
||||
return angleAxis->toggleWorkingChangerState(value);
|
||||
detectorTowerAngleAxis *aAxis = getDetectorTowerAngleAxis(pasynUser);
|
||||
if (aAxis != nullptr) {
|
||||
return aAxis->toggleWorkingChangerState(value);
|
||||
}
|
||||
detectorTowerLiftAxis *liftAxis = getDetectorTowerLiftAxis(pasynUser);
|
||||
if (liftAxis != nullptr) {
|
||||
return liftAxis->angleAxis()->toggleWorkingChangerState(value);
|
||||
detectorTowerLiftAxis *lAxis = getDetectorTowerLiftAxis(pasynUser);
|
||||
if (lAxis != nullptr) {
|
||||
return lAxis->angleAxis()->toggleWorkingChangerState(value);
|
||||
}
|
||||
detectorTowerSupportAxis *sAxis =
|
||||
getDetectorTowerSupportAxis(pasynUser);
|
||||
if (sAxis != nullptr) {
|
||||
return sAxis->angleAxis()->toggleWorkingChangerState(value);
|
||||
}
|
||||
}
|
||||
return turboPmacController::writeInt32(pasynUser, value);
|
||||
@ -176,7 +161,7 @@ asynStatus detectorTowerController::writeFloat64(asynUser *pasynUser,
|
||||
|
||||
if (function == motorAdjustOrigin_) {
|
||||
|
||||
// Is this function called by an asynUser of the angle or lift axis?
|
||||
// Is this function called by a detector axis?
|
||||
detectorTowerAngleAxis *aAxis = getDetectorTowerAngleAxis(pasynUser);
|
||||
if (aAxis != nullptr) {
|
||||
status = aAxis->adjustOrigin(value);
|
||||
@ -184,26 +169,27 @@ asynStatus detectorTowerController::writeFloat64(asynUser *pasynUser,
|
||||
return status;
|
||||
}
|
||||
return turboPmacController::writeFloat64(pasynUser, value);
|
||||
} else {
|
||||
detectorTowerLiftAxis *lAxis = getDetectorTowerLiftAxis(pasynUser);
|
||||
if (lAxis != nullptr) {
|
||||
status = lAxis->adjustOrigin(value);
|
||||
if (status != asynSuccess) {
|
||||
return status;
|
||||
}
|
||||
return turboPmacController::writeFloat64(pasynUser, value);
|
||||
}
|
||||
}
|
||||
return asynSuccess;
|
||||
} else if (function == liftSupportAdjustOrigin_) {
|
||||
|
||||
detectorTowerLiftAxis *lAxis = getDetectorTowerLiftAxis(pasynUser);
|
||||
if (lAxis != nullptr) {
|
||||
status = lAxis->adjustSupportOrigin(value);
|
||||
status = lAxis->adjustOrigin(value);
|
||||
if (status != asynSuccess) {
|
||||
return status;
|
||||
}
|
||||
return turboPmacController::writeFloat64(pasynUser, value);
|
||||
}
|
||||
|
||||
detectorTowerSupportAxis *sAxis =
|
||||
getDetectorTowerSupportAxis(pasynUser);
|
||||
if (sAxis != nullptr) {
|
||||
status = sAxis->adjustOrigin(value);
|
||||
if (status != asynSuccess) {
|
||||
return status;
|
||||
}
|
||||
return turboPmacController::writeFloat64(pasynUser, value);
|
||||
}
|
||||
|
||||
return asynSuccess;
|
||||
} else {
|
||||
return turboPmacController::writeFloat64(pasynUser, value);
|
||||
@ -252,10 +238,30 @@ detectorTowerController::getDetectorTowerLiftAxis(int axisNo) {
|
||||
return dynamic_cast<detectorTowerLiftAxis *>(asynAxis);
|
||||
}
|
||||
|
||||
asynStatus
|
||||
detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
detectorTowerAngleAxis *angleAxis,
|
||||
detectorTowerLiftAxis *liftAxis) {
|
||||
/*
|
||||
Access one of the axes of the controller via the axis adress stored in asynUser.
|
||||
If the axis does not exist or is not a Axis, a nullptr is returned and an
|
||||
error is emitted.
|
||||
*/
|
||||
detectorTowerSupportAxis *
|
||||
detectorTowerController::getDetectorTowerSupportAxis(asynUser *pasynUser) {
|
||||
asynMotorAxis *asynAxis = asynMotorController::getAxis(pasynUser);
|
||||
return dynamic_cast<detectorTowerSupportAxis *>(asynAxis);
|
||||
}
|
||||
|
||||
/*
|
||||
Access one of the axes of the controller via the axis index.
|
||||
If the axis does not exist or is not a Axis, the function must return Null
|
||||
*/
|
||||
detectorTowerSupportAxis *
|
||||
detectorTowerController::getDetectorTowerSupportAxis(int axisNo) {
|
||||
asynMotorAxis *asynAxis = asynMotorController::getAxis(axisNo);
|
||||
return dynamic_cast<detectorTowerSupportAxis *>(asynAxis);
|
||||
}
|
||||
|
||||
asynStatus detectorTowerController::pollDetectorAxes(
|
||||
bool *moving, detectorTowerAngleAxis *angleAxis,
|
||||
detectorTowerLiftAxis *liftAxis, detectorTowerSupportAxis *supportAxis) {
|
||||
|
||||
// Return value for the poll
|
||||
asynStatus pollStatus = asynSuccess;
|
||||
@ -267,6 +273,8 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
asynStatus plStatus = asynSuccess;
|
||||
|
||||
char userMessage[MAXBUF_] = {0};
|
||||
// User message which was created in one of the other axis methods
|
||||
char oldUserMessage[MAXBUF_] = {0};
|
||||
char response[MAXBUF_] = {0};
|
||||
int nvals = 0;
|
||||
|
||||
@ -292,20 +300,26 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
double liftAdjustOriginHighLimit = 0.0;
|
||||
double liftAdjustOriginLowLimit = 0.0;
|
||||
|
||||
double supportOrigin = 0.0;
|
||||
|
||||
double angleOrigin = 0.0;
|
||||
double angleAdjustOriginHighLimit = 0.0;
|
||||
double angleAdjustOriginLowLimit = 0.0;
|
||||
|
||||
double supportOrigin = 0.0;
|
||||
|
||||
int angleAxisNo = angleAxis->axisNo();
|
||||
int liftAxisNo = liftAxis->axisNo();
|
||||
int supportAxisNo = supportAxis->axisNo();
|
||||
|
||||
/*
|
||||
For messages which in principle concern both axes, use the smaller of the
|
||||
two indices.
|
||||
For messages which in principle concern all axes, use the smallest index
|
||||
*/
|
||||
int comAxisNo = angleAxisNo > liftAxisNo ? liftAxisNo : angleAxisNo;
|
||||
int comAxisNo = angleAxisNo;
|
||||
if (comAxisNo > liftAxisNo) {
|
||||
comAxisNo = liftAxisNo;
|
||||
}
|
||||
if (comAxisNo > supportAxisNo) {
|
||||
comAxisNo = supportAxisNo;
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
|
||||
@ -329,6 +343,11 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
paramLibAccessFailed(plStatus, "motorStatusProblem_", liftAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
plStatus = supportAxis->setIntegerParam(motorStatusProblem(), false);
|
||||
if (plStatus != asynSuccess) {
|
||||
paramLibAccessFailed(plStatus, "motorStatusProblem_", supportAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
plStatus = angleAxis->setIntegerParam(motorStatusCommsError(), false);
|
||||
if (plStatus != asynSuccess) {
|
||||
@ -340,6 +359,11 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
paramLibAccessFailed(plStatus, "motorStatusCommsError_", liftAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
plStatus = supportAxis->setIntegerParam(motorStatusCommsError(), false);
|
||||
if (plStatus != asynSuccess) {
|
||||
paramLibAccessFailed(plStatus, "motorStatusCommsError_", supportAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
// Read the previous motor positions
|
||||
plStatus = angleAxis->motorPosition(&prevAngle);
|
||||
@ -458,13 +482,9 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
}
|
||||
resetCountPosState = false;
|
||||
|
||||
plStatus =
|
||||
setStringParam(motorMessageText(), "Reset one of the tower axes.");
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorMessageText_",
|
||||
comAxisNo, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
snprintf(userMessage, sizeof(userMessage),
|
||||
"Reset one of the tower axes."
|
||||
);
|
||||
|
||||
pollStatus = asynError;
|
||||
break;
|
||||
@ -504,12 +524,6 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
"Unknown state P358 = %d has been reached. Please call "
|
||||
"the support.",
|
||||
positionState);
|
||||
plStatus = setStringParam(motorMessageText(), userMessage);
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorMessageText_",
|
||||
comAxisNo, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
pollStatus = asynError;
|
||||
}
|
||||
@ -627,12 +641,6 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
"Axis release was removed while moving. Try resetting the axis "
|
||||
"and issue the move command again.");
|
||||
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorMessageText_",
|
||||
comAxisNo, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
pollStatus = asynError;
|
||||
break;
|
||||
|
||||
@ -797,8 +805,13 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
getMsgPrintControl().resetCount(keyError, pasynUser());
|
||||
}
|
||||
|
||||
// Update the parameter library for both axes
|
||||
if (error != 0) {
|
||||
// Update the parameter library for all axes
|
||||
|
||||
|
||||
|
||||
getStringParam(angleAxisNo, motorMessageText(), sizeof(oldUserMessage), oldUserMessage);
|
||||
|
||||
if (error != 0 || oldUserMessage[0] != '\0') {
|
||||
|
||||
plStatus = angleAxis->setIntegerParam(motorStatusProblem(), true);
|
||||
if (plStatus != asynSuccess) {
|
||||
@ -813,9 +826,17 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
liftAxisNo, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
plStatus = supportAxis->setIntegerParam(motorStatusProblem(), true);
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorStatusProblem_",
|
||||
supportAxisNo, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the user message text
|
||||
// Update the user message text, if one is available
|
||||
if (userMessage[0] != '\0') {
|
||||
plStatus = angleAxis->setStringParam(motorMessageText(), userMessage);
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorMessageText_", angleAxisNo,
|
||||
@ -826,6 +847,13 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
return paramLibAccessFailed(plStatus, "motorMessageText_", liftAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
plStatus = supportAxis->setStringParam(motorMessageText(), userMessage);
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorMessageText_",
|
||||
supportAxisNo, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the working position state PV
|
||||
plStatus = angleAxis->setIntegerParam(positionStateRBV(), positionState);
|
||||
@ -838,6 +866,12 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
return paramLibAccessFailed(plStatus, "positionStateRBV_", liftAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
plStatus = supportAxis->setIntegerParam(positionStateRBV(), positionState);
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "positionStateRBV_",
|
||||
supportAxisNo, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
// The axes are always enabled
|
||||
plStatus = angleAxis->setIntegerParam(motorEnableRBV(), 1);
|
||||
@ -850,6 +884,11 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
return paramLibAccessFailed(plStatus, "motorEnableRBV_", liftAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
plStatus = supportAxis->setIntegerParam(motorEnableRBV(), 1);
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorEnableRBV_", supportAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
// Are the axes currently moving?
|
||||
plStatus = angleAxis->setIntegerParam(motorStatusMoving(), *moving);
|
||||
@ -862,6 +901,12 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
return paramLibAccessFailed(plStatus, "motorStatusMoving_", liftAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
plStatus = supportAxis->setIntegerParam(motorStatusMoving(), *moving);
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorStatusMoving_",
|
||||
supportAxisNo, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
// Is the axis movement done?
|
||||
plStatus = angleAxis->setIntegerParam(motorStatusDone(), !(*moving));
|
||||
@ -874,8 +919,13 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
return paramLibAccessFailed(plStatus, "motorStatusDone_", liftAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
plStatus = supportAxis->setIntegerParam(motorStatusDone(), !(*moving));
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorStatusDone_", supportAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
// In which angleDir are the axes currently moving?
|
||||
// In which direction are the axes currently moving?
|
||||
plStatus = angleAxis->setIntegerParam(motorStatusDirection(), angleDir);
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorStatusDirection_",
|
||||
@ -886,6 +936,13 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
return paramLibAccessFailed(plStatus, "motorStatusDirection_",
|
||||
liftAxisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
// Using the lift direction for the support axis is done on purpose!
|
||||
plStatus = supportAxis->setIntegerParam(motorStatusDirection(), liftDir);
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorStatusDirection_",
|
||||
supportAxisNo, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
// High limits from hardware
|
||||
plStatus =
|
||||
@ -900,6 +957,14 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
return paramLibAccessFailed(plStatus, "motorHighLimitFromDriver",
|
||||
liftAxisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
// Using the lift high limit for the support axis is done on purpose!
|
||||
plStatus = setDoubleParam(supportAxisNo, motorHighLimitFromDriver(),
|
||||
liftHighLimit);
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorHighLimitFromDriver",
|
||||
supportAxisNo, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
// Low limits from hardware
|
||||
plStatus =
|
||||
@ -914,6 +979,14 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
return paramLibAccessFailed(plStatus, "motorLowLimitFromDriver",
|
||||
liftAxisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
// Using the lift low limit for the support axis is done on purpose!
|
||||
plStatus =
|
||||
setDoubleParam(supportAxisNo, motorLowLimitFromDriver(), liftLowLimit);
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorLowLimitFromDriver",
|
||||
supportAxisNo, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
// Write the motor origin
|
||||
plStatus = setDoubleParam(angleAxisNo, motorOrigin(), angleOrigin);
|
||||
@ -926,11 +999,9 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
return paramLibAccessFailed(plStatus, "motorOrigin", liftAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
// Write the lift support origin motor
|
||||
plStatus = setDoubleParam(liftAxisNo, liftSupportOrigin(), supportOrigin);
|
||||
plStatus = setDoubleParam(supportAxisNo, motorOrigin(), supportOrigin);
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "liftSupportOrigin", liftAxisNo,
|
||||
return paramLibAccessFailed(plStatus, "supportOrigin", supportAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
@ -949,6 +1020,15 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
return paramLibAccessFailed(plStatus, "motorOriginHighLimitFromDriver",
|
||||
liftAxisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
// Using the lift high limit for the support axis is done on purpose!
|
||||
plStatus =
|
||||
setDoubleParam(supportAxisNo, motorAdjustOriginHighLimitFromDriver(),
|
||||
liftAdjustOriginHighLimit);
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorOriginHighLimitFromDriver",
|
||||
supportAxisNo, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
// Origin adjustment low limit
|
||||
plStatus =
|
||||
@ -966,6 +1046,15 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
"motorAdjustOriginLowLimitFromDriver",
|
||||
liftAxisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
// Using the lift low limit for the support axis is done on purpose!
|
||||
plStatus =
|
||||
setDoubleParam(supportAxisNo, motorAdjustOriginLowLimitFromDriver(),
|
||||
liftAdjustOriginLowLimit);
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(
|
||||
plStatus, "motorAdjustOriginLowLimitFromDriver", supportAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
// Axes positions
|
||||
plStatus = angleAxis->setMotorPosition(angle);
|
||||
@ -976,22 +1065,13 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
if (plStatus != asynSuccess) {
|
||||
return plStatus;
|
||||
}
|
||||
|
||||
// Something went wrong -> Report a status problem
|
||||
if (pollStatus != asynSuccess) {
|
||||
plStatus = angleAxis->setIntegerParam(motorStatusProblem(), true);
|
||||
if (plStatus != asynSuccess) {
|
||||
paramLibAccessFailed(plStatus, "motorStatusProblem_", angleAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
plStatus = liftAxis->setIntegerParam(motorStatusProblem(), true);
|
||||
if (plStatus != asynSuccess) {
|
||||
paramLibAccessFailed(plStatus, "motorStatusProblem_", liftAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
// Using the lift position for the support axis is done on purpose!
|
||||
plStatus = supportAxis->setMotorPosition(lift);
|
||||
if (plStatus != asynSuccess) {
|
||||
return plStatus;
|
||||
}
|
||||
|
||||
// Update the parameter library
|
||||
// Update the parameter library for all three axes
|
||||
bool wantToPrint = false;
|
||||
|
||||
plStatus = angleAxis->callParamCallbacks();
|
||||
@ -1009,6 +1089,7 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
if (wantToPrint) {
|
||||
pollStatus = plStatus;
|
||||
}
|
||||
|
||||
plStatus = liftAxis->callParamCallbacks();
|
||||
wantToPrint = plStatus != asynSuccess;
|
||||
if (getMsgPrintControl().shouldBePrinted(portName, liftAxisNo,
|
||||
@ -1025,6 +1106,40 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
||||
pollStatus = plStatus;
|
||||
}
|
||||
|
||||
plStatus = supportAxis->callParamCallbacks();
|
||||
wantToPrint = plStatus != asynSuccess;
|
||||
if (getMsgPrintControl().shouldBePrinted(portName, supportAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__,
|
||||
wantToPrint, pasynUser())) {
|
||||
asynPrint(pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line "
|
||||
"%d:\ncallParamCallbacks failed with %s.%s\n",
|
||||
portName, supportAxisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(pollStatus),
|
||||
getMsgPrintControl().getSuffix());
|
||||
}
|
||||
if (wantToPrint) {
|
||||
pollStatus = plStatus;
|
||||
}
|
||||
|
||||
// Reset the message text for the next poll cycle AFTER updating the PVs
|
||||
plStatus = angleAxis->setStringParam(motorMessageText(), "");
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorMessageText_", angleAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
plStatus = liftAxis->setStringParam(motorMessageText(), "");
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorMessageText_", liftAxisNo,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
plStatus = supportAxis->setStringParam(motorMessageText(), "");
|
||||
if (plStatus != asynSuccess) {
|
||||
return paramLibAccessFailed(plStatus, "motorMessageText_",
|
||||
supportAxisNo, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
return pollStatus;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define detectorTowerController_H
|
||||
#include "detectorTowerAngleAxis.h"
|
||||
#include "detectorTowerLiftAxis.h"
|
||||
#include "detectorTowerSupportAxis.h"
|
||||
#include "turboPmacController.h"
|
||||
|
||||
class detectorTowerController : public turboPmacController {
|
||||
@ -97,6 +98,24 @@ class detectorTowerController : public turboPmacController {
|
||||
*/
|
||||
detectorTowerLiftAxis *getDetectorTowerLiftAxis(int axisNo);
|
||||
|
||||
/**
|
||||
* @brief Get the axis object
|
||||
*
|
||||
* @param pasynUser Specify the axis via the asynUser
|
||||
* @return detectorTowerSupportAxis* If no axis could be found,
|
||||
* this is a nullptr
|
||||
*/
|
||||
detectorTowerSupportAxis *getDetectorTowerSupportAxis(asynUser *pasynUser);
|
||||
|
||||
/**
|
||||
* @brief Get the axis object
|
||||
*
|
||||
* @param axisNo Specify the axis via its index
|
||||
* @return detectorTowerSupportAxis* If no axis could be found,
|
||||
* this is a nullptr
|
||||
*/
|
||||
detectorTowerSupportAxis *getDetectorTowerSupportAxis(int axisNo);
|
||||
|
||||
/**
|
||||
* @brief Common poll function for both lift and angle axes
|
||||
*
|
||||
@ -106,7 +125,8 @@ class detectorTowerController : public turboPmacController {
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus pollDetectorAxes(bool *moving, detectorTowerAngleAxis *angleAxis,
|
||||
detectorTowerLiftAxis *liftAxis);
|
||||
detectorTowerLiftAxis *liftAxis,
|
||||
detectorTowerSupportAxis *supportAxis);
|
||||
|
||||
// Accessors for additional PVs
|
||||
int positionStateRBV() { return positionStateRBV_; }
|
||||
@ -120,8 +140,6 @@ class detectorTowerController : public turboPmacController {
|
||||
int motorAdjustOriginLowLimitFromDriver() {
|
||||
return motorAdjustOriginLowLimitFromDriver_;
|
||||
}
|
||||
int liftSupportOrigin() { return liftSupportOrigin_; }
|
||||
int liftSupportAdjustOrigin() { return liftSupportAdjustOrigin_; }
|
||||
|
||||
private:
|
||||
// Indices of additional PVs
|
||||
@ -133,9 +151,7 @@ class detectorTowerController : public turboPmacController {
|
||||
int motorAdjustOrigin_;
|
||||
int motorAdjustOriginHighLimitFromDriver_;
|
||||
int motorAdjustOriginLowLimitFromDriver_;
|
||||
int liftSupportOrigin_;
|
||||
int liftSupportAdjustOrigin_;
|
||||
#define LAST_detectorTower_PARAM liftSupportAdjustOrigin_
|
||||
#define LAST_detectorTower_PARAM motorAdjustOriginLowLimitFromDriver_
|
||||
};
|
||||
#define NUM_detectorTower_DRIVER_PARAMS \
|
||||
(&LAST_detectorTower_PARAM - &FIRST_detectorTower_PARAM + 1)
|
||||
|
@ -30,21 +30,22 @@ static void epicsInithookFunction(initHookState iState) {
|
||||
}
|
||||
|
||||
detectorTowerLiftAxis::detectorTowerLiftAxis(detectorTowerController *pC,
|
||||
int axisNo)
|
||||
int axisNo,
|
||||
detectorTowerAngleAxis *angleAxis)
|
||||
: turboPmacAxis(pC, axisNo, false), pC_(pC) {
|
||||
|
||||
/*
|
||||
The superclass constructor sinqAxis calls in turn its superclass constructor
|
||||
asynMotorAxis. In the latter, a pointer to the constructed object this is
|
||||
stored inside the array pAxes_:
|
||||
The superclass constructor sinqAxis calls in turn its superclass
|
||||
constructor asynMotorAxis. In the latter, a pointer to the constructed
|
||||
object this is stored inside the array pAxes_:
|
||||
|
||||
pC->pAxes_[axisNo] = this;
|
||||
|
||||
Therefore, the axes are managed by the controller pC. If axisNo is out of
|
||||
bounds, asynMotorAxis prints an error (see
|
||||
Therefore, the axes are managed by the controller pC. If axisNo is out
|
||||
of bounds, asynMotorAxis prints an error (see
|
||||
https://github.com/epics-modules/motor/blob/master/motorApp/MotorSrc/asynMotorAxis.cpp,
|
||||
line 40). However, we want the IOC creation to stop completely, since this
|
||||
is a configuration error.
|
||||
line 40). However, we want the IOC creation to stop completely, since
|
||||
this is a configuration error.
|
||||
*/
|
||||
if (axisNo >= pC->numAxes()) {
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
@ -56,7 +57,8 @@ detectorTowerLiftAxis::detectorTowerLiftAxis(detectorTowerController *pC,
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Register the hook function during construction of the first axis object
|
||||
// Register the hook function during construction of the first axis
|
||||
// object
|
||||
if (axes.empty()) {
|
||||
initHookRegister(&epicsInithookFunction);
|
||||
}
|
||||
@ -64,11 +66,14 @@ detectorTowerLiftAxis::detectorTowerLiftAxis(detectorTowerController *pC,
|
||||
// Collect all axes into this list which will be used in the hook
|
||||
// function
|
||||
axes.push_back(this);
|
||||
|
||||
angleAxis_ = angleAxis;
|
||||
angleAxis->liftAxis_ = this;
|
||||
}
|
||||
|
||||
detectorTowerLiftAxis::~detectorTowerLiftAxis(void) {
|
||||
// Since the controller memory is managed somewhere else, we don't need to
|
||||
// clean up the pointer pC here.
|
||||
// Since the controller memory is managed somewhere else, we don't need
|
||||
// to clean up the pointer pC here.
|
||||
}
|
||||
|
||||
asynStatus detectorTowerLiftAxis::init() {
|
||||
@ -76,6 +81,9 @@ asynStatus detectorTowerLiftAxis::init() {
|
||||
// Local variable declaration
|
||||
asynStatus status = asynSuccess;
|
||||
double motorRecResolution = 0.0;
|
||||
char response[pC_->MAXBUF_] = {0};
|
||||
int positionState = 0;
|
||||
int nvals = 0;
|
||||
|
||||
// The parameter library takes some time to be initialized. Therefore we
|
||||
// wait until the status is not asynParamUndefined anymore.
|
||||
@ -109,7 +117,22 @@ asynStatus detectorTowerLiftAxis::init() {
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
return asynSuccess;
|
||||
// Check if we are currently in the changer position and update the PV
|
||||
// accordingly
|
||||
status = pC_->writeRead(axisNo_, "P358", response, 1);
|
||||
nvals = sscanf(response, "%d", &positionState);
|
||||
if (nvals != 1) {
|
||||
return pC_->couldNotParseResponse("P358", response, axisNo(),
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
status = setIntegerParam(pC_->changeStateRBV(), positionState == 2);
|
||||
if (status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(status, "changeStateRBV", axisNo_,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
return callParamCallbacks();
|
||||
}
|
||||
|
||||
// Perform the actual poll
|
||||
@ -118,8 +141,10 @@ asynStatus detectorTowerLiftAxis::poll(bool *moving) {
|
||||
|
||||
// Is this axis the one with the smallest index?
|
||||
// If not, just read out the movement status and update *moving
|
||||
if (axisNo() < angleAxis_->axisNo()) {
|
||||
status = pC_->pollDetectorAxes(moving, angleAxis_, this);
|
||||
if (axisNo() < angleAxis()->axisNo() &&
|
||||
axisNo() < angleAxis()->supportAxis()->axisNo()) {
|
||||
status = pC_->pollDetectorAxes(moving, angleAxis(), this,
|
||||
angleAxis()->supportAxis());
|
||||
} else {
|
||||
status = pC_->getIntegerParam(axisNo(), pC_->motorStatusMoving(),
|
||||
(int *)moving);
|
||||
@ -156,14 +181,16 @@ asynStatus detectorTowerLiftAxis::doMove(double position, int relative,
|
||||
}
|
||||
|
||||
// Signal to the deferredMovementCollectorLoop (of the
|
||||
// detectorTowerAngleAxis) that a movement should be started to the defined
|
||||
// target position.
|
||||
// detectorTowerAngleAxis) that a movement should be started to the
|
||||
// defined target position.
|
||||
targetPosition_ = position * motorRecResolution;
|
||||
angleAxis_->receivedTarget_ = true;
|
||||
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
asynStatus detectorTowerLiftAxis::reset() { return angleAxis()->reset(); };
|
||||
|
||||
asynStatus detectorTowerLiftAxis::stop(double acceleration) {
|
||||
|
||||
// Status of read-write-operations of ASCII commands to the controller
|
||||
@ -179,11 +206,11 @@ asynStatus detectorTowerLiftAxis::stop(double acceleration) {
|
||||
rwStatus = pC_->writeRead(axisNo_, "P350=8", response, 0);
|
||||
|
||||
if (rwStatus != asynSuccess) {
|
||||
asynPrint(
|
||||
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nStopping the movement "
|
||||
"failed.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nStopping "
|
||||
"the movement "
|
||||
"failed.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
|
||||
plStatus = setIntegerParam(pC_->motorStatusProblem(), true);
|
||||
if (plStatus != asynSuccess) {
|
||||
@ -197,7 +224,9 @@ asynStatus detectorTowerLiftAxis::stop(double acceleration) {
|
||||
return rwStatus;
|
||||
}
|
||||
|
||||
asynStatus detectorTowerLiftAxis::reset() { return angleAxis_->reset(); };
|
||||
asynStatus detectorTowerLiftAxis::readEncoderType() {
|
||||
return angleAxis()->readEncoderType();
|
||||
}
|
||||
|
||||
asynStatus detectorTowerLiftAxis::adjustOrigin(double newOrigin) {
|
||||
|
||||
@ -252,57 +281,3 @@ asynStatus detectorTowerLiftAxis::adjustOrigin(double newOrigin) {
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
asynStatus detectorTowerLiftAxis::adjustSupportOrigin(double newOrigin) {
|
||||
|
||||
asynStatus status = asynSuccess;
|
||||
char command[pC_->MAXBUF_] = {0};
|
||||
char response[pC_->MAXBUF_] = {0};
|
||||
int positionState = 0;
|
||||
|
||||
// =========================================================================
|
||||
|
||||
status =
|
||||
pC_->getIntegerParam(axisNo(), pC_->positionStateRBV(), &positionState);
|
||||
if (status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(status, "positionStateRBV_", axisNo_,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
// If the axis is in changer position, it must be moved into working
|
||||
// position before any move can be started.
|
||||
bool isInChangerPos = positionState == 2 || positionState == 3;
|
||||
if (pC_->getMsgPrintControl().shouldBePrinted(
|
||||
pC_->portName, axisNo(), __PRETTY_FUNCTION__, __LINE__,
|
||||
isInChangerPos, pC_->pasynUser())) {
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis cannot be "
|
||||
"moved because it is moving from working to changer "
|
||||
"position, is in changer position or is moving from changer "
|
||||
"to working position.%s\n",
|
||||
pC_->portName, axisNo(), __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->getMsgPrintControl().getSuffix());
|
||||
}
|
||||
|
||||
// Set the new adjust for the lift axis
|
||||
snprintf(command, sizeof(command), "Q656=%lf P350=6", newOrigin);
|
||||
|
||||
// We don't expect an answer
|
||||
status = pC_->writeRead(axisNo_, command, response, 0);
|
||||
|
||||
if (status != asynSuccess) {
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nSetting new "
|
||||
"lift origin %lf failed.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
newOrigin);
|
||||
status = setIntegerParam(pC_->motorStatusProblem(), true);
|
||||
if (status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(status, "motorStatusProblem_",
|
||||
axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -16,7 +16,8 @@ class detectorTowerLiftAxis : public turboPmacAxis {
|
||||
* @param pController Pointer to the associated controller
|
||||
* @param axisNo Index of the axis
|
||||
*/
|
||||
detectorTowerLiftAxis(detectorTowerController *pController, int axisNo);
|
||||
detectorTowerLiftAxis(detectorTowerController *pController, int axisNo,
|
||||
detectorTowerAngleAxis *angleAxis);
|
||||
|
||||
/**
|
||||
* @brief Destroy the turboPmacAxis
|
||||
@ -69,9 +70,9 @@ class detectorTowerLiftAxis : public turboPmacAxis {
|
||||
double max_velocity, double acceleration);
|
||||
|
||||
/**
|
||||
* @brief Call the reset function of the associated
|
||||
* `detectorTowerAngleAxis`.
|
||||
* @brief Calls the `reset` function of the associated lift axis.
|
||||
*
|
||||
* @param on
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus reset();
|
||||
@ -106,6 +107,13 @@ class detectorTowerLiftAxis : public turboPmacAxis {
|
||||
*/
|
||||
detectorTowerAngleAxis *angleAxis() { return angleAxis_; }
|
||||
|
||||
/**
|
||||
* @brief This axis type has an absolute encoder by default
|
||||
*
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus readEncoderType();
|
||||
|
||||
protected:
|
||||
detectorTowerController *pC_;
|
||||
detectorTowerAngleAxis *angleAxis_;
|
||||
|
232
src/detectorTowerSupportAxis.cpp
Normal file
232
src/detectorTowerSupportAxis.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
#include "detectorTowerSupportAxis.h"
|
||||
#include "detectorTowerAngleAxis.h"
|
||||
#include "detectorTowerController.h"
|
||||
#include "turboPmacController.h"
|
||||
#include <epicsExport.h>
|
||||
#include <errlog.h>
|
||||
#include <iocsh.h>
|
||||
|
||||
/*
|
||||
Contains all instances of detectorTowerSupportAxis which have been created and
|
||||
is used in the initialization hook function.
|
||||
*/
|
||||
static std::vector<detectorTowerSupportAxis *> axes;
|
||||
|
||||
/**
|
||||
* @brief Hook function to perform certain actions during the IOC initialization
|
||||
*
|
||||
* @param iState
|
||||
*/
|
||||
static void epicsInithookFunction(initHookState iState) {
|
||||
if (iState == initHookAfterDatabaseRunning) {
|
||||
// Iterate through all axes of each and call the initialization method
|
||||
// on each one of them.
|
||||
for (std::vector<detectorTowerSupportAxis *>::iterator itA =
|
||||
axes.begin();
|
||||
itA != axes.end(); ++itA) {
|
||||
detectorTowerSupportAxis *axis = *itA;
|
||||
axis->init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
detectorTowerSupportAxis::detectorTowerSupportAxis(
|
||||
detectorTowerController *pC, int axisNo, detectorTowerAngleAxis *angleAxis)
|
||||
: turboPmacAxis(pC, axisNo, false), pC_(pC) {
|
||||
|
||||
/*
|
||||
The superclass constructor sinqAxis calls in turn its superclass constructor
|
||||
asynMotorAxis. In the latter, a pointer to the constructed object this is
|
||||
stored inside the array pAxes_:
|
||||
|
||||
pC->pAxes_[axisNo] = this;
|
||||
|
||||
Therefore, the axes are managed by the controller pC. If axisNo is out of
|
||||
bounds, asynMotorAxis prints an error (see
|
||||
https://github.com/epics-modules/motor/blob/master/motorApp/MotorSrc/asynMotorAxis.cpp,
|
||||
line 40). However, we want the IOC creation to stop completely, since this
|
||||
is a configuration error.
|
||||
*/
|
||||
if (axisNo >= pC->numAxes()) {
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d: FATAL ERROR: "
|
||||
"Axis index %d must be smaller than the total number of axes "
|
||||
"%d",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
axisNo_, pC->numAxes());
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Register the hook function during construction of the first axis object
|
||||
if (axes.empty()) {
|
||||
initHookRegister(&epicsInithookFunction);
|
||||
}
|
||||
|
||||
// Collect all axes into this list which will be used in the hook
|
||||
// function
|
||||
axes.push_back(this);
|
||||
|
||||
// Link the axes to each other
|
||||
angleAxis_ = angleAxis;
|
||||
angleAxis_->supportAxis_ = this;
|
||||
}
|
||||
|
||||
detectorTowerSupportAxis::~detectorTowerSupportAxis(void) {
|
||||
// Since the controller memory is managed somewhere else, we don't need to
|
||||
// clean up the pointer pC here.
|
||||
}
|
||||
|
||||
asynStatus detectorTowerSupportAxis::init() {
|
||||
|
||||
// Local variable declaration
|
||||
asynStatus status = asynSuccess;
|
||||
double motorRecResolution = 0.0;
|
||||
char response[pC_->MAXBUF_] = {0};
|
||||
int positionState = 0;
|
||||
int nvals = 0;
|
||||
|
||||
// The parameter library takes some time to be initialized. Therefore we
|
||||
// wait until the status is not asynParamUndefined anymore.
|
||||
time_t now = time(NULL);
|
||||
time_t maxInitTime = 60;
|
||||
while (1) {
|
||||
status = pC_->getDoubleParam(axisNo_, pC_->motorRecResolution(),
|
||||
&motorRecResolution);
|
||||
if (status == asynParamUndefined) {
|
||||
if (now + maxInitTime < time(NULL)) {
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line "
|
||||
"%d\nInitializing the parameter library failed.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
return asynError;
|
||||
}
|
||||
} else if (status == asynSuccess) {
|
||||
break;
|
||||
} else if (status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(status, "motorRecResolution_",
|
||||
axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the motorStatusMoving flag
|
||||
status = setIntegerParam(pC_->motorStatusMoving(), 0);
|
||||
if (status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(status, "motorStatusMoving_", axisNo_,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
// Check if we are currently in the changer position and update the PV
|
||||
// accordingly
|
||||
status = pC_->writeRead(axisNo_, "P358", response, 1);
|
||||
nvals = sscanf(response, "%d", &positionState);
|
||||
if (nvals != 1) {
|
||||
return pC_->couldNotParseResponse("P358", response, axisNo(),
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
status = setIntegerParam(pC_->changeStateRBV(), positionState == 2);
|
||||
if (status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(status, "changeStateRBV", axisNo_,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
return callParamCallbacks();
|
||||
}
|
||||
|
||||
// Perform the actual poll
|
||||
asynStatus detectorTowerSupportAxis::poll(bool *moving) {
|
||||
|
||||
asynStatus status = asynSuccess;
|
||||
|
||||
// Is this axis the one with the smallest index?
|
||||
// If not, just read out the movement status and update *moving
|
||||
if (axisNo() < angleAxis()->liftAxis()->axisNo() &&
|
||||
axisNo() < angleAxis()->axisNo()) {
|
||||
status = pC_->pollDetectorAxes(moving, angleAxis(),
|
||||
angleAxis()->liftAxis(), this);
|
||||
} else {
|
||||
status = pC_->getIntegerParam(axisNo(), pC_->motorStatusMoving(),
|
||||
(int *)moving);
|
||||
if (status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(status, "motorStatusMoving",
|
||||
axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
}
|
||||
wasMoving_ = *moving;
|
||||
return status;
|
||||
}
|
||||
|
||||
asynStatus detectorTowerSupportAxis::doPoll(bool *moving) {
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nThe doPoll method "
|
||||
"of this axis type should not be reachable. This is a bug.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
return asynError;
|
||||
}
|
||||
|
||||
asynStatus detectorTowerSupportAxis::stop(double acceleration) {
|
||||
return angleAxis()->stop(acceleration);
|
||||
}
|
||||
|
||||
asynStatus detectorTowerSupportAxis::reset() { return angleAxis()->reset(); };
|
||||
|
||||
asynStatus detectorTowerSupportAxis::readEncoderType() {
|
||||
return angleAxis()->readEncoderType();
|
||||
}
|
||||
|
||||
asynStatus detectorTowerSupportAxis::adjustOrigin(double newOrigin) {
|
||||
|
||||
asynStatus status = asynSuccess;
|
||||
char command[pC_->MAXBUF_] = {0};
|
||||
char response[pC_->MAXBUF_] = {0};
|
||||
int positionState = 0;
|
||||
|
||||
// =========================================================================
|
||||
|
||||
status =
|
||||
pC_->getIntegerParam(axisNo_, pC_->positionStateRBV(), &positionState);
|
||||
if (status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(status, "positionStateRBV_", axisNo_,
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
// If the axis is in changer position, it must be moved into working
|
||||
// position before any move can be started.
|
||||
bool isInChangerPos = positionState == 2 || positionState == 3;
|
||||
if (pC_->getMsgPrintControl().shouldBePrinted(
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
isInChangerPos, pC_->pasynUser())) {
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis cannot be "
|
||||
"moved because it is moving from working to changer "
|
||||
"position, is in changer position or is moving from changer "
|
||||
"to working position.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->getMsgPrintControl().getSuffix());
|
||||
}
|
||||
|
||||
// Set the new adjust for the lift axis
|
||||
snprintf(command, sizeof(command), "Q656=%lf P350=6", newOrigin);
|
||||
|
||||
// We don't expect an answer
|
||||
status = pC_->writeRead(axisNo_, command, response, 0);
|
||||
|
||||
if (status != asynSuccess) {
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nSetting new "
|
||||
"lift origin %lf failed.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
newOrigin);
|
||||
status = setIntegerParam(pC_->motorStatusProblem(), true);
|
||||
if (status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(status, "motorStatusProblem_",
|
||||
axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
127
src/detectorTowerSupportAxis.h
Normal file
127
src/detectorTowerSupportAxis.h
Normal file
@ -0,0 +1,127 @@
|
||||
#ifndef detectorTowerSupportAxis_H
|
||||
#define detectorTowerSupportAxis_H
|
||||
#include "turboPmacAxis.h"
|
||||
|
||||
// Forward declaration of the controller class to resolve the cyclic dependency
|
||||
// between the controller and the axis .h-file. See
|
||||
// https://en.cppreference.com/w/cpp/language/class.
|
||||
class detectorTowerController;
|
||||
class detectorTowerAngleAxis;
|
||||
|
||||
/**
|
||||
* @brief Passive axis which is mostly controlled indirectly by the hardware
|
||||
*
|
||||
*/
|
||||
class detectorTowerSupportAxis : public turboPmacAxis {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new detectorTowerSupportAxis
|
||||
*
|
||||
* @param pController Pointer to the associated controller
|
||||
* @param axisNo Index of the axis
|
||||
* @param liftAxis Pointer to the associated lift axis
|
||||
*/
|
||||
detectorTowerSupportAxis(detectorTowerController *pController, int axisNo,
|
||||
detectorTowerAngleAxis *angleAxis);
|
||||
|
||||
/**
|
||||
* @brief Destroy the detectorTowerSupportAxis
|
||||
*
|
||||
*/
|
||||
virtual ~detectorTowerSupportAxis();
|
||||
|
||||
/**
|
||||
* @brief Readout of some values from the controller at IOC startup
|
||||
*
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus init();
|
||||
|
||||
/**
|
||||
* @brief Implementation of the `stop` function from asynMotorAxis
|
||||
*
|
||||
* @param acceleration Acceleration ACCEL from the motor record. This
|
||||
* value is currently not used.
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus stop(double acceleration);
|
||||
|
||||
/**
|
||||
* @brief Poll all detector tower axes, if this axis is the one with the
|
||||
* smallest index.
|
||||
*
|
||||
* We do not use the doPoll framework from sinqMotor here on purpose, since
|
||||
* we want to e.g. reset the motorStatusProblem for all axes at once at the
|
||||
* beginning of the poll.
|
||||
*
|
||||
* @param moving
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus poll(bool *moving);
|
||||
asynStatus doPoll(bool *moving);
|
||||
|
||||
/**
|
||||
* @brief This axis cannot be moved directly
|
||||
*
|
||||
* @param position
|
||||
* @param relative
|
||||
* @param min_velocity
|
||||
* @param max_velocity
|
||||
* @param acceleration
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus doMove(double position, int relative, double min_velocity,
|
||||
double max_velocity, double acceleration) {
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief If the input value is true, move the axis into working position,
|
||||
* otherwise into changer position.
|
||||
*
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus toggleWorkingChangerState(bool toChangingPosition);
|
||||
|
||||
/**
|
||||
* @brief Calls the `reset` function of the associated lift axis.
|
||||
*
|
||||
* @param on
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus reset();
|
||||
|
||||
/**
|
||||
* @brief Move the axis to the position `newOrigin` and recalibrate
|
||||
*
|
||||
* When calling this function, the angle axis moves to `newOrigin` and the
|
||||
* hardware sets this position as the new origin.
|
||||
*
|
||||
* @param origin
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus adjustOrigin(double newOrigin);
|
||||
|
||||
/**
|
||||
* @brief Return a pointer to the associated angle axis
|
||||
*
|
||||
* @return detectorTowerAngleAxis*
|
||||
*/
|
||||
detectorTowerAngleAxis *angleAxis() { return angleAxis_; }
|
||||
|
||||
/**
|
||||
* @brief This axis type has an absolute encoder by default
|
||||
*
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus readEncoderType();
|
||||
|
||||
protected:
|
||||
detectorTowerController *pC_;
|
||||
detectorTowerAngleAxis *angleAxis_;
|
||||
|
||||
private:
|
||||
friend class detectorTowerLiftAxis;
|
||||
};
|
||||
|
||||
#endif
|
Submodule turboPmac updated: 5298b5ef69...2f83060ec1
Reference in New Issue
Block a user