3 Commits
1.0.0 ... main

9 changed files with 155 additions and 337 deletions

View File

@ -19,8 +19,13 @@ seleneAngleAxis::seleneAngleAxis(seleneGuideController *pController, int axisNo,
// Selene guide motors cannot be disabled
status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 0);
if (status != asynSuccess) {
pC_->paramLibAccessFailed(status, "motorCanDisable", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR "
"(setting a parameter value failed "
"with %s)\n. Terminating IOC",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
pC_->stringifyAsynStatus(status));
exit(-1);
}
// Even though this happens already in sinqAxis, a default value for
@ -49,13 +54,7 @@ asynStatus seleneAngleAxis::doMove(double position, int relative,
double acceleration) {
double motorRecResolution = 0.0;
asynStatus pl_status = pC_->getDoubleParam(
axisNo_, pC_->motorRecResolution(), &motorRecResolution);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorRecResolution_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
getAxisParamChecked(this, motorRecResolution, &motorRecResolution);
setTargetPosition(position * motorRecResolution);
targetSet_ = true;
return liftAxis_->startCombinedMoveFromVirtualAxis();
@ -75,25 +74,17 @@ double seleneAngleAxis::targetPosition() {
asynStatus seleneAngleAxis::doPoll(bool *moving) {
char errorMessage[pC_->MAXBUF_] = {0};
asynStatus status = asynSuccess;
// In the doPoll method of `seleneLiftAxis`, the parameters
// `motorStatusMoving` and `motorStatusDone` of this axis have already been
// set accordingly.
int isMoving = 0;
asynStatus pl_status =
pC_->getIntegerParam(axisNo(), pC_->motorStatusMoving(), &isMoving);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorStatusMoving",
axisNo(), __PRETTY_FUNCTION__,
__LINE__);
}
*moving = (isMoving != 0);
getAxisParamChecked(this, motorStatusMoving, moving);
double motPos = 0.0;
pl_status = motorPosition(&motPos);
if (pl_status != asynSuccess) {
return pl_status;
status = motorPosition(&motPos);
if (status != asynSuccess) {
return status;
}
/*
@ -126,9 +117,9 @@ asynStatus seleneAngleAxis::doPoll(bool *moving) {
double smallestHighLimit = std::numeric_limits<double>::infinity();
double smallestLowLimit = std::numeric_limits<double>::infinity();
double liftPosition = 0.0;
pl_status = liftAxis_->motorPosition(&liftPosition);
if (pl_status != asynSuccess) {
return pl_status;
status = liftAxis_->motorPosition(&liftPosition);
if (status != asynSuccess) {
return status;
}
for (int i = 0; i < liftAxis_->numAxes_; i++) {
@ -137,9 +128,9 @@ asynStatus seleneAngleAxis::doPoll(bool *moving) {
double leverArm = oAxis->xOffset() - liftAxis_->xPos();
double motPos = 0.0;
pl_status = oAxis->motorPosition(&motPos);
if (pl_status != asynSuccess) {
return pl_status;
status = oAxis->motorPosition(&motPos);
if (status != asynSuccess) {
return status;
}
/*
@ -176,52 +167,23 @@ asynStatus seleneAngleAxis::doPoll(bool *moving) {
}
}
pl_status = pC_->setDoubleParam(axisNo_, pC_->motorHighLimitFromDriver(),
smallestHighLimit);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorHighLimitFromDriver",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
pl_status = pC_->setDoubleParam(axisNo_, pC_->motorLowLimitFromDriver(),
smallestLowLimit);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorLowLimitFromDriver",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
setAxisParamChecked(this, motorHighLimitFromDriver, smallestHighLimit);
setAxisParamChecked(this, motorLowLimitFromDriver, smallestLowLimit);
// This axis should always be seen as enabled, since it is automatically
// enabled before each movement and disabled afterwards
pl_status = setIntegerParam(pC_->motorEnableRBV(), 1);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorEnableRBV_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, motorEnableRBV, true);
// If an error message is set in the liftAxis_, copy this message into this
// axis.
pl_status =
pC_->getStringParam(liftAxis_->axisNo(), pC_->motorMessageText(),
sizeof(errorMessage), errorMessage);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorMessageText",
liftAxis_->axisNo(),
__PRETTY_FUNCTION__, __LINE__);
}
getAxisParamChecked(liftAxis_, motorMessageText, &errorMessage);
if (strlen(errorMessage) != 0) {
pl_status = setStringParam(pC_->motorMessageText(), errorMessage);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
setAxisParamChecked(this, motorMessageText, errorMessage);
return asynError;
}
return pl_status;
return status;
}
asynStatus seleneAngleAxis::doReset() { return liftAxis_->reset(); }
@ -229,13 +191,7 @@ asynStatus seleneAngleAxis::doReset() { return liftAxis_->reset(); }
asynStatus seleneAngleAxis::enable(bool on) { return liftAxis_->enable(on); }
asynStatus seleneAngleAxis::readEncoderType() {
asynStatus pl_status =
setStringParam(pC_->encoderType(), IncrementalEncoder);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "encoderType_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, encoderType, IncrementalEncoder);
return asynSuccess;
}

View File

@ -1,5 +1,6 @@
#ifndef seleneAngleAxis_H
#define seleneAngleAxis_H
#include "seleneGuideController.h"
#include "turboPmacAxis.h"
// Forward declaration of the seleneLiftAxis class to resolve the cyclic
@ -7,10 +8,6 @@
// See https://en.cppreference.com/w/cpp/language/class.
class seleneLiftAxis;
// Forward declaration of the seleneGuideController class to resolve the cyclic
// dependency. See https://en.cppreference.com/w/cpp/language/class.
class seleneGuideController;
/**
* @brief Virtual axis for setting the angle of the Selene guide
*
@ -140,6 +137,11 @@ class seleneAngleAxis : public turboPmacAxis {
*/
asynStatus rereadEncoder() { return asynSuccess; }
/**
* @brief Return a pointer to the axis controller
*/
virtual seleneGuideController *pController() override { return pC_; };
protected:
seleneGuideController *pC_;
seleneLiftAxis *liftAxis_;

View File

@ -1,4 +1,7 @@
#include "seleneGuideController.h"
#include "seleneAngleAxis.h"
#include "seleneLiftAxis.h"
#include "seleneOffsetAxis.h"
#include "turboPmacController.h"
#include <epicsExport.h>
#include <errlog.h>

View File

@ -8,11 +8,15 @@
#ifndef seleneGuideController_H
#define seleneGuideController_H
#include "seleneAngleAxis.h"
#include "seleneLiftAxis.h"
#include "seleneOffsetAxis.h"
#include "turboPmacController.h"
// Forward declaration of the axis classes to resolve the cyclic
// dependency between the seleneLiftAxis and the seleneAngleAxis .h-file.
// See https://en.cppreference.com/w/cpp/language/class.
class seleneAngleAxis;
class seleneLiftAxis;
class seleneOffsetAxis;
class seleneGuideController : public turboPmacController {
public:

View File

@ -96,8 +96,13 @@ seleneLiftAxis::seleneLiftAxis(seleneGuideController *pC, int axis1No,
// Selene guide motors cannot be disabled
status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 0);
if (status != asynSuccess) {
pC_->paramLibAccessFailed(status, "motorCanDisable", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR "
"(setting a parameter value failed "
"with %s)\n. Terminating IOC",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
pC_->stringifyAsynStatus(status));
exit(-1);
}
// Even though this happens already in sinqAxis, a default value for
@ -151,44 +156,17 @@ asynStatus seleneLiftAxis::init() {
}
// Assume the virtual axes are not moving at the start
status = setIntegerParam(pC_->motorStatusMoving(), 0);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorStatusMoving", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
status = setIntegerParam(pC_->motorStatusDone(), 1);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorStatusDone", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, motorStatusMoving, false);
setAxisParamChecked(this, motorStatusDone, true);
status = angleAxis_->setIntegerParam(pC_->motorStatusMoving(), 0);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorStatusMoving",
angleAxis_->axisNo(),
__PRETTY_FUNCTION__, __LINE__);
}
status = angleAxis_->setIntegerParam(pC_->motorStatusDone(), 1);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorStatusDone",
angleAxis_->axisNo(),
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(angleAxis_, motorStatusMoving, false);
setAxisParamChecked(angleAxis_, motorStatusDone, true);
// The virtual axes should always be seen as enabled, since the underlying
// hardware is automatically enabled after sending a start command to the
// controller and automatically disabled after the movement finished.
status = setIntegerParam(pC_->motorEnableRBV(), 1);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorEnableRBV_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
status = angleAxis_->setIntegerParam(pC_->motorEnableRBV(), 1);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorEnableRBV_",
angleAxis_->axisNo(),
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, motorEnableRBV, true);
setAxisParamChecked(angleAxis_, motorEnableRBV, true);
status = normalizePositions();
if (status != asynSuccess) {
@ -277,12 +255,7 @@ asynStatus seleneLiftAxis::normalizePositions() {
}
asynStatus seleneLiftAxis::doPoll(bool *moving) {
// Status of read-write-operations of ASCII commands to the controller
asynStatus rw_status = asynSuccess;
// Status of parameter library operations
asynStatus pl_status = asynSuccess;
asynStatus status = asynSuccess;
char response[pC_->MAXBUF_] = {0};
char userMessage[pC_->MAXBUF_] = {0};
@ -293,18 +266,12 @@ asynStatus seleneLiftAxis::doPoll(bool *moving) {
// =========================================================================
pl_status =
pC_->getIntegerParam(axisNo(), pC_->motorStatusDone(), &wasDone);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorStatusMoving",
axisNo(), __PRETTY_FUNCTION__,
__LINE__);
}
getAxisParamChecked(this, motorStatusDone, &wasDone);
const char *command = "P158";
rw_status = pC_->writeRead(axisNo_, command, response, 1);
if (rw_status != asynSuccess) {
return rw_status;
status = pC_->writeRead(axisNo_, command, response, 1);
if (status != asynSuccess) {
return status;
}
nvals = sscanf(response, "%d", &axStatus);
@ -315,31 +282,12 @@ asynStatus seleneLiftAxis::doPoll(bool *moving) {
*moving = (axStatus != 0);
// Set the moving status of seleneLiftAxis
pl_status = setIntegerParam(pC_->motorStatusMoving(), *moving);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorStatusMoving",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
pl_status = setIntegerParam(pC_->motorStatusDone(), !(*moving));
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorStatusDone", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, motorStatusMoving, *moving);
setAxisParamChecked(this, motorStatusDone, !(*moving));
// Set the moving status of seleneAngleAxis
pl_status = angleAxis_->setIntegerParam(pC_->motorStatusMoving(), *moving);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorStatusMoving",
angleAxis_->axisNo(),
__PRETTY_FUNCTION__, __LINE__);
}
pl_status = angleAxis_->setIntegerParam(pC_->motorStatusDone(), !(*moving));
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorStatusDone",
angleAxis_->axisNo(),
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(angleAxis_, motorStatusMoving, *moving);
setAxisParamChecked(angleAxis_, motorStatusDone, !(*moving));
/*
If an seleneOffsetAxis is moving, the positions of the virtual axes
@ -358,22 +306,17 @@ asynStatus seleneLiftAxis::doPoll(bool *moving) {
double motorRecResolution = 0.0;
asynStatus pl_status = pC_->getDoubleParam(
axisNo_, pC_->motorRecResolution(), &motorRecResolution);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorRecResolution_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
getAxisParamChecked(angleAxis_, motorRecResolution,
&motorRecResolution);
status = offsetAxes_[2]->motorPosition(&offsetAx2Pos);
if (status != asynSuccess) {
return status;
}
pl_status = offsetAxes_[2]->motorPosition(&offsetAx2Pos);
if (pl_status != asynSuccess) {
return pl_status;
}
pl_status = offsetAxes_[3]->motorPosition(&offsetAx3Pos);
if (pl_status != asynSuccess) {
return pl_status;
status = offsetAxes_[3]->motorPosition(&offsetAx3Pos);
if (status != asynSuccess) {
return status;
}
deriveLiftAndAngle(
@ -382,14 +325,14 @@ asynStatus seleneLiftAxis::doPoll(bool *moving) {
&angle);
// Set the position values in the parameter library
pl_status = setMotorPosition(lift);
if (pl_status != asynSuccess) {
return pl_status;
status = setMotorPosition(lift);
if (status != asynSuccess) {
return status;
}
pl_status = angleAxis_->setMotorPosition(angle);
if (pl_status != asynSuccess) {
return pl_status;
status = angleAxis_->setMotorPosition(angle);
if (status != asynSuccess) {
return status;
}
// Calculate the new liftPosition_ of all seleneOffsetAxis
@ -414,45 +357,22 @@ asynStatus seleneLiftAxis::doPoll(bool *moving) {
// Set the limits for the lift axis
double motPos = 0.0;
pl_status = motorPosition(&motPos);
if (pl_status != asynSuccess) {
return pl_status;
status = motorPosition(&motPos);
if (status != asynSuccess) {
return status;
}
pl_status = pC_->setDoubleParam(axisNo_, pC_->motorHighLimitFromDriver(),
motPos + smallestDistHighLimit);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorHighLimitFromDriver_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
pl_status = pC_->setDoubleParam(axisNo_, pC_->motorLowLimitFromDriver(),
motPos - smallestDistLowLimit);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorLowLimit_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, motorHighLimitFromDriver,
motPos + smallestDistHighLimit);
setAxisParamChecked(this, motorLowLimitFromDriver,
motPos - smallestDistLowLimit);
// The virtual axes are in an error state, if at least one of the underlying
// real axes is in an error state.
for (int i = 0; i < numAxes_; i++) {
pl_status = pC_->getStringParam(offsetAxes_[i]->axisNo(),
pC_->motorMessageText(),
sizeof(userMessage), userMessage);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorMessageText",
offsetAxes_[i]->axisNo(),
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(offsetAxes_[i], motorMessageText, userMessage);
if (strlen(userMessage) != 0) {
pl_status = setStringParam(pC_->motorMessageText(), userMessage);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
setAxisParamChecked(this, motorMessageText, userMessage);
return asynError;
}
}
@ -464,17 +384,10 @@ asynStatus seleneLiftAxis::doMove(double position, int relative,
double min_velocity, double max_velocity,
double acceleration) {
double motorRecResolution = 0.0;
asynStatus status = asynSuccess;
status = pC_->getDoubleParam(axisNo_, pC_->motorRecResolution(),
&motorRecResolution);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorRecResolution_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
getAxisParamChecked(this, motorRecResolution, &motorRecResolution);
setTargetPosition(position * motorRecResolution);
targetSet_ = true;
status = startCombinedMoveFromVirtualAxis();
asynStatus status = startCombinedMoveFromVirtualAxis();
targetSet_ = false;
return status;
}
@ -521,34 +434,26 @@ asynStatus seleneLiftAxis::startCombinedMove() {
asynStatus seleneLiftAxis::stop(double acceleration) {
// Status of read-write-operations of ASCII commands to the controller
asynStatus rw_status = asynSuccess;
// Status of parameter library operations
asynStatus pl_status = asynSuccess;
asynStatus status = asynSuccess;
char response[pC_->MAXBUF_] = {0};
// =========================================================================
// Stop all axes
rw_status = pC_->writeRead(axisNo_, "P150=8", response, 0);
status = pC_->writeRead(axisNo_, "P150=8", response, 0);
if (rw_status != asynSuccess) {
if (status != 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__);
pl_status = setIntegerParam(pC_->motorStatusProblem(), true);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorStatusProblem_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
setAxisParamChecked(this, motorStatusProblem, true);
}
return rw_status;
return status;
}
asynStatus seleneLiftAxis::doReset() {
@ -561,24 +466,13 @@ asynStatus seleneLiftAxis::doReset() {
}
asynStatus seleneLiftAxis::enable(bool on) {
asynStatus pl_status = setStringParam(pC_->motorMessageText(),
"Axis cannot be enabled / disabled");
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
return pl_status;
setAxisParamChecked(this, motorMessageText,
"Axis cannot be enabled / disabled");
return asynSuccess;
}
asynStatus seleneLiftAxis::readEncoderType() {
asynStatus pl_status =
setStringParam(pC_->encoderType(), IncrementalEncoder);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "encoderType_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, encoderType, IncrementalEncoder);
return asynSuccess;
}

View File

@ -1,14 +1,11 @@
#ifndef seleneLiftAxis_H
#define seleneLiftAxis_H
#include "seleneAngleAxis.h"
#include "seleneGuideController.h"
#include "seleneOffsetAxis.h"
#include "turboPmacAxis.h"
#include <array>
// Forward declaration of the seleneGuideController class to resolve the cyclic
// dependency. See https://en.cppreference.com/w/cpp/language/class.
class seleneGuideController;
/**
* @brief Virtual axis for setting the height of the center of a Selene guide
*
@ -278,6 +275,11 @@ class seleneLiftAxis : public turboPmacAxis {
*/
seleneOffsetAxis *offsetAxis(int idx);
/**
* @brief Return a pointer to the axis controller
*/
virtual seleneGuideController *pController() override { return pC_; };
protected:
std::array<seleneOffsetAxis *, numAxes_> offsetAxes_;

View File

@ -50,18 +50,33 @@ seleneOffsetAxis::seleneOffsetAxis(seleneGuideController *pController,
status = pC_->setIntegerParam(axisNo_, pC_->motorStatusDone(), 1);
if (status != asynSuccess) {
pC_->paramLibAccessFailed(status, "motorStatusDone", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR "
"(setting a parameter value failed "
"with %s)\n. Terminating IOC",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
pC_->stringifyAsynStatus(status));
exit(-1);
}
status = pC_->setIntegerParam(axisNo_, pC_->motorStatusMoving(), 0);
if (status != asynSuccess) {
pC_->paramLibAccessFailed(status, "motorStatusMoving", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR "
"(setting a parameter value failed "
"with %s)\n. Terminating IOC",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
pC_->stringifyAsynStatus(status));
exit(-1);
}
status = pC_->setDoubleParam(axisNo_, pC_->motorEncoderPosition(), 0.0);
if (status != asynSuccess) {
pC_->paramLibAccessFailed(status, "motorEncoderPosition", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR "
"(setting a parameter value failed "
"with %s)\n. Terminating IOC",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
pC_->stringifyAsynStatus(status));
exit(-1);
}
// Register the hook function during construction of the first axis
@ -77,8 +92,13 @@ seleneOffsetAxis::seleneOffsetAxis(seleneGuideController *pController,
// Selene guide motors cannot be disabled
status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 0);
if (status != asynSuccess) {
pC_->paramLibAccessFailed(status, "motorCanDisable", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR "
"(setting a parameter value failed "
"with %s)\n. Terminating IOC",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
pC_->stringifyAsynStatus(status));
exit(-1);
}
// Even though this happens already in sinqAxis, a default value for
@ -132,16 +152,8 @@ asynStatus seleneOffsetAxis::init() {
}
// Read the initial limits from the paramlib
status = pC_->getDoubleParam(axisNo_, pC_->motorHighLimit(), &highLimit_);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorHighLimit", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
status = pC_->getDoubleParam(axisNo_, pC_->motorLowLimit(), &lowLimit_);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorLowLimit", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
getAxisParamChecked(this, motorHighLimit, &highLimit_);
getAxisParamChecked(this, motorLowLimit, &lowLimit_);
// The high limits read from the paramLib are divided by motorRecResolution,
// hence we need to multiply them to undo this change.
@ -214,24 +226,10 @@ asynStatus seleneOffsetAxis::doPoll(bool *moving) {
// Update the parameter library
if (error != 0) {
status = setStringParam(pC_->motorMessageText(), userMessage);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorMessageText",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
status = setIntegerParam(pC_->motorStatusProblem(), true);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorStatusProblem_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
setAxisParamChecked(this, motorMessageText, userMessage);
setAxisParamChecked(this, motorStatusProblem, true);
}
// TODO: To be removed, once the real limits are derived
// highLimit = 10.0;
// lowLimit = -10.0;
// Convert into lift coordinate system
absoluteHighLimitLiftCS_ = highLimit - zOffset_;
absoluteLowLimitLiftCS_ = lowLimit - zOffset_;
@ -251,20 +249,8 @@ asynStatus seleneOffsetAxis::doPoll(bool *moving) {
relLowLimit = lowLimit - encoderPosition;
}
status = pC_->setDoubleParam(axisNo_, pC_->motorHighLimitFromDriver(),
relHighLimit);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorHighLimitFromDriver_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
status = pC_->setDoubleParam(axisNo_, pC_->motorLowLimitFromDriver(),
relLowLimit);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorLowLimit_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, motorHighLimitFromDriver, relHighLimit);
setAxisParamChecked(this, motorLowLimitFromDriver, relLowLimit);
/*
If this axis is moving as a result of an individual move command to the axis
@ -278,41 +264,22 @@ asynStatus seleneOffsetAxis::doPoll(bool *moving) {
}
}
status = setIntegerParam(pC_->motorStatusMoving(), *moving);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorStatusMoving_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
status = setIntegerParam(pC_->motorStatusDone(), !(*moving));
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorStatusDone_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, motorStatusMoving, *moving);
setAxisParamChecked(this, motorStatusDone, !(*moving));
// Axis is always shown as enabled, since it is enabled automatically by the
// controller when a move command P150=1 is sent and disabled once the
// movement is completed.
status = setIntegerParam(pC_->motorEnableRBV(), 1);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorEnableRBV_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, motorEnableRBV, true);
return errorStatus;
}
asynStatus
seleneOffsetAxis::setPositionsFromEncoderPosition(double encoderPosition) {
asynStatus status = pC_->setDoubleParam(
axisNo_, pC_->motorAbsolutePositionRBV(), encoderPosition);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorEncoderPosition",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
setAxisParamChecked(this, motorAbsolutePositionRBV, encoderPosition);
absolutePositionLiftCS_ = encoderPosition - zOffset_;
return status;
return asynSuccess;
}
asynStatus seleneOffsetAxis::doMove(double position, int relative,
@ -321,14 +288,7 @@ asynStatus seleneOffsetAxis::doMove(double position, int relative,
double acceleration) {
double motorRecResolution = 0.0;
asynStatus pl_status = pC_->getDoubleParam(
axisNo_, pC_->motorRecResolution(), &motorRecResolution);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorRecResolution_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
getAxisParamChecked(this, motorRecResolution, &motorRecResolution);
// Set the target position
setTargetPosition(position * motorRecResolution);
@ -339,14 +299,9 @@ asynStatus seleneOffsetAxis::doMove(double position, int relative,
}
asynStatus seleneOffsetAxis::enable(bool on) {
asynStatus pl_status = setStringParam(pC_->motorMessageText(),
"Axis cannot be enabled / disabled");
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
return pl_status;
setAxisParamChecked(this, motorMessageText,
"Axis cannot be enabled / disabled");
return asynSuccess;
}
asynStatus seleneOffsetAxis::normalizePositions() {

View File

@ -1,6 +1,7 @@
#ifndef seleneOffsetAxis_H
#define seleneOffsetAxis_H
#include "seleneGuideController.h"
#include "turboPmacAxis.h"
// Forward declaration of the seleneLiftAxis class to resolve the cyclic
@ -8,10 +9,6 @@
// See https://en.cppreference.com/w/cpp/language/class.
class seleneLiftAxis;
// Forward declaration of the seleneGuideController class to resolve the cyclic
// dependency. See https://en.cppreference.com/w/cpp/language/class.
class seleneGuideController;
/**
* @brief Virtual axis for setting the offset of a motor of the Selene guide
*
@ -126,6 +123,11 @@ class seleneOffsetAxis : public turboPmacAxis {
*/
double absoluteLowLimitLiftCS() { return absoluteLowLimitLiftCS_; }
/**
* @brief Return a pointer to the axis controller
*/
virtual seleneGuideController *pController() override { return pC_; };
protected:
// True, if the target has been set from this axis
bool targetSet_;