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/detectorTowerAngleAxis.h
|
||||||
HEADERS += src/detectorTowerController.h
|
HEADERS += src/detectorTowerController.h
|
||||||
HEADERS += src/detectorTowerLiftAxis.h
|
HEADERS += src/detectorTowerLiftAxis.h
|
||||||
|
HEADERS += src/detectorTowerSupportAxis.h
|
||||||
|
|
||||||
# Source files to build
|
# 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/turboPmacAxis.cpp
|
||||||
SOURCES += turboPmac/src/turboPmacController.cpp
|
SOURCES += turboPmac/src/turboPmacController.cpp
|
||||||
SOURCES += turboPmac/src/pmacAsynIPPort.c
|
SOURCES += turboPmac/src/pmacAsynIPPort.c
|
||||||
SOURCES += src/detectorTowerAngleAxis.cpp
|
SOURCES += src/detectorTowerAngleAxis.cpp
|
||||||
SOURCES += src/detectorTowerController.cpp
|
SOURCES += src/detectorTowerController.cpp
|
||||||
SOURCES += src/detectorTowerLiftAxis.cpp
|
SOURCES += src/detectorTowerLiftAxis.cpp
|
||||||
|
SOURCES += src/detectorTowerSupportAxis.cpp
|
||||||
|
|
||||||
# Store the record files
|
# Store the record files
|
||||||
TEMPLATES += turboPmac/sinqMotor/db/asynRecord.db
|
TEMPLATES += turboPmac/sinqMotor/db/asynRecord.db
|
||||||
|
@ -89,47 +89,6 @@ record(ao, "$(INSTR)$(M):WriteAO") {
|
|||||||
field(VAL, "0")
|
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_"
|
# This record pair reads the parameter library value for "AdjustOriginHighLimitFromDriver_"
|
||||||
# and pushes it to the high limit field of the "$(INSTR)$(M):AdjustOrigin" PV.
|
# 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.
|
# 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,
|
detectorTowerAngleAxis::detectorTowerAngleAxis(detectorTowerController *pC,
|
||||||
int axisNo,
|
int axisNo)
|
||||||
detectorTowerLiftAxis *liftAxis)
|
|
||||||
: turboPmacAxis(pC, axisNo, false), pC_(pC) {
|
: turboPmacAxis(pC, axisNo, false), pC_(pC) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -80,8 +79,6 @@ detectorTowerAngleAxis::detectorTowerAngleAxis(detectorTowerController *pC,
|
|||||||
receivedTarget_ = false;
|
receivedTarget_ = false;
|
||||||
startingDeferredMovement_ = false;
|
startingDeferredMovement_ = false;
|
||||||
deferredMovementWait_ = 0.1; // seconds
|
deferredMovementWait_ = 0.1; // seconds
|
||||||
liftAxis_ = liftAxis;
|
|
||||||
liftAxis_->angleAxis_ = this;
|
|
||||||
|
|
||||||
// Will be populated in the init() method
|
// Will be populated in the init() method
|
||||||
beamRadius_ = 0.0;
|
beamRadius_ = 0.0;
|
||||||
@ -117,6 +114,7 @@ asynStatus detectorTowerAngleAxis::init() {
|
|||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
double motorRecResolution = 0.0;
|
double motorRecResolution = 0.0;
|
||||||
char response[pC_->MAXBUF_] = {0};
|
char response[pC_->MAXBUF_] = {0};
|
||||||
|
int positionState = 0;
|
||||||
int nvals = 0;
|
int nvals = 0;
|
||||||
|
|
||||||
// The parameter library takes some time to be initialized. Therefore we
|
// The parameter library takes some time to be initialized. Therefore we
|
||||||
@ -146,14 +144,14 @@ asynStatus detectorTowerAngleAxis::init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read the detector radius
|
// Read the detector radius
|
||||||
const char *command = "P459";
|
const char *command = "P459 P358";
|
||||||
status = pC_->writeRead(axisNo_, command, response, 1);
|
status = pC_->writeRead(axisNo_, command, response, 2);
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
nvals = sscanf(response, "%lf", &beamRadius_);
|
nvals = sscanf(response, "%lf %d", &beamRadius_, &positionState);
|
||||||
if (nvals != 1) {
|
if (nvals != 2) {
|
||||||
return pC_->couldNotParseResponse(command, response, axisNo_,
|
return pC_->couldNotParseResponse(command, response, axisNo_,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
@ -165,7 +163,13 @@ asynStatus detectorTowerAngleAxis::init() {
|
|||||||
__PRETTY_FUNCTION__, __LINE__);
|
__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
|
// Perform the actual poll
|
||||||
@ -174,8 +178,8 @@ asynStatus detectorTowerAngleAxis::poll(bool *moving) {
|
|||||||
|
|
||||||
// Is this axis the one with the smallest index?
|
// Is this axis the one with the smallest index?
|
||||||
// If not, just read out the movement status and update *moving
|
// If not, just read out the movement status and update *moving
|
||||||
if (axisNo() < liftAxis_->axisNo()) {
|
if (axisNo() < liftAxis()->axisNo() && axisNo() < supportAxis()->axisNo()) {
|
||||||
status = pC_->pollDetectorAxes(moving, this, liftAxis_);
|
status = pC_->pollDetectorAxes(moving, this, liftAxis(), supportAxis());
|
||||||
} else {
|
} else {
|
||||||
status = pC_->getIntegerParam(axisNo(), pC_->motorStatusMoving(),
|
status = pC_->getIntegerParam(axisNo(), pC_->motorStatusMoving(),
|
||||||
(int *)moving);
|
(int *)moving);
|
||||||
@ -255,6 +259,23 @@ asynStatus detectorTowerAngleAxis::startCombinedMove() {
|
|||||||
pC_->getMsgPrintControl().getSuffix());
|
pC_->getMsgPrintControl().getSuffix());
|
||||||
}
|
}
|
||||||
if (isInChangerPos) {
|
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;
|
startingDeferredMovement_ = false;
|
||||||
return asynError;
|
return asynError;
|
||||||
}
|
}
|
||||||
@ -287,6 +308,7 @@ asynStatus detectorTowerAngleAxis::startCombinedMove() {
|
|||||||
axisNo_, __PRETTY_FUNCTION__,
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
__LINE__);
|
__LINE__);
|
||||||
}
|
}
|
||||||
|
callParamCallbacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
return rwStatus;
|
return rwStatus;
|
||||||
@ -416,13 +438,10 @@ detectorTowerAngleAxis::toggleWorkingChangerState(bool toChangingPosition) {
|
|||||||
// Move the axis into changer or working position
|
// Move the axis into changer or working position
|
||||||
if (toChangingPosition) {
|
if (toChangingPosition) {
|
||||||
rwStatus = pC_->writeRead(axisNo_, "P350=2", response, 0);
|
rwStatus = pC_->writeRead(axisNo_, "P350=2", response, 0);
|
||||||
plStatus = setStringParam(pC_->motorMessageText(),
|
|
||||||
"Moving to changer position ...");
|
|
||||||
} else {
|
} else {
|
||||||
rwStatus = pC_->writeRead(axisNo_, "P350=3", response, 0);
|
rwStatus = pC_->writeRead(axisNo_, "P350=3", response, 0);
|
||||||
plStatus = setStringParam(pC_->motorMessageText(),
|
|
||||||
"Moving to working state ...");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plStatus != asynSuccess) {
|
if (plStatus != asynSuccess) {
|
||||||
plStatus = setIntegerParam(pC_->changeStateRBV(), !toChangingPosition);
|
plStatus = setIntegerParam(pC_->changeStateRBV(), !toChangingPosition);
|
||||||
if (plStatus != asynSuccess) {
|
if (plStatus != asynSuccess) {
|
||||||
@ -444,34 +463,6 @@ detectorTowerAngleAxis::toggleWorkingChangerState(bool toChangingPosition) {
|
|||||||
return rwStatus;
|
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 detectorTowerAngleAxis::adjustOrigin(double newOrigin) {
|
||||||
|
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
@ -526,6 +517,34 @@ asynStatus detectorTowerAngleAxis::adjustOrigin(double newOrigin) {
|
|||||||
return status;
|
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
|
/** The following functions are C-wrappers, and can be called directly from
|
||||||
* iocsh */
|
* 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.
|
constructor documentation. The controller is read from the portName.
|
||||||
*/
|
*/
|
||||||
asynStatus detectorTowerCreateAxis(const char *portName, int angleAxisIdx,
|
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.
|
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.
|
be "leaked" here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
detectorTowerLiftAxis *liftAxis =
|
detectorTowerAngleAxis *angleAxis =
|
||||||
new detectorTowerLiftAxis(pC, liftAxisIdx);
|
new detectorTowerAngleAxis(pC, angleAxisIdx);
|
||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||||
detectorTowerAngleAxis *pAxis =
|
detectorTowerLiftAxis *liftAxis =
|
||||||
new detectorTowerAngleAxis(pC, angleAxisIdx, 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
|
// Allow manipulation of the controller again
|
||||||
pC->unlock();
|
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",
|
static const iocshArg CreateAxisArg1 = {"Number of the detector angle axis",
|
||||||
iocshArgInt};
|
iocshArgInt};
|
||||||
static const iocshArg CreateAxisArg2 = {"Number of the lift 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[] = {
|
static const iocshArg *const CreateAxisArgs[] = {
|
||||||
&CreateAxisArg0,
|
&CreateAxisArg0,
|
||||||
&CreateAxisArg1,
|
&CreateAxisArg1,
|
||||||
&CreateAxisArg2,
|
&CreateAxisArg2,
|
||||||
|
&CreateAxisArg3,
|
||||||
};
|
};
|
||||||
static const iocshFuncDef configDetectorTowerCreateAxis = {"detectorTowerAxis",
|
static const iocshFuncDef configDetectorTowerCreateAxis = {"detectorTowerAxis",
|
||||||
3, CreateAxisArgs};
|
4, CreateAxisArgs};
|
||||||
static void configDetectorTowerCreateAxisCallFunc(const iocshArgBuf *args) {
|
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
|
#ifndef detectorTowerAngleAxis_H
|
||||||
#define detectorTowerAngleAxis_H
|
#define detectorTowerAngleAxis_H
|
||||||
#include "detectorTowerLiftAxis.h"
|
|
||||||
#include "turboPmacAxis.h"
|
#include "turboPmacAxis.h"
|
||||||
|
|
||||||
// Forward declaration of the controller class to resolve the cyclic dependency
|
// Forward declaration of the controller class to resolve the cyclic dependency
|
||||||
// between the controller and the axis .h-file. See
|
// between the controller and the axis .h-file. See
|
||||||
// https://en.cppreference.com/w/cpp/language/class.
|
// https://en.cppreference.com/w/cpp/language/class.
|
||||||
class detectorTowerController;
|
class detectorTowerController;
|
||||||
|
class detectorTowerLiftAxis;
|
||||||
|
class detectorTowerSupportAxis;
|
||||||
|
|
||||||
class detectorTowerAngleAxis : public turboPmacAxis {
|
class detectorTowerAngleAxis : public turboPmacAxis {
|
||||||
public:
|
public:
|
||||||
@ -15,13 +16,9 @@ class detectorTowerAngleAxis : public turboPmacAxis {
|
|||||||
*
|
*
|
||||||
* @param pController Pointer to the associated controller
|
* @param pController Pointer to the associated controller
|
||||||
* @param axisNo Index of the axis
|
* @param axisNo Index of the axis
|
||||||
* @param liftZeroCorrAxis Pointer to the attached axis which controls
|
* @param liftAxis Pointer to the associated lift axis
|
||||||
* the lift offset
|
|
||||||
* @param tiltZeroCorrAxis Pointer to the attached axis which controls
|
|
||||||
* the tilt offset
|
|
||||||
*/
|
*/
|
||||||
detectorTowerAngleAxis(detectorTowerController *pController, int axisNo,
|
detectorTowerAngleAxis(detectorTowerController *pController, int axisNo);
|
||||||
detectorTowerLiftAxis *liftAxis);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Destroy the detectorTowerAngleAxis
|
* @brief Destroy the detectorTowerAngleAxis
|
||||||
@ -99,7 +96,6 @@ class detectorTowerAngleAxis : public turboPmacAxis {
|
|||||||
/**
|
/**
|
||||||
* @brief Implementation of the `doReset` method of sinqAxis
|
* @brief Implementation of the `doReset` method of sinqAxis
|
||||||
*
|
*
|
||||||
* @param on
|
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus doReset();
|
asynStatus doReset();
|
||||||
@ -129,6 +125,13 @@ class detectorTowerAngleAxis : public turboPmacAxis {
|
|||||||
*/
|
*/
|
||||||
detectorTowerLiftAxis *liftAxis() { return liftAxis_; }
|
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
|
// If true, either this axis or one of the detectorTowerLiftAxis
|
||||||
// attached to it received a movement command.
|
// attached to it received a movement command.
|
||||||
bool receivedTarget_;
|
bool receivedTarget_;
|
||||||
@ -153,10 +156,12 @@ class detectorTowerAngleAxis : public turboPmacAxis {
|
|||||||
protected:
|
protected:
|
||||||
detectorTowerController *pC_;
|
detectorTowerController *pC_;
|
||||||
detectorTowerLiftAxis *liftAxis_;
|
detectorTowerLiftAxis *liftAxis_;
|
||||||
|
detectorTowerSupportAxis *supportAxis_;
|
||||||
double beamRadius_;
|
double beamRadius_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class detectorTowerLiftAxis;
|
friend class detectorTowerLiftAxis;
|
||||||
|
friend class detectorTowerSupportAxis;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -104,43 +104,26 @@ detectorTowerController::detectorTowerController(
|
|||||||
stringifyAsynStatus(status));
|
stringifyAsynStatus(status));
|
||||||
exit(-1);
|
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,
|
asynStatus detectorTowerController::readInt32(asynUser *pasynUser,
|
||||||
epicsInt32 *value) {
|
epicsInt32 *value) {
|
||||||
|
|
||||||
// The detector tower or its auxiliary axes cannot be disabled
|
// The detector axes cannot be disabled
|
||||||
if (pasynUser->reason == motorCanDisable_) {
|
if (pasynUser->reason == motorCanDisable_) {
|
||||||
detectorTowerAngleAxis *angleAxis =
|
detectorTowerAngleAxis *aAxis = getDetectorTowerAngleAxis(pasynUser);
|
||||||
getDetectorTowerAngleAxis(pasynUser);
|
if (aAxis != nullptr) {
|
||||||
if (angleAxis != nullptr) {
|
|
||||||
*value = 0;
|
*value = 0;
|
||||||
return asynSuccess;
|
return asynSuccess;
|
||||||
}
|
}
|
||||||
detectorTowerLiftAxis *liftAxis = getDetectorTowerLiftAxis(pasynUser);
|
detectorTowerLiftAxis *lAxis = getDetectorTowerLiftAxis(pasynUser);
|
||||||
if (liftAxis != nullptr) {
|
if (lAxis != nullptr) {
|
||||||
|
*value = 0;
|
||||||
|
return asynSuccess;
|
||||||
|
}
|
||||||
|
detectorTowerSupportAxis *sAxis =
|
||||||
|
getDetectorTowerSupportAxis(pasynUser);
|
||||||
|
if (sAxis != nullptr) {
|
||||||
*value = 0;
|
*value = 0;
|
||||||
return asynSuccess;
|
return asynSuccess;
|
||||||
}
|
}
|
||||||
@ -151,17 +134,19 @@ asynStatus detectorTowerController::readInt32(asynUser *pasynUser,
|
|||||||
asynStatus detectorTowerController::writeInt32(asynUser *pasynUser,
|
asynStatus detectorTowerController::writeInt32(asynUser *pasynUser,
|
||||||
epicsInt32 value) {
|
epicsInt32 value) {
|
||||||
|
|
||||||
// =====================================================================
|
|
||||||
|
|
||||||
if (pasynUser->reason == changeState_) {
|
if (pasynUser->reason == changeState_) {
|
||||||
detectorTowerAngleAxis *angleAxis =
|
detectorTowerAngleAxis *aAxis = getDetectorTowerAngleAxis(pasynUser);
|
||||||
getDetectorTowerAngleAxis(pasynUser);
|
if (aAxis != nullptr) {
|
||||||
if (angleAxis != nullptr) {
|
return aAxis->toggleWorkingChangerState(value);
|
||||||
return angleAxis->toggleWorkingChangerState(value);
|
|
||||||
}
|
}
|
||||||
detectorTowerLiftAxis *liftAxis = getDetectorTowerLiftAxis(pasynUser);
|
detectorTowerLiftAxis *lAxis = getDetectorTowerLiftAxis(pasynUser);
|
||||||
if (liftAxis != nullptr) {
|
if (lAxis != nullptr) {
|
||||||
return liftAxis->angleAxis()->toggleWorkingChangerState(value);
|
return lAxis->angleAxis()->toggleWorkingChangerState(value);
|
||||||
|
}
|
||||||
|
detectorTowerSupportAxis *sAxis =
|
||||||
|
getDetectorTowerSupportAxis(pasynUser);
|
||||||
|
if (sAxis != nullptr) {
|
||||||
|
return sAxis->angleAxis()->toggleWorkingChangerState(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return turboPmacController::writeInt32(pasynUser, value);
|
return turboPmacController::writeInt32(pasynUser, value);
|
||||||
@ -176,7 +161,7 @@ asynStatus detectorTowerController::writeFloat64(asynUser *pasynUser,
|
|||||||
|
|
||||||
if (function == motorAdjustOrigin_) {
|
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);
|
detectorTowerAngleAxis *aAxis = getDetectorTowerAngleAxis(pasynUser);
|
||||||
if (aAxis != nullptr) {
|
if (aAxis != nullptr) {
|
||||||
status = aAxis->adjustOrigin(value);
|
status = aAxis->adjustOrigin(value);
|
||||||
@ -184,7 +169,8 @@ asynStatus detectorTowerController::writeFloat64(asynUser *pasynUser,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
return turboPmacController::writeFloat64(pasynUser, value);
|
return turboPmacController::writeFloat64(pasynUser, value);
|
||||||
} else {
|
}
|
||||||
|
|
||||||
detectorTowerLiftAxis *lAxis = getDetectorTowerLiftAxis(pasynUser);
|
detectorTowerLiftAxis *lAxis = getDetectorTowerLiftAxis(pasynUser);
|
||||||
if (lAxis != nullptr) {
|
if (lAxis != nullptr) {
|
||||||
status = lAxis->adjustOrigin(value);
|
status = lAxis->adjustOrigin(value);
|
||||||
@ -193,17 +179,17 @@ asynStatus detectorTowerController::writeFloat64(asynUser *pasynUser,
|
|||||||
}
|
}
|
||||||
return turboPmacController::writeFloat64(pasynUser, value);
|
return turboPmacController::writeFloat64(pasynUser, value);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return asynSuccess;
|
detectorTowerSupportAxis *sAxis =
|
||||||
} else if (function == liftSupportAdjustOrigin_) {
|
getDetectorTowerSupportAxis(pasynUser);
|
||||||
detectorTowerLiftAxis *lAxis = getDetectorTowerLiftAxis(pasynUser);
|
if (sAxis != nullptr) {
|
||||||
if (lAxis != nullptr) {
|
status = sAxis->adjustOrigin(value);
|
||||||
status = lAxis->adjustSupportOrigin(value);
|
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
return turboPmacController::writeFloat64(pasynUser, value);
|
return turboPmacController::writeFloat64(pasynUser, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return asynSuccess;
|
return asynSuccess;
|
||||||
} else {
|
} else {
|
||||||
return turboPmacController::writeFloat64(pasynUser, value);
|
return turboPmacController::writeFloat64(pasynUser, value);
|
||||||
@ -252,10 +238,30 @@ detectorTowerController::getDetectorTowerLiftAxis(int axisNo) {
|
|||||||
return dynamic_cast<detectorTowerLiftAxis *>(asynAxis);
|
return dynamic_cast<detectorTowerLiftAxis *>(asynAxis);
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus
|
/*
|
||||||
detectorTowerController::pollDetectorAxes(bool *moving,
|
Access one of the axes of the controller via the axis adress stored in asynUser.
|
||||||
detectorTowerAngleAxis *angleAxis,
|
If the axis does not exist or is not a Axis, a nullptr is returned and an
|
||||||
detectorTowerLiftAxis *liftAxis) {
|
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
|
// Return value for the poll
|
||||||
asynStatus pollStatus = asynSuccess;
|
asynStatus pollStatus = asynSuccess;
|
||||||
@ -267,6 +273,8 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
asynStatus plStatus = asynSuccess;
|
asynStatus plStatus = asynSuccess;
|
||||||
|
|
||||||
char userMessage[MAXBUF_] = {0};
|
char userMessage[MAXBUF_] = {0};
|
||||||
|
// User message which was created in one of the other axis methods
|
||||||
|
char oldUserMessage[MAXBUF_] = {0};
|
||||||
char response[MAXBUF_] = {0};
|
char response[MAXBUF_] = {0};
|
||||||
int nvals = 0;
|
int nvals = 0;
|
||||||
|
|
||||||
@ -292,20 +300,26 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
double liftAdjustOriginHighLimit = 0.0;
|
double liftAdjustOriginHighLimit = 0.0;
|
||||||
double liftAdjustOriginLowLimit = 0.0;
|
double liftAdjustOriginLowLimit = 0.0;
|
||||||
|
|
||||||
double supportOrigin = 0.0;
|
|
||||||
|
|
||||||
double angleOrigin = 0.0;
|
double angleOrigin = 0.0;
|
||||||
double angleAdjustOriginHighLimit = 0.0;
|
double angleAdjustOriginHighLimit = 0.0;
|
||||||
double angleAdjustOriginLowLimit = 0.0;
|
double angleAdjustOriginLowLimit = 0.0;
|
||||||
|
|
||||||
|
double supportOrigin = 0.0;
|
||||||
|
|
||||||
int angleAxisNo = angleAxis->axisNo();
|
int angleAxisNo = angleAxis->axisNo();
|
||||||
int liftAxisNo = liftAxis->axisNo();
|
int liftAxisNo = liftAxis->axisNo();
|
||||||
|
int supportAxisNo = supportAxis->axisNo();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
For messages which in principle concern both axes, use the smaller of the
|
For messages which in principle concern all axes, use the smallest index
|
||||||
two indices.
|
|
||||||
*/
|
*/
|
||||||
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,
|
paramLibAccessFailed(plStatus, "motorStatusProblem_", liftAxisNo,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
plStatus = supportAxis->setIntegerParam(motorStatusProblem(), false);
|
||||||
|
if (plStatus != asynSuccess) {
|
||||||
|
paramLibAccessFailed(plStatus, "motorStatusProblem_", supportAxisNo,
|
||||||
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
plStatus = angleAxis->setIntegerParam(motorStatusCommsError(), false);
|
plStatus = angleAxis->setIntegerParam(motorStatusCommsError(), false);
|
||||||
if (plStatus != asynSuccess) {
|
if (plStatus != asynSuccess) {
|
||||||
@ -340,6 +359,11 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
paramLibAccessFailed(plStatus, "motorStatusCommsError_", liftAxisNo,
|
paramLibAccessFailed(plStatus, "motorStatusCommsError_", liftAxisNo,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
plStatus = supportAxis->setIntegerParam(motorStatusCommsError(), false);
|
||||||
|
if (plStatus != asynSuccess) {
|
||||||
|
paramLibAccessFailed(plStatus, "motorStatusCommsError_", supportAxisNo,
|
||||||
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
// Read the previous motor positions
|
// Read the previous motor positions
|
||||||
plStatus = angleAxis->motorPosition(&prevAngle);
|
plStatus = angleAxis->motorPosition(&prevAngle);
|
||||||
@ -458,13 +482,9 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
}
|
}
|
||||||
resetCountPosState = false;
|
resetCountPosState = false;
|
||||||
|
|
||||||
plStatus =
|
snprintf(userMessage, sizeof(userMessage),
|
||||||
setStringParam(motorMessageText(), "Reset one of the tower axes.");
|
"Reset one of the tower axes."
|
||||||
if (plStatus != asynSuccess) {
|
);
|
||||||
return paramLibAccessFailed(plStatus, "motorMessageText_",
|
|
||||||
comAxisNo, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
pollStatus = asynError;
|
pollStatus = asynError;
|
||||||
break;
|
break;
|
||||||
@ -504,12 +524,6 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
"Unknown state P358 = %d has been reached. Please call "
|
"Unknown state P358 = %d has been reached. Please call "
|
||||||
"the support.",
|
"the support.",
|
||||||
positionState);
|
positionState);
|
||||||
plStatus = setStringParam(motorMessageText(), userMessage);
|
|
||||||
if (plStatus != asynSuccess) {
|
|
||||||
return paramLibAccessFailed(plStatus, "motorMessageText_",
|
|
||||||
comAxisNo, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
pollStatus = asynError;
|
pollStatus = asynError;
|
||||||
}
|
}
|
||||||
@ -627,12 +641,6 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
"Axis release was removed while moving. Try resetting the axis "
|
"Axis release was removed while moving. Try resetting the axis "
|
||||||
"and issue the move command again.");
|
"and issue the move command again.");
|
||||||
|
|
||||||
if (plStatus != asynSuccess) {
|
|
||||||
return paramLibAccessFailed(plStatus, "motorMessageText_",
|
|
||||||
comAxisNo, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
pollStatus = asynError;
|
pollStatus = asynError;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -797,8 +805,13 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
getMsgPrintControl().resetCount(keyError, pasynUser());
|
getMsgPrintControl().resetCount(keyError, pasynUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the parameter library for both axes
|
// Update the parameter library for all axes
|
||||||
if (error != 0) {
|
|
||||||
|
|
||||||
|
|
||||||
|
getStringParam(angleAxisNo, motorMessageText(), sizeof(oldUserMessage), oldUserMessage);
|
||||||
|
|
||||||
|
if (error != 0 || oldUserMessage[0] != '\0') {
|
||||||
|
|
||||||
plStatus = angleAxis->setIntegerParam(motorStatusProblem(), true);
|
plStatus = angleAxis->setIntegerParam(motorStatusProblem(), true);
|
||||||
if (plStatus != asynSuccess) {
|
if (plStatus != asynSuccess) {
|
||||||
@ -813,9 +826,17 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
liftAxisNo, __PRETTY_FUNCTION__,
|
liftAxisNo, __PRETTY_FUNCTION__,
|
||||||
__LINE__);
|
__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);
|
plStatus = angleAxis->setStringParam(motorMessageText(), userMessage);
|
||||||
if (plStatus != asynSuccess) {
|
if (plStatus != asynSuccess) {
|
||||||
return paramLibAccessFailed(plStatus, "motorMessageText_", angleAxisNo,
|
return paramLibAccessFailed(plStatus, "motorMessageText_", angleAxisNo,
|
||||||
@ -826,6 +847,13 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
return paramLibAccessFailed(plStatus, "motorMessageText_", liftAxisNo,
|
return paramLibAccessFailed(plStatus, "motorMessageText_", liftAxisNo,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__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
|
// Update the working position state PV
|
||||||
plStatus = angleAxis->setIntegerParam(positionStateRBV(), positionState);
|
plStatus = angleAxis->setIntegerParam(positionStateRBV(), positionState);
|
||||||
@ -838,6 +866,12 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
return paramLibAccessFailed(plStatus, "positionStateRBV_", liftAxisNo,
|
return paramLibAccessFailed(plStatus, "positionStateRBV_", liftAxisNo,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
plStatus = supportAxis->setIntegerParam(positionStateRBV(), positionState);
|
||||||
|
if (plStatus != asynSuccess) {
|
||||||
|
return paramLibAccessFailed(plStatus, "positionStateRBV_",
|
||||||
|
supportAxisNo, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
// The axes are always enabled
|
// The axes are always enabled
|
||||||
plStatus = angleAxis->setIntegerParam(motorEnableRBV(), 1);
|
plStatus = angleAxis->setIntegerParam(motorEnableRBV(), 1);
|
||||||
@ -850,6 +884,11 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
return paramLibAccessFailed(plStatus, "motorEnableRBV_", liftAxisNo,
|
return paramLibAccessFailed(plStatus, "motorEnableRBV_", liftAxisNo,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
plStatus = supportAxis->setIntegerParam(motorEnableRBV(), 1);
|
||||||
|
if (plStatus != asynSuccess) {
|
||||||
|
return paramLibAccessFailed(plStatus, "motorEnableRBV_", supportAxisNo,
|
||||||
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
// Are the axes currently moving?
|
// Are the axes currently moving?
|
||||||
plStatus = angleAxis->setIntegerParam(motorStatusMoving(), *moving);
|
plStatus = angleAxis->setIntegerParam(motorStatusMoving(), *moving);
|
||||||
@ -862,6 +901,12 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
return paramLibAccessFailed(plStatus, "motorStatusMoving_", liftAxisNo,
|
return paramLibAccessFailed(plStatus, "motorStatusMoving_", liftAxisNo,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
plStatus = supportAxis->setIntegerParam(motorStatusMoving(), *moving);
|
||||||
|
if (plStatus != asynSuccess) {
|
||||||
|
return paramLibAccessFailed(plStatus, "motorStatusMoving_",
|
||||||
|
supportAxisNo, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
// Is the axis movement done?
|
// Is the axis movement done?
|
||||||
plStatus = angleAxis->setIntegerParam(motorStatusDone(), !(*moving));
|
plStatus = angleAxis->setIntegerParam(motorStatusDone(), !(*moving));
|
||||||
@ -874,8 +919,13 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
return paramLibAccessFailed(plStatus, "motorStatusDone_", liftAxisNo,
|
return paramLibAccessFailed(plStatus, "motorStatusDone_", liftAxisNo,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__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);
|
plStatus = angleAxis->setIntegerParam(motorStatusDirection(), angleDir);
|
||||||
if (plStatus != asynSuccess) {
|
if (plStatus != asynSuccess) {
|
||||||
return paramLibAccessFailed(plStatus, "motorStatusDirection_",
|
return paramLibAccessFailed(plStatus, "motorStatusDirection_",
|
||||||
@ -886,6 +936,13 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
return paramLibAccessFailed(plStatus, "motorStatusDirection_",
|
return paramLibAccessFailed(plStatus, "motorStatusDirection_",
|
||||||
liftAxisNo, __PRETTY_FUNCTION__, __LINE__);
|
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
|
// High limits from hardware
|
||||||
plStatus =
|
plStatus =
|
||||||
@ -900,6 +957,14 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
return paramLibAccessFailed(plStatus, "motorHighLimitFromDriver",
|
return paramLibAccessFailed(plStatus, "motorHighLimitFromDriver",
|
||||||
liftAxisNo, __PRETTY_FUNCTION__, __LINE__);
|
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
|
// Low limits from hardware
|
||||||
plStatus =
|
plStatus =
|
||||||
@ -914,6 +979,14 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
return paramLibAccessFailed(plStatus, "motorLowLimitFromDriver",
|
return paramLibAccessFailed(plStatus, "motorLowLimitFromDriver",
|
||||||
liftAxisNo, __PRETTY_FUNCTION__, __LINE__);
|
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
|
// Write the motor origin
|
||||||
plStatus = setDoubleParam(angleAxisNo, motorOrigin(), angleOrigin);
|
plStatus = setDoubleParam(angleAxisNo, motorOrigin(), angleOrigin);
|
||||||
@ -926,11 +999,9 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
return paramLibAccessFailed(plStatus, "motorOrigin", liftAxisNo,
|
return paramLibAccessFailed(plStatus, "motorOrigin", liftAxisNo,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
plStatus = setDoubleParam(supportAxisNo, motorOrigin(), supportOrigin);
|
||||||
// Write the lift support origin motor
|
|
||||||
plStatus = setDoubleParam(liftAxisNo, liftSupportOrigin(), supportOrigin);
|
|
||||||
if (plStatus != asynSuccess) {
|
if (plStatus != asynSuccess) {
|
||||||
return paramLibAccessFailed(plStatus, "liftSupportOrigin", liftAxisNo,
|
return paramLibAccessFailed(plStatus, "supportOrigin", supportAxisNo,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -949,6 +1020,15 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
return paramLibAccessFailed(plStatus, "motorOriginHighLimitFromDriver",
|
return paramLibAccessFailed(plStatus, "motorOriginHighLimitFromDriver",
|
||||||
liftAxisNo, __PRETTY_FUNCTION__, __LINE__);
|
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
|
// Origin adjustment low limit
|
||||||
plStatus =
|
plStatus =
|
||||||
@ -966,6 +1046,15 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
"motorAdjustOriginLowLimitFromDriver",
|
"motorAdjustOriginLowLimitFromDriver",
|
||||||
liftAxisNo, __PRETTY_FUNCTION__, __LINE__);
|
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
|
// Axes positions
|
||||||
plStatus = angleAxis->setMotorPosition(angle);
|
plStatus = angleAxis->setMotorPosition(angle);
|
||||||
@ -976,22 +1065,13 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
if (plStatus != asynSuccess) {
|
if (plStatus != asynSuccess) {
|
||||||
return plStatus;
|
return plStatus;
|
||||||
}
|
}
|
||||||
|
// Using the lift position for the support axis is done on purpose!
|
||||||
// Something went wrong -> Report a status problem
|
plStatus = supportAxis->setMotorPosition(lift);
|
||||||
if (pollStatus != asynSuccess) {
|
|
||||||
plStatus = angleAxis->setIntegerParam(motorStatusProblem(), true);
|
|
||||||
if (plStatus != asynSuccess) {
|
if (plStatus != asynSuccess) {
|
||||||
paramLibAccessFailed(plStatus, "motorStatusProblem_", angleAxisNo,
|
return plStatus;
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
|
||||||
}
|
|
||||||
plStatus = liftAxis->setIntegerParam(motorStatusProblem(), true);
|
|
||||||
if (plStatus != asynSuccess) {
|
|
||||||
paramLibAccessFailed(plStatus, "motorStatusProblem_", liftAxisNo,
|
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the parameter library
|
// Update the parameter library for all three axes
|
||||||
bool wantToPrint = false;
|
bool wantToPrint = false;
|
||||||
|
|
||||||
plStatus = angleAxis->callParamCallbacks();
|
plStatus = angleAxis->callParamCallbacks();
|
||||||
@ -1009,6 +1089,7 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
if (wantToPrint) {
|
if (wantToPrint) {
|
||||||
pollStatus = plStatus;
|
pollStatus = plStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
plStatus = liftAxis->callParamCallbacks();
|
plStatus = liftAxis->callParamCallbacks();
|
||||||
wantToPrint = plStatus != asynSuccess;
|
wantToPrint = plStatus != asynSuccess;
|
||||||
if (getMsgPrintControl().shouldBePrinted(portName, liftAxisNo,
|
if (getMsgPrintControl().shouldBePrinted(portName, liftAxisNo,
|
||||||
@ -1025,6 +1106,40 @@ detectorTowerController::pollDetectorAxes(bool *moving,
|
|||||||
pollStatus = plStatus;
|
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;
|
return pollStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#define detectorTowerController_H
|
#define detectorTowerController_H
|
||||||
#include "detectorTowerAngleAxis.h"
|
#include "detectorTowerAngleAxis.h"
|
||||||
#include "detectorTowerLiftAxis.h"
|
#include "detectorTowerLiftAxis.h"
|
||||||
|
#include "detectorTowerSupportAxis.h"
|
||||||
#include "turboPmacController.h"
|
#include "turboPmacController.h"
|
||||||
|
|
||||||
class detectorTowerController : public turboPmacController {
|
class detectorTowerController : public turboPmacController {
|
||||||
@ -97,6 +98,24 @@ class detectorTowerController : public turboPmacController {
|
|||||||
*/
|
*/
|
||||||
detectorTowerLiftAxis *getDetectorTowerLiftAxis(int axisNo);
|
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
|
* @brief Common poll function for both lift and angle axes
|
||||||
*
|
*
|
||||||
@ -106,7 +125,8 @@ class detectorTowerController : public turboPmacController {
|
|||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus pollDetectorAxes(bool *moving, detectorTowerAngleAxis *angleAxis,
|
asynStatus pollDetectorAxes(bool *moving, detectorTowerAngleAxis *angleAxis,
|
||||||
detectorTowerLiftAxis *liftAxis);
|
detectorTowerLiftAxis *liftAxis,
|
||||||
|
detectorTowerSupportAxis *supportAxis);
|
||||||
|
|
||||||
// Accessors for additional PVs
|
// Accessors for additional PVs
|
||||||
int positionStateRBV() { return positionStateRBV_; }
|
int positionStateRBV() { return positionStateRBV_; }
|
||||||
@ -120,8 +140,6 @@ class detectorTowerController : public turboPmacController {
|
|||||||
int motorAdjustOriginLowLimitFromDriver() {
|
int motorAdjustOriginLowLimitFromDriver() {
|
||||||
return motorAdjustOriginLowLimitFromDriver_;
|
return motorAdjustOriginLowLimitFromDriver_;
|
||||||
}
|
}
|
||||||
int liftSupportOrigin() { return liftSupportOrigin_; }
|
|
||||||
int liftSupportAdjustOrigin() { return liftSupportAdjustOrigin_; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Indices of additional PVs
|
// Indices of additional PVs
|
||||||
@ -133,9 +151,7 @@ class detectorTowerController : public turboPmacController {
|
|||||||
int motorAdjustOrigin_;
|
int motorAdjustOrigin_;
|
||||||
int motorAdjustOriginHighLimitFromDriver_;
|
int motorAdjustOriginHighLimitFromDriver_;
|
||||||
int motorAdjustOriginLowLimitFromDriver_;
|
int motorAdjustOriginLowLimitFromDriver_;
|
||||||
int liftSupportOrigin_;
|
#define LAST_detectorTower_PARAM motorAdjustOriginLowLimitFromDriver_
|
||||||
int liftSupportAdjustOrigin_;
|
|
||||||
#define LAST_detectorTower_PARAM liftSupportAdjustOrigin_
|
|
||||||
};
|
};
|
||||||
#define NUM_detectorTower_DRIVER_PARAMS \
|
#define NUM_detectorTower_DRIVER_PARAMS \
|
||||||
(&LAST_detectorTower_PARAM - &FIRST_detectorTower_PARAM + 1)
|
(&LAST_detectorTower_PARAM - &FIRST_detectorTower_PARAM + 1)
|
||||||
|
@ -30,21 +30,22 @@ static void epicsInithookFunction(initHookState iState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
detectorTowerLiftAxis::detectorTowerLiftAxis(detectorTowerController *pC,
|
detectorTowerLiftAxis::detectorTowerLiftAxis(detectorTowerController *pC,
|
||||||
int axisNo)
|
int axisNo,
|
||||||
|
detectorTowerAngleAxis *angleAxis)
|
||||||
: turboPmacAxis(pC, axisNo, false), pC_(pC) {
|
: turboPmacAxis(pC, axisNo, false), pC_(pC) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The superclass constructor sinqAxis calls in turn its superclass constructor
|
The superclass constructor sinqAxis calls in turn its superclass
|
||||||
asynMotorAxis. In the latter, a pointer to the constructed object this is
|
constructor asynMotorAxis. In the latter, a pointer to the constructed
|
||||||
stored inside the array pAxes_:
|
object this is stored inside the array pAxes_:
|
||||||
|
|
||||||
pC->pAxes_[axisNo] = this;
|
pC->pAxes_[axisNo] = this;
|
||||||
|
|
||||||
Therefore, the axes are managed by the controller pC. If axisNo is out of
|
Therefore, the axes are managed by the controller pC. If axisNo is out
|
||||||
bounds, asynMotorAxis prints an error (see
|
of bounds, asynMotorAxis prints an error (see
|
||||||
https://github.com/epics-modules/motor/blob/master/motorApp/MotorSrc/asynMotorAxis.cpp,
|
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
|
line 40). However, we want the IOC creation to stop completely, since
|
||||||
is a configuration error.
|
this is a configuration error.
|
||||||
*/
|
*/
|
||||||
if (axisNo >= pC->numAxes()) {
|
if (axisNo >= pC->numAxes()) {
|
||||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
@ -56,7 +57,8 @@ detectorTowerLiftAxis::detectorTowerLiftAxis(detectorTowerController *pC,
|
|||||||
exit(-1);
|
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()) {
|
if (axes.empty()) {
|
||||||
initHookRegister(&epicsInithookFunction);
|
initHookRegister(&epicsInithookFunction);
|
||||||
}
|
}
|
||||||
@ -64,11 +66,14 @@ detectorTowerLiftAxis::detectorTowerLiftAxis(detectorTowerController *pC,
|
|||||||
// Collect all axes into this list which will be used in the hook
|
// Collect all axes into this list which will be used in the hook
|
||||||
// function
|
// function
|
||||||
axes.push_back(this);
|
axes.push_back(this);
|
||||||
|
|
||||||
|
angleAxis_ = angleAxis;
|
||||||
|
angleAxis->liftAxis_ = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
detectorTowerLiftAxis::~detectorTowerLiftAxis(void) {
|
detectorTowerLiftAxis::~detectorTowerLiftAxis(void) {
|
||||||
// Since the controller memory is managed somewhere else, we don't need to
|
// Since the controller memory is managed somewhere else, we don't need
|
||||||
// clean up the pointer pC here.
|
// to clean up the pointer pC here.
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus detectorTowerLiftAxis::init() {
|
asynStatus detectorTowerLiftAxis::init() {
|
||||||
@ -76,6 +81,9 @@ asynStatus detectorTowerLiftAxis::init() {
|
|||||||
// Local variable declaration
|
// Local variable declaration
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
double motorRecResolution = 0.0;
|
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
|
// The parameter library takes some time to be initialized. Therefore we
|
||||||
// wait until the status is not asynParamUndefined anymore.
|
// wait until the status is not asynParamUndefined anymore.
|
||||||
@ -109,7 +117,22 @@ asynStatus detectorTowerLiftAxis::init() {
|
|||||||
__PRETTY_FUNCTION__, __LINE__);
|
__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
|
// Perform the actual poll
|
||||||
@ -118,8 +141,10 @@ asynStatus detectorTowerLiftAxis::poll(bool *moving) {
|
|||||||
|
|
||||||
// Is this axis the one with the smallest index?
|
// Is this axis the one with the smallest index?
|
||||||
// If not, just read out the movement status and update *moving
|
// If not, just read out the movement status and update *moving
|
||||||
if (axisNo() < angleAxis_->axisNo()) {
|
if (axisNo() < angleAxis()->axisNo() &&
|
||||||
status = pC_->pollDetectorAxes(moving, angleAxis_, this);
|
axisNo() < angleAxis()->supportAxis()->axisNo()) {
|
||||||
|
status = pC_->pollDetectorAxes(moving, angleAxis(), this,
|
||||||
|
angleAxis()->supportAxis());
|
||||||
} else {
|
} else {
|
||||||
status = pC_->getIntegerParam(axisNo(), pC_->motorStatusMoving(),
|
status = pC_->getIntegerParam(axisNo(), pC_->motorStatusMoving(),
|
||||||
(int *)moving);
|
(int *)moving);
|
||||||
@ -156,14 +181,16 @@ asynStatus detectorTowerLiftAxis::doMove(double position, int relative,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Signal to the deferredMovementCollectorLoop (of the
|
// Signal to the deferredMovementCollectorLoop (of the
|
||||||
// detectorTowerAngleAxis) that a movement should be started to the defined
|
// detectorTowerAngleAxis) that a movement should be started to the
|
||||||
// target position.
|
// defined target position.
|
||||||
targetPosition_ = position * motorRecResolution;
|
targetPosition_ = position * motorRecResolution;
|
||||||
angleAxis_->receivedTarget_ = true;
|
angleAxis_->receivedTarget_ = true;
|
||||||
|
|
||||||
return asynSuccess;
|
return asynSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asynStatus detectorTowerLiftAxis::reset() { return angleAxis()->reset(); };
|
||||||
|
|
||||||
asynStatus detectorTowerLiftAxis::stop(double acceleration) {
|
asynStatus detectorTowerLiftAxis::stop(double acceleration) {
|
||||||
|
|
||||||
// Status of read-write-operations of ASCII commands to the controller
|
// Status of read-write-operations of ASCII commands to the controller
|
||||||
@ -179,9 +206,9 @@ asynStatus detectorTowerLiftAxis::stop(double acceleration) {
|
|||||||
rwStatus = pC_->writeRead(axisNo_, "P350=8", response, 0);
|
rwStatus = pC_->writeRead(axisNo_, "P350=8", response, 0);
|
||||||
|
|
||||||
if (rwStatus != asynSuccess) {
|
if (rwStatus != asynSuccess) {
|
||||||
asynPrint(
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
"Controller \"%s\", axis %d => %s, line %d\nStopping "
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nStopping the movement "
|
"the movement "
|
||||||
"failed.\n",
|
"failed.\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||||
|
|
||||||
@ -197,7 +224,9 @@ asynStatus detectorTowerLiftAxis::stop(double acceleration) {
|
|||||||
return rwStatus;
|
return rwStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus detectorTowerLiftAxis::reset() { return angleAxis_->reset(); };
|
asynStatus detectorTowerLiftAxis::readEncoderType() {
|
||||||
|
return angleAxis()->readEncoderType();
|
||||||
|
}
|
||||||
|
|
||||||
asynStatus detectorTowerLiftAxis::adjustOrigin(double newOrigin) {
|
asynStatus detectorTowerLiftAxis::adjustOrigin(double newOrigin) {
|
||||||
|
|
||||||
@ -252,57 +281,3 @@ asynStatus detectorTowerLiftAxis::adjustOrigin(double newOrigin) {
|
|||||||
|
|
||||||
return status;
|
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 pController Pointer to the associated controller
|
||||||
* @param axisNo Index of the axis
|
* @param axisNo Index of the axis
|
||||||
*/
|
*/
|
||||||
detectorTowerLiftAxis(detectorTowerController *pController, int axisNo);
|
detectorTowerLiftAxis(detectorTowerController *pController, int axisNo,
|
||||||
|
detectorTowerAngleAxis *angleAxis);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Destroy the turboPmacAxis
|
* @brief Destroy the turboPmacAxis
|
||||||
@ -69,9 +70,9 @@ class detectorTowerLiftAxis : public turboPmacAxis {
|
|||||||
double max_velocity, double acceleration);
|
double max_velocity, double acceleration);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Call the reset function of the associated
|
* @brief Calls the `reset` function of the associated lift axis.
|
||||||
* `detectorTowerAngleAxis`.
|
|
||||||
*
|
*
|
||||||
|
* @param on
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus reset();
|
asynStatus reset();
|
||||||
@ -106,6 +107,13 @@ class detectorTowerLiftAxis : public turboPmacAxis {
|
|||||||
*/
|
*/
|
||||||
detectorTowerAngleAxis *angleAxis() { return angleAxis_; }
|
detectorTowerAngleAxis *angleAxis() { return angleAxis_; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This axis type has an absolute encoder by default
|
||||||
|
*
|
||||||
|
* @return asynStatus
|
||||||
|
*/
|
||||||
|
asynStatus readEncoderType();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
detectorTowerController *pC_;
|
detectorTowerController *pC_;
|
||||||
detectorTowerAngleAxis *angleAxis_;
|
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