11 Commits
1.0.0 ... main

Author SHA1 Message Date
2c9de618ec Made code compile with compiler flags
Some checks failed
Test And Build / Lint (push) Successful in 4s
Test And Build / Build (push) Failing after 7s
2025-12-23 14:00:08 +01:00
b834dc3f8d Updated turboPmac version 2025-12-23 13:51:18 +01:00
ee6235e74a Removed C++ only flag from USR_CFLAGS and updated turboPmac version
Some checks failed
Test And Build / Lint (push) Successful in 3s
Test And Build / Build (push) Failing after 9s
2025-08-22 15:30:33 +02:00
48c068826c Updated sinqMotor to fix bug in forcedPoll regarding watchdog
Some checks failed
Test And Build / Lint (push) Successful in 4s
Test And Build / Build (push) Failing after 10s
2025-08-14 17:25:35 +02:00
c494fc88a5 Updated to turboPmac 1.4 and hid symbols
Some checks failed
Test And Build / Lint (push) Successful in 3s
Test And Build / Build (push) Failing after 9s
2025-08-12 09:28:06 +02:00
e0fa9ef3a9 also check header files
Some checks failed
Test And Build / Lint (push) Successful in 3s
Test And Build / Build (push) Failing after 10s
2025-07-04 14:37:43 +02:00
dc6d5c40b3 need to build sinqmotor first
Some checks failed
Test And Build / Lint (push) Successful in 4s
Test And Build / Build (push) Failing after 10s
2025-07-04 14:23:21 +02:00
56288b1db8 adds gitea action
Some checks failed
Test And Build / Lint (push) Successful in 3s
Test And Build / Build (push) Failing after 3s
2025-07-04 14:21:39 +02:00
dde15eb30d Updated param lib accessors to use macro to reduce boilerplate 2025-06-18 10:22:49 +02:00
efccb26302 Updated param lib accessors to use macro to reduce boilerplate 2025-06-18 10:19:43 +02:00
85d443a92b Updated turboPmac version 2025-06-18 08:56:32 +02:00
12 changed files with 248 additions and 418 deletions

View File

@@ -0,0 +1,30 @@
name: Test And Build
on: [push]
jobs:
Lint:
runs-on: linepics
steps:
- name: checkout repo
uses: actions/checkout@v4
- name: cppcheck
run: cppcheck --std=c++17 --addon=cert --addon=misc --error-exitcode=1 src/*.cpp
- name: formatting
run: clang-format --style=file --Werror --dry-run src/*.cpp src/*.h
Build:
runs-on: linepics
steps:
- name: checkout repo
uses: actions/checkout@v4
with:
submodules: 'true'
- run: |
pushd turboPmac
sed -i 's/ARCH_FILTER=.*/ARCH_FILTER=linux%/' Makefile
echo -e "\nIGNORE_SUBMODULES += sinqmotor" >> Makefile
make install
popd
- run: |
sed -i 's/ARCH_FILTER=.*/ARCH_FILTER=linux%/' Makefile
echo -e "\nIGNORE_SUBMODULES += turboPmac" >> Makefile
make install

View File

@@ -1,58 +0,0 @@
default:
image: docker.psi.ch:5000/sinqdev/sinqepics:latest
stages:
- lint
- build
- test
cppcheck:
stage: lint
script:
- cppcheck --std=c++17 --addon=cert --addon=misc --error-exitcode=1 src/*.cpp
artifacts:
expire_in: 1 week
tags:
- sinq
formatting:
stage: lint
script:
- clang-format --style=file --Werror --dry-run src/*.cpp
artifacts:
expire_in: 1 week
tags:
- sinq
# clangtidy:
# stage: lint
# script:
# - curl https://docker.psi.ch:5000/v2/_catalog
# # - dnf update -y
# # - dnf install -y clang-tools-extra
# # - clang-tidy sinqEPICSApp/src/*.cpp sinqEPICSApp/src/*.c sinqEPICSApp/src/*.h -checks=cppcoreguidelines-*,cert-*
# # tags:
# # - sinq
build_module:
stage: build
script:
- export SINQMOTOR_VERSION="$(grep 'sinqMotor_VERSION=' Makefile | cut -d= -f2)"
- git clone --depth 1 --branch "${SINQMOTOR_VERSION}" https://gitlab-ci-token:${CI_JOB_TOKEN}@git.psi.ch/sinq-epics-modules/sinqmotor.git
- pushd sinqmotor
- sed -i 's/ARCH_FILTER=.*/ARCH_FILTER=linux%/' Makefile
- echo "LIBVERSION=${SINQMOTOR_VERSION}" >> Makefile
- make install
- popd
- sed -i 's/ARCH_FILTER=.*/ARCH_FILTER=linux%/' Makefile
- echo "LIBVERSION=${CI_COMMIT_TAG:-0.0.1}" >> Makefile
- make install
- cp -rT "/ioc/modules/seleneLift/$(ls -U /ioc/modules/seleneLift/ | head -1)" "./seleneLift-${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}"
artifacts:
name: "seleneLift-${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}"
paths:
- "seleneLift-${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}/*"
expire_in: 1 week
when: always
tags:
- sinq

View File

@@ -42,4 +42,5 @@ DBDS += turboPmac/sinqMotor/src/sinqMotor.dbd
DBDS += turboPmac/src/turboPmac.dbd DBDS += turboPmac/src/turboPmac.dbd
DBDS += src/seleneGuide.dbd DBDS += src/seleneGuide.dbd
USR_CFLAGS += -Wall -Wextra -Weffc++ -Wunused-result -Wextra -Werror # -Wpedantic // Does not work because EPICS macros trigger warnings USR_CFLAGS += -Wall -Wextra -Wunused-result -Wextra -Werror # -Wpedantic // Does not work because EPICS macros trigger warnings
USR_CXXFLAGS += -Wall -Wextra -Wunused-result -Wextra -Werror

View File

@@ -19,8 +19,13 @@ seleneAngleAxis::seleneAngleAxis(seleneGuideController *pController, int axisNo,
// Selene guide motors cannot be disabled // Selene guide motors cannot be disabled
status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 0); status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 0);
if (status != asynSuccess) { if (status != asynSuccess) {
pC_->paramLibAccessFailed(status, "motorCanDisable", axisNo_, asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
__PRETTY_FUNCTION__, __LINE__); "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 // Even though this happens already in sinqAxis, a default value for
@@ -45,17 +50,18 @@ asynStatus seleneAngleAxis::stop(double acceleration) {
} }
asynStatus seleneAngleAxis::doMove(double position, int relative, asynStatus seleneAngleAxis::doMove(double position, int relative,
double min_velocity, double max_velocity, double minVelocity, double maxVelocity,
double acceleration) { double acceleration) {
// Suppress unused variable warnings
(void)relative;
(void)minVelocity;
(void)maxVelocity;
(void)acceleration;
double motorRecResolution = 0.0; double motorRecResolution = 0.0;
asynStatus pl_status = pC_->getDoubleParam( getAxisParamChecked(this, motorRecResolution, &motorRecResolution);
axisNo_, pC_->motorRecResolution(), &motorRecResolution);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorRecResolution_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
setTargetPosition(position * motorRecResolution); setTargetPosition(position * motorRecResolution);
targetSet_ = true; targetSet_ = true;
return liftAxis_->startCombinedMoveFromVirtualAxis(); return liftAxis_->startCombinedMoveFromVirtualAxis();
@@ -75,25 +81,17 @@ double seleneAngleAxis::targetPosition() {
asynStatus seleneAngleAxis::doPoll(bool *moving) { asynStatus seleneAngleAxis::doPoll(bool *moving) {
char errorMessage[pC_->MAXBUF_] = {0}; char errorMessage[pC_->MAXBUF_] = {0};
asynStatus status = asynSuccess;
// In the doPoll method of `seleneLiftAxis`, the parameters // In the doPoll method of `seleneLiftAxis`, the parameters
// `motorStatusMoving` and `motorStatusDone` of this axis have already been // `motorStatusMoving` and `motorStatusDone` of this axis have already been
// set accordingly. // set accordingly.
int isMoving = 0; getAxisParamChecked(this, motorStatusMoving, moving);
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);
double motPos = 0.0; double motPos = 0.0;
pl_status = motorPosition(&motPos); status = motorPosition(&motPos);
if (pl_status != asynSuccess) { if (status != asynSuccess) {
return pl_status; return status;
} }
/* /*
@@ -126,9 +124,9 @@ asynStatus seleneAngleAxis::doPoll(bool *moving) {
double smallestHighLimit = std::numeric_limits<double>::infinity(); double smallestHighLimit = std::numeric_limits<double>::infinity();
double smallestLowLimit = std::numeric_limits<double>::infinity(); double smallestLowLimit = std::numeric_limits<double>::infinity();
double liftPosition = 0.0; double liftPosition = 0.0;
pl_status = liftAxis_->motorPosition(&liftPosition); status = liftAxis_->motorPosition(&liftPosition);
if (pl_status != asynSuccess) { if (status != asynSuccess) {
return pl_status; return status;
} }
for (int i = 0; i < liftAxis_->numAxes_; i++) { for (int i = 0; i < liftAxis_->numAxes_; i++) {
@@ -137,9 +135,9 @@ asynStatus seleneAngleAxis::doPoll(bool *moving) {
double leverArm = oAxis->xOffset() - liftAxis_->xPos(); double leverArm = oAxis->xOffset() - liftAxis_->xPos();
double motPos = 0.0; double motPos = 0.0;
pl_status = oAxis->motorPosition(&motPos); status = oAxis->motorPosition(&motPos);
if (pl_status != asynSuccess) { if (status != asynSuccess) {
return pl_status; return status;
} }
/* /*
@@ -176,52 +174,23 @@ asynStatus seleneAngleAxis::doPoll(bool *moving) {
} }
} }
pl_status = pC_->setDoubleParam(axisNo_, pC_->motorHighLimitFromDriver(), setAxisParamChecked(this, motorHighLimitFromDriver, smallestHighLimit);
smallestHighLimit); setAxisParamChecked(this, motorLowLimitFromDriver, smallestLowLimit);
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__);
}
// This axis should always be seen as enabled, since it is automatically // This axis should always be seen as enabled, since it is automatically
// enabled before each movement and disabled afterwards // enabled before each movement and disabled afterwards
pl_status = setIntegerParam(pC_->motorEnableRBV(), 1); setAxisParamChecked(this, motorEnableRBV, true);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorEnableRBV_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
// If an error message is set in the liftAxis_, copy this message into this // If an error message is set in the liftAxis_, copy this message into this
// axis. // axis.
pl_status = getAxisParamChecked(liftAxis_, motorMessageText, &errorMessage);
pC_->getStringParam(liftAxis_->axisNo(), pC_->motorMessageText(),
sizeof(errorMessage), errorMessage);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorMessageText",
liftAxis_->axisNo(),
__PRETTY_FUNCTION__, __LINE__);
}
if (strlen(errorMessage) != 0) { if (strlen(errorMessage) != 0) {
pl_status = setStringParam(pC_->motorMessageText(), errorMessage); setAxisParamChecked(this, motorMessageText, errorMessage);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
return asynError; return asynError;
} }
return pl_status; return status;
} }
asynStatus seleneAngleAxis::doReset() { return liftAxis_->reset(); } asynStatus seleneAngleAxis::doReset() { return liftAxis_->reset(); }
@@ -229,13 +198,7 @@ asynStatus seleneAngleAxis::doReset() { return liftAxis_->reset(); }
asynStatus seleneAngleAxis::enable(bool on) { return liftAxis_->enable(on); } asynStatus seleneAngleAxis::enable(bool on) { return liftAxis_->enable(on); }
asynStatus seleneAngleAxis::readEncoderType() { asynStatus seleneAngleAxis::readEncoderType() {
asynStatus pl_status = setAxisParamChecked(this, encoderType, IncrementalEncoder);
setStringParam(pC_->encoderType(), IncrementalEncoder);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "encoderType_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
return asynSuccess; return asynSuccess;
} }

View File

@@ -1,22 +1,19 @@
#ifndef seleneAngleAxis_H #ifndef seleneAngleAxis_H
#define seleneAngleAxis_H #define seleneAngleAxis_H
#include "seleneGuideController.h"
#include "turboPmacAxis.h" #include "turboPmacAxis.h"
// Forward declaration of the seleneLiftAxis class to resolve the cyclic // Forward declaration of the seleneLiftAxis class to resolve the cyclic
// dependency between the seleneLiftAxis and the seleneAngleAxis .h-file. // dependency between the seleneLiftAxis and the seleneAngleAxis .h-file.
// See https://en.cppreference.com/w/cpp/language/class. // See https://en.cppreference.com/w/cpp/language/class.
class seleneLiftAxis; class HIDDEN 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 * @brief Virtual axis for setting the angle of the Selene guide
* *
* Please see README.md for a detailed explanation. * Please see README.md for a detailed explanation.
*/ */
class seleneAngleAxis : public turboPmacAxis { class HIDDEN seleneAngleAxis : public turboPmacAxis {
public: public:
/** /**
* @brief Construct a new seleneAngleAxis. * @brief Construct a new seleneAngleAxis.
@@ -51,12 +48,12 @@ class seleneAngleAxis : public turboPmacAxis {
* *
* @param position * @param position
* @param relative * @param relative
* @param min_velocity * @param minVelocity
* @param maxOffset_velocity * @param maxOffset_velocity
* @param acceleration * @param acceleration
* @return asynStatus * @return asynStatus
*/ */
asynStatus doMove(double position, int relative, double min_velocity, asynStatus doMove(double position, int relative, double minVelocity,
double maxOffset_velocity, double acceleration); double maxOffset_velocity, double acceleration);
/** /**
@@ -140,6 +137,11 @@ class seleneAngleAxis : public turboPmacAxis {
*/ */
asynStatus rereadEncoder() { return asynSuccess; } asynStatus rereadEncoder() { return asynSuccess; }
/**
* @brief Return a pointer to the axis controller
*/
virtual seleneGuideController *pController() override { return pC_; };
protected: protected:
seleneGuideController *pC_; seleneGuideController *pC_;
seleneLiftAxis *liftAxis_; seleneLiftAxis *liftAxis_;

View File

@@ -1,4 +1,7 @@
#include "seleneGuideController.h" #include "seleneGuideController.h"
#include "seleneAngleAxis.h"
#include "seleneLiftAxis.h"
#include "seleneOffsetAxis.h"
#include "turboPmacController.h" #include "turboPmacController.h"
#include <epicsExport.h> #include <epicsExport.h>
#include <errlog.h> #include <errlog.h>
@@ -20,7 +23,8 @@ seleneGuideController::seleneGuideController(
const char *portName, const char *ipPortConfigName, int numAxes, const char *portName, const char *ipPortConfigName, int numAxes,
double movingPollPeriod, double idlePollPeriod, double comTimeout) double movingPollPeriod, double idlePollPeriod, double comTimeout)
: turboPmacController(portName, ipPortConfigName, numAxes, movingPollPeriod, : turboPmacController(portName, ipPortConfigName, numAxes, movingPollPeriod,
idlePollPeriod, NUM_seleneGuide_DRIVER_PARAMS) idlePollPeriod, comTimeout,
NUM_seleneGuide_DRIVER_PARAMS)
{ {
@@ -142,7 +146,8 @@ static const iocshArg *const CreateControllerArgs[] = {
&CreateControllerArg0, &CreateControllerArg1, &CreateControllerArg2, &CreateControllerArg0, &CreateControllerArg1, &CreateControllerArg2,
&CreateControllerArg3, &CreateControllerArg4, &CreateControllerArg5}; &CreateControllerArg3, &CreateControllerArg4, &CreateControllerArg5};
static const iocshFuncDef configSeleneGuideCreateController = { static const iocshFuncDef configSeleneGuideCreateController = {
"seleneGuideController", 6, CreateControllerArgs}; "seleneGuideController", 6, CreateControllerArgs,
"Create a new instance of a Selene controller."};
static void configSeleneGuideCreateControllerCallFunc(const iocshArgBuf *args) { static void configSeleneGuideCreateControllerCallFunc(const iocshArgBuf *args) {
seleneGuideCreateController(args[0].sval, args[1].sval, args[2].ival, seleneGuideCreateController(args[0].sval, args[1].sval, args[2].ival,
args[3].dval, args[4].dval, args[5].dval); args[3].dval, args[4].dval, args[5].dval);

View File

@@ -8,12 +8,16 @@
#ifndef seleneGuideController_H #ifndef seleneGuideController_H
#define seleneGuideController_H #define seleneGuideController_H
#include "seleneAngleAxis.h"
#include "seleneLiftAxis.h"
#include "seleneOffsetAxis.h"
#include "turboPmacController.h" #include "turboPmacController.h"
class seleneGuideController : public turboPmacController { // 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 HIDDEN seleneAngleAxis;
class HIDDEN seleneLiftAxis;
class HIDDEN seleneOffsetAxis;
class HIDDEN seleneGuideController : public turboPmacController {
public: public:
/** /**

View File

@@ -96,8 +96,13 @@ seleneLiftAxis::seleneLiftAxis(seleneGuideController *pC, int axis1No,
// Selene guide motors cannot be disabled // Selene guide motors cannot be disabled
status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 0); status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 0);
if (status != asynSuccess) { if (status != asynSuccess) {
pC_->paramLibAccessFailed(status, "motorCanDisable", axisNo_, asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
__PRETTY_FUNCTION__, __LINE__); "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 // 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 // Assume the virtual axes are not moving at the start
status = setIntegerParam(pC_->motorStatusMoving(), 0); setAxisParamChecked(this, motorStatusMoving, false);
if (status != asynSuccess) { setAxisParamChecked(this, motorStatusDone, true);
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__);
}
status = angleAxis_->setIntegerParam(pC_->motorStatusMoving(), 0); setAxisParamChecked(angleAxis_, motorStatusMoving, false);
if (status != asynSuccess) { setAxisParamChecked(angleAxis_, motorStatusDone, true);
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__);
}
// The virtual axes should always be seen as enabled, since the underlying // The virtual axes should always be seen as enabled, since the underlying
// hardware is automatically enabled after sending a start command to the // hardware is automatically enabled after sending a start command to the
// controller and automatically disabled after the movement finished. // controller and automatically disabled after the movement finished.
status = setIntegerParam(pC_->motorEnableRBV(), 1); setAxisParamChecked(this, motorEnableRBV, true);
if (status != asynSuccess) { setAxisParamChecked(angleAxis_, motorEnableRBV, true);
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__);
}
status = normalizePositions(); status = normalizePositions();
if (status != asynSuccess) { if (status != asynSuccess) {
@@ -277,12 +255,7 @@ asynStatus seleneLiftAxis::normalizePositions() {
} }
asynStatus seleneLiftAxis::doPoll(bool *moving) { asynStatus seleneLiftAxis::doPoll(bool *moving) {
asynStatus status = asynSuccess;
// Status of read-write-operations of ASCII commands to the controller
asynStatus rw_status = asynSuccess;
// Status of parameter library operations
asynStatus pl_status = asynSuccess;
char response[pC_->MAXBUF_] = {0}; char response[pC_->MAXBUF_] = {0};
char userMessage[pC_->MAXBUF_] = {0}; char userMessage[pC_->MAXBUF_] = {0};
@@ -293,18 +266,12 @@ asynStatus seleneLiftAxis::doPoll(bool *moving) {
// ========================================================================= // =========================================================================
pl_status = getAxisParamChecked(this, motorStatusDone, &wasDone);
pC_->getIntegerParam(axisNo(), pC_->motorStatusDone(), &wasDone);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorStatusMoving",
axisNo(), __PRETTY_FUNCTION__,
__LINE__);
}
const char *command = "P158"; const char *command = "P158";
rw_status = pC_->writeRead(axisNo_, command, response, 1); status = pC_->writeRead(axisNo_, command, response, 1);
if (rw_status != asynSuccess) { if (status != asynSuccess) {
return rw_status; return status;
} }
nvals = sscanf(response, "%d", &axStatus); nvals = sscanf(response, "%d", &axStatus);
@@ -315,31 +282,12 @@ asynStatus seleneLiftAxis::doPoll(bool *moving) {
*moving = (axStatus != 0); *moving = (axStatus != 0);
// Set the moving status of seleneLiftAxis // Set the moving status of seleneLiftAxis
pl_status = setIntegerParam(pC_->motorStatusMoving(), *moving); setAxisParamChecked(this, motorStatusMoving, *moving);
if (pl_status != asynSuccess) { setAxisParamChecked(this, motorStatusDone, !(*moving));
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__);
}
// Set the moving status of seleneAngleAxis // Set the moving status of seleneAngleAxis
pl_status = angleAxis_->setIntegerParam(pC_->motorStatusMoving(), *moving); setAxisParamChecked(angleAxis_, motorStatusMoving, *moving);
if (pl_status != asynSuccess) { setAxisParamChecked(angleAxis_, motorStatusDone, !(*moving));
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__);
}
/* /*
If an seleneOffsetAxis is moving, the positions of the virtual axes If an seleneOffsetAxis is moving, the positions of the virtual axes
@@ -358,22 +306,17 @@ asynStatus seleneLiftAxis::doPoll(bool *moving) {
double motorRecResolution = 0.0; double motorRecResolution = 0.0;
asynStatus pl_status = pC_->getDoubleParam( getAxisParamChecked(angleAxis_, motorRecResolution,
axisNo_, pC_->motorRecResolution(), &motorRecResolution); &motorRecResolution);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorRecResolution_", status = offsetAxes_[2]->motorPosition(&offsetAx2Pos);
axisNo_, __PRETTY_FUNCTION__, if (status != asynSuccess) {
__LINE__); return status;
} }
pl_status = offsetAxes_[2]->motorPosition(&offsetAx2Pos); status = offsetAxes_[3]->motorPosition(&offsetAx3Pos);
if (pl_status != asynSuccess) { if (status != asynSuccess) {
return pl_status; return status;
}
pl_status = offsetAxes_[3]->motorPosition(&offsetAx3Pos);
if (pl_status != asynSuccess) {
return pl_status;
} }
deriveLiftAndAngle( deriveLiftAndAngle(
@@ -382,14 +325,14 @@ asynStatus seleneLiftAxis::doPoll(bool *moving) {
&angle); &angle);
// Set the position values in the parameter library // Set the position values in the parameter library
pl_status = setMotorPosition(lift); status = setMotorPosition(lift);
if (pl_status != asynSuccess) { if (status != asynSuccess) {
return pl_status; return status;
} }
pl_status = angleAxis_->setMotorPosition(angle); status = angleAxis_->setMotorPosition(angle);
if (pl_status != asynSuccess) { if (status != asynSuccess) {
return pl_status; return status;
} }
// Calculate the new liftPosition_ of all seleneOffsetAxis // Calculate the new liftPosition_ of all seleneOffsetAxis
@@ -414,45 +357,22 @@ asynStatus seleneLiftAxis::doPoll(bool *moving) {
// Set the limits for the lift axis // Set the limits for the lift axis
double motPos = 0.0; double motPos = 0.0;
pl_status = motorPosition(&motPos); status = motorPosition(&motPos);
if (pl_status != asynSuccess) { if (status != asynSuccess) {
return pl_status; return status;
} }
pl_status = pC_->setDoubleParam(axisNo_, pC_->motorHighLimitFromDriver(), setAxisParamChecked(this, motorHighLimitFromDriver,
motPos + smallestDistHighLimit); motPos + smallestDistHighLimit);
if (pl_status != asynSuccess) { setAxisParamChecked(this, motorLowLimitFromDriver,
return pC_->paramLibAccessFailed(pl_status, "motorHighLimitFromDriver_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
pl_status = pC_->setDoubleParam(axisNo_, pC_->motorLowLimitFromDriver(),
motPos - smallestDistLowLimit); motPos - smallestDistLowLimit);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorLowLimit_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
// The virtual axes are in an error state, if at least one of the underlying // The virtual axes are in an error state, if at least one of the underlying
// real axes is in an error state. // real axes is in an error state.
for (int i = 0; i < numAxes_; i++) { for (int i = 0; i < numAxes_; i++) {
pl_status = pC_->getStringParam(offsetAxes_[i]->axisNo(), setAxisParamChecked(offsetAxes_[i], motorMessageText, userMessage);
pC_->motorMessageText(),
sizeof(userMessage), userMessage);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorMessageText",
offsetAxes_[i]->axisNo(),
__PRETTY_FUNCTION__, __LINE__);
}
if (strlen(userMessage) != 0) { if (strlen(userMessage) != 0) {
pl_status = setStringParam(pC_->motorMessageText(), userMessage); setAxisParamChecked(this, motorMessageText, userMessage);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
return asynError; return asynError;
} }
} }
@@ -461,20 +381,20 @@ asynStatus seleneLiftAxis::doPoll(bool *moving) {
} }
asynStatus seleneLiftAxis::doMove(double position, int relative, asynStatus seleneLiftAxis::doMove(double position, int relative,
double min_velocity, double max_velocity, double minVelocity, double maxVelocity,
double acceleration) { double acceleration) {
double motorRecResolution = 0.0;
asynStatus status = asynSuccess;
status = pC_->getDoubleParam(axisNo_, pC_->motorRecResolution(), // Suppress unused variable warnings
&motorRecResolution); (void)relative;
if (status != asynSuccess) { (void)minVelocity;
return pC_->paramLibAccessFailed(status, "motorRecResolution_", axisNo_, (void)maxVelocity;
__PRETTY_FUNCTION__, __LINE__); (void)acceleration;
}
double motorRecResolution = 0.0;
getAxisParamChecked(this, motorRecResolution, &motorRecResolution);
setTargetPosition(position * motorRecResolution); setTargetPosition(position * motorRecResolution);
targetSet_ = true; targetSet_ = true;
status = startCombinedMoveFromVirtualAxis(); asynStatus status = startCombinedMoveFromVirtualAxis();
targetSet_ = false; targetSet_ = false;
return status; return status;
} }
@@ -521,34 +441,29 @@ asynStatus seleneLiftAxis::startCombinedMove() {
asynStatus seleneLiftAxis::stop(double acceleration) { asynStatus seleneLiftAxis::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
asynStatus rw_status = asynSuccess; asynStatus status = asynSuccess;
// Status of parameter library operations
asynStatus pl_status = asynSuccess;
char response[pC_->MAXBUF_] = {0}; char response[pC_->MAXBUF_] = {0};
// ========================================================================= // =========================================================================
// Stop all axes // Suppress unused variable warnings
rw_status = pC_->writeRead(axisNo_, "P150=8", response, 0); (void)acceleration;
if (rw_status != asynSuccess) { // Stop all axes
status = pC_->writeRead(axisNo_, "P150=8", response, 0);
if (status != asynSuccess) {
asynPrint( asynPrint(
pC_->pasynUser(), ASYN_TRACE_ERROR, pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d\nStopping the movement " "Controller \"%s\", axis %d => %s, line %d\nStopping the movement "
"failed.\n", "failed.\n",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__); pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
pl_status = setIntegerParam(pC_->motorStatusProblem(), true); setAxisParamChecked(this, motorStatusProblem, true);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorStatusProblem_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
} }
return rw_status; return status;
} }
asynStatus seleneLiftAxis::doReset() { asynStatus seleneLiftAxis::doReset() {
@@ -561,30 +476,29 @@ asynStatus seleneLiftAxis::doReset() {
} }
asynStatus seleneLiftAxis::enable(bool on) { asynStatus seleneLiftAxis::enable(bool on) {
asynStatus pl_status = setStringParam(pC_->motorMessageText(),
// Suppress unused variable warnings
(void)on;
setAxisParamChecked(this, motorMessageText,
"Axis cannot be enabled / disabled"); "Axis cannot be enabled / disabled");
if (pl_status != asynSuccess) { return asynSuccess;
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
return pl_status;
} }
asynStatus seleneLiftAxis::readEncoderType() { asynStatus seleneLiftAxis::readEncoderType() {
asynStatus pl_status = setAxisParamChecked(this, encoderType, IncrementalEncoder);
setStringParam(pC_->encoderType(), IncrementalEncoder);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "encoderType_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
return asynSuccess; return asynSuccess;
} }
asynStatus seleneLiftAxis::doHome(double minVelocity, double maxVelocity, asynStatus seleneLiftAxis::doHome(double minVelocity, double maxVelocity,
double acceleration, int forwards) { double acceleration, int forwards) {
// Suppress unused variable warnings
(void)minVelocity;
(void)maxVelocity;
(void)acceleration;
(void)forwards;
char response[pC_->MAXBUF_] = {0}; char response[pC_->MAXBUF_] = {0};
// No answer expected // No answer expected
@@ -742,8 +656,9 @@ static const iocshArg *const CreateAxisArgs[] = {
&CreateAxisArg3, &CreateAxisArg4, &CreateAxisArg5, &CreateAxisArg3, &CreateAxisArg4, &CreateAxisArg5,
&CreateAxisArg6, &CreateAxisArg7, &CreateAxisArg8, &CreateAxisArg6, &CreateAxisArg7, &CreateAxisArg8,
}; };
static const iocshFuncDef configSeleneVirtualCreateAxes = {"seleneVirtualAxes", static const iocshFuncDef configSeleneVirtualCreateAxes = {
9, CreateAxisArgs}; "seleneVirtualAxes", 9, CreateAxisArgs,
"Creates instances of Selene axes."};
static void configSeleneVirtualCreateAxesCallFunc(const iocshArgBuf *args) { static void configSeleneVirtualCreateAxesCallFunc(const iocshArgBuf *args) {
seleneVirtualCreateAxes(args[0].sval, args[1].ival, args[2].ival, seleneVirtualCreateAxes(args[0].sval, args[1].ival, args[2].ival,
args[3].ival, args[4].ival, args[5].ival, args[3].ival, args[4].ival, args[5].ival,

View File

@@ -1,20 +1,17 @@
#ifndef seleneLiftAxis_H #ifndef seleneLiftAxis_H
#define seleneLiftAxis_H #define seleneLiftAxis_H
#include "seleneAngleAxis.h" #include "seleneAngleAxis.h"
#include "seleneGuideController.h"
#include "seleneOffsetAxis.h" #include "seleneOffsetAxis.h"
#include "turboPmacAxis.h" #include "turboPmacAxis.h"
#include <array> #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 * @brief Virtual axis for setting the height of the center of a Selene guide
* *
* Please see README.md for a detailed explanation. * Please see README.md for a detailed explanation.
*/ */
class seleneLiftAxis : public turboPmacAxis { class HIDDEN seleneLiftAxis : public turboPmacAxis {
public: public:
static const int numAxes_ = 6; static const int numAxes_ = 6;
@@ -68,12 +65,12 @@ class seleneLiftAxis : public turboPmacAxis {
* *
* @param position * @param position
* @param relative * @param relative
* @param min_velocity * @param minVelocity
* @param maxOffset_velocity * @param maxOffset_velocity
* @param acceleration * @param acceleration
* @return asynStatus * @return asynStatus
*/ */
asynStatus doMove(double position, int relative, double min_velocity, asynStatus doMove(double position, int relative, double minVelocity,
double maxOffset_velocity, double acceleration); double maxOffset_velocity, double acceleration);
/** /**
@@ -278,6 +275,11 @@ class seleneLiftAxis : public turboPmacAxis {
*/ */
seleneOffsetAxis *offsetAxis(int idx); seleneOffsetAxis *offsetAxis(int idx);
/**
* @brief Return a pointer to the axis controller
*/
virtual seleneGuideController *pController() override { return pC_; };
protected: protected:
std::array<seleneOffsetAxis *, numAxes_> offsetAxes_; std::array<seleneOffsetAxis *, numAxes_> offsetAxes_;

View File

@@ -50,18 +50,33 @@ seleneOffsetAxis::seleneOffsetAxis(seleneGuideController *pController,
status = pC_->setIntegerParam(axisNo_, pC_->motorStatusDone(), 1); status = pC_->setIntegerParam(axisNo_, pC_->motorStatusDone(), 1);
if (status != asynSuccess) { if (status != asynSuccess) {
pC_->paramLibAccessFailed(status, "motorStatusDone", axisNo_, asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
__PRETTY_FUNCTION__, __LINE__); "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); status = pC_->setIntegerParam(axisNo_, pC_->motorStatusMoving(), 0);
if (status != asynSuccess) { if (status != asynSuccess) {
pC_->paramLibAccessFailed(status, "motorStatusMoving", axisNo_, asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
__PRETTY_FUNCTION__, __LINE__); "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); status = pC_->setDoubleParam(axisNo_, pC_->motorEncoderPosition(), 0.0);
if (status != asynSuccess) { if (status != asynSuccess) {
pC_->paramLibAccessFailed(status, "motorEncoderPosition", axisNo_, asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
__PRETTY_FUNCTION__, __LINE__); "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 // Register the hook function during construction of the first axis
@@ -77,8 +92,13 @@ seleneOffsetAxis::seleneOffsetAxis(seleneGuideController *pController,
// Selene guide motors cannot be disabled // Selene guide motors cannot be disabled
status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 0); status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 0);
if (status != asynSuccess) { if (status != asynSuccess) {
pC_->paramLibAccessFailed(status, "motorCanDisable", axisNo_, asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
__PRETTY_FUNCTION__, __LINE__); "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 // 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 // Read the initial limits from the paramlib
status = pC_->getDoubleParam(axisNo_, pC_->motorHighLimit(), &highLimit_); getAxisParamChecked(this, motorHighLimit, &highLimit_);
if (status != asynSuccess) { getAxisParamChecked(this, motorLowLimit, &lowLimit_);
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__);
}
// The high limits read from the paramLib are divided by motorRecResolution, // The high limits read from the paramLib are divided by motorRecResolution,
// hence we need to multiply them to undo this change. // hence we need to multiply them to undo this change.
@@ -214,23 +226,9 @@ asynStatus seleneOffsetAxis::doPoll(bool *moving) {
// Update the parameter library // Update the parameter library
if (error != 0) { if (error != 0) {
status = setStringParam(pC_->motorMessageText(), userMessage); setAxisParamChecked(this, motorMessageText, userMessage);
if (status != asynSuccess) { setAxisParamChecked(this, motorStatusProblem, true);
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__);
}
}
// TODO: To be removed, once the real limits are derived
// highLimit = 10.0;
// lowLimit = -10.0;
// Convert into lift coordinate system // Convert into lift coordinate system
absoluteHighLimitLiftCS_ = highLimit - zOffset_; absoluteHighLimitLiftCS_ = highLimit - zOffset_;
@@ -251,20 +249,8 @@ asynStatus seleneOffsetAxis::doPoll(bool *moving) {
relLowLimit = lowLimit - encoderPosition; relLowLimit = lowLimit - encoderPosition;
} }
status = pC_->setDoubleParam(axisNo_, pC_->motorHighLimitFromDriver(), setAxisParamChecked(this, motorHighLimitFromDriver, relHighLimit);
relHighLimit); setAxisParamChecked(this, motorLowLimitFromDriver, relLowLimit);
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__);
}
/* /*
If this axis is moving as a result of an individual move command to the axis If this axis is moving as a result of an individual move command to the axis
@@ -278,57 +264,36 @@ asynStatus seleneOffsetAxis::doPoll(bool *moving) {
} }
} }
status = setIntegerParam(pC_->motorStatusMoving(), *moving); setAxisParamChecked(this, motorStatusMoving, *moving);
if (status != asynSuccess) { setAxisParamChecked(this, motorStatusDone, !(*moving));
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__);
}
// Axis is always shown as enabled, since it is enabled automatically by the // 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 // controller when a move command P150=1 is sent and disabled once the
// movement is completed. // movement is completed.
status = setIntegerParam(pC_->motorEnableRBV(), 1); setAxisParamChecked(this, motorEnableRBV, true);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorEnableRBV_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
return errorStatus; return errorStatus;
} }
asynStatus asynStatus
seleneOffsetAxis::setPositionsFromEncoderPosition(double encoderPosition) { seleneOffsetAxis::setPositionsFromEncoderPosition(double encoderPosition) {
asynStatus status = pC_->setDoubleParam( setAxisParamChecked(this, motorAbsolutePositionRBV, encoderPosition);
axisNo_, pC_->motorAbsolutePositionRBV(), encoderPosition);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorEncoderPosition",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
absolutePositionLiftCS_ = encoderPosition - zOffset_; absolutePositionLiftCS_ = encoderPosition - zOffset_;
return status; return asynSuccess;
} }
asynStatus seleneOffsetAxis::doMove(double position, int relative, asynStatus seleneOffsetAxis::doMove(double position, int relative,
double min_velocity, double minVelocity, double maxVelocity,
double maxOffset_velocity,
double acceleration) { double acceleration) {
double motorRecResolution = 0.0; // Suppress unused variable warnings
(void)relative;
(void)minVelocity;
(void)maxVelocity;
(void)acceleration;
asynStatus pl_status = pC_->getDoubleParam( double motorRecResolution = 0.0;
axisNo_, pC_->motorRecResolution(), &motorRecResolution); getAxisParamChecked(this, motorRecResolution, &motorRecResolution);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorRecResolution_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
// Set the target position // Set the target position
setTargetPosition(position * motorRecResolution); setTargetPosition(position * motorRecResolution);
@@ -339,14 +304,12 @@ asynStatus seleneOffsetAxis::doMove(double position, int relative,
} }
asynStatus seleneOffsetAxis::enable(bool on) { asynStatus seleneOffsetAxis::enable(bool on) {
asynStatus pl_status = setStringParam(pC_->motorMessageText(), // Suppress unused variable warnings
(void)on;
setAxisParamChecked(this, motorMessageText,
"Axis cannot be enabled / disabled"); "Axis cannot be enabled / disabled");
if (pl_status != asynSuccess) { return asynSuccess;
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
return pl_status;
} }
asynStatus seleneOffsetAxis::normalizePositions() { asynStatus seleneOffsetAxis::normalizePositions() {
@@ -429,7 +392,8 @@ static const iocshArg *const CreateAxisArgs[] = {
&CreateAxisArg3, &CreateAxisArg3,
}; };
static const iocshFuncDef configSeleneOffsetAxisCreateAxis = { static const iocshFuncDef configSeleneOffsetAxisCreateAxis = {
"seleneOffsetAxis", 4, CreateAxisArgs}; "seleneOffsetAxis", 4, CreateAxisArgs,
"Creates a new instance of a Selene offset axis."};
static void configSeleneOffsetAxisCreateAxisCallFunc(const iocshArgBuf *args) { static void configSeleneOffsetAxisCreateAxisCallFunc(const iocshArgBuf *args) {
seleneOffsetAxisCreateAxis(args[0].sval, args[1].ival, args[2].dval, seleneOffsetAxisCreateAxis(args[0].sval, args[1].ival, args[2].dval,
args[3].dval); args[3].dval);

View File

@@ -1,23 +1,20 @@
#ifndef seleneOffsetAxis_H #ifndef seleneOffsetAxis_H
#define seleneOffsetAxis_H #define seleneOffsetAxis_H
#include "seleneGuideController.h"
#include "turboPmacAxis.h" #include "turboPmacAxis.h"
// Forward declaration of the seleneLiftAxis class to resolve the cyclic // Forward declaration of the seleneLiftAxis class to resolve the cyclic
// dependency between the seleneLiftAxis and the seleneAngleAxis .h-file. // dependency between the seleneLiftAxis and the seleneAngleAxis .h-file.
// See https://en.cppreference.com/w/cpp/language/class. // See https://en.cppreference.com/w/cpp/language/class.
class seleneLiftAxis; class HIDDEN 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 * @brief Virtual axis for setting the offset of a motor of the Selene guide
* *
* Please see README.md for a detailed explanation. * Please see README.md for a detailed explanation.
*/ */
class seleneOffsetAxis : public turboPmacAxis { class HIDDEN seleneOffsetAxis : public turboPmacAxis {
public: public:
/** /**
* @brief Construct a new selene Offset Axis object * @brief Construct a new selene Offset Axis object
@@ -54,12 +51,12 @@ class seleneOffsetAxis : public turboPmacAxis {
* *
* @param position * @param position
* @param relative * @param relative
* @param min_velocity * @param minVelocity
* @param maxOffset_velocity * @param maxOffset_velocity
* @param acceleration * @param acceleration
* @return asynStatus * @return asynStatus
*/ */
asynStatus doMove(double position, int relative, double min_velocity, asynStatus doMove(double position, int relative, double minVelocity,
double maxOffset_velocity, double acceleration); double maxOffset_velocity, double acceleration);
/** /**
@@ -126,6 +123,11 @@ class seleneOffsetAxis : public turboPmacAxis {
*/ */
double absoluteLowLimitLiftCS() { return absoluteLowLimitLiftCS_; } double absoluteLowLimitLiftCS() { return absoluteLowLimitLiftCS_; }
/**
* @brief Return a pointer to the axis controller
*/
virtual seleneGuideController *pController() override { return pC_; };
protected: protected:
// True, if the target has been set from this axis // True, if the target has been set from this axis
bool targetSet_; bool targetSet_;