11 Commits
1.0.0 ... 1.2.1

Author SHA1 Message Date
ab596ded48 Lift and angle axis now move simultaneously
Some checks failed
Test And Build / Lint (push) Failing after 3s
Test And Build / Build (push) Successful in 15s
Fixed a bug which caused the axes not to move in parallel, but after
each other.
2025-08-14 08:05:35 +02:00
bfd565aabd Hide visibility of classes
All checks were successful
Test And Build / Lint (push) Successful in 3s
Test And Build / Build (push) Successful in 15s
2025-08-12 09:20:25 +02:00
0005775c9d Updated turboPmac to 1.4.0 2025-08-12 09:18:37 +02:00
e5f9e33c66 Test to hide visibility 2025-08-12 08:09:36 +02:00
46b839cc66 Removed symbol visibility for turboPmac 2025-08-11 16:48:18 +02:00
38b4ba9843 Fixed record setup in detectorTower.db
All checks were successful
Test And Build / Lint (push) Successful in 4s
Test And Build / Build (push) Successful in 16s
2025-07-21 17:04:09 +02:00
8eba612524 UDF state is not shown during initialization anymore
All checks were successful
Test And Build / Lint (push) Successful in 4s
Test And Build / Build (push) Successful in 15s
These changes process the AdjustOrigin record during initialization to
make sure its .STAT field does not show "UDF" anymore before the first
processing. The gate record makes sure that no command is send to the
underlying hardware during initial processing.
2025-07-09 11:43:31 +02:00
9565198424 adds gitea action
All checks were successful
Test And Build / Lint (push) Successful in 3s
Test And Build / Build (push) Successful in 14s
2025-07-04 14:40:11 +02:00
bc8561c299 Updated turboPmac version 2025-06-18 08:33:04 +02:00
cf6f836416 Updated turboPmac version 2025-06-17 16:51:08 +02:00
6e99b37ed2 Updated turboPmac version 2025-06-17 13:26:13 +02:00
13 changed files with 232 additions and 611 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 TURBOPMAC_VERSION="$(grep 'turboPmac_VERSION=' Makefile | cut -d= -f2)"
- git clone --depth 1 --branch "${TURBOPMAC_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=${TURBOPMAC_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/detectorTower/$(ls -U /ioc/modules/detectorTower/ | head -1)" "./detectorTower-${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}"
artifacts:
name: "detectorTower-${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}"
paths:
- "detectorTower-${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}/*"
expire_in: 1 week
when: always
tags:
- sinq

View File

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

View File

@@ -58,7 +58,6 @@ record(ai, "$(INSTR)$(M):Origin") {
field(INP, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_ORIGIN")
field(SCAN, "I/O Intr")
field(PINI, "NO")
field(VAL, "0")
}
# Shift the origin of the corresponding axis by the given value. The axis will move to this
@@ -69,16 +68,28 @@ record(ao, "$(INSTR)$(M):AdjustOrigin") {
field(PINI, "NO")
field(FLNK, "$(INSTR)$(M):ResetAO")
field(VAL, "0")
field(UDF, "0")
field(SCAN, "Passive")
}
# Only forward nonzero inputs for the origin adjustment
record(calcout, "$(INSTR)$(M):GateOrigin") {
field(CALC, "A!=0?A:0")
field(INPA, "$(INSTR)$(M):AdjustOrigin")
field(OUT, "$(INSTR)$(M):WriteAO.VAL PP") # Forward the value to the driver
field(PINI, "NO")
field(SCAN, "Passive")
}
# 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):ResetAO") {
field(DESC, "Write value to hardware then reset to 0")
field(DOL1, "$(INSTR)$(M):AdjustOrigin")
field(LNK1, "$(INSTR)$(M):WriteAO.VAL PP") # Perform write to hardware
field(DOL1, "1") # Dummy value which is only here to trigger processing of LNK1
field(LNK1, "$(INSTR)$(M):GateOrigin.PROC PP")
field(DOL2, "0.0")
field(LNK2, "$(INSTR)$(M):AdjustOrigin.VAL PP") # Reset to zero
field(UDF, "0")
}
# This record forwards the adjustment of the origin to the asyn driver.

View File

@@ -1,5 +1,7 @@
#include "detectorTowerAngleAxis.h"
#include "detectorTowerController.h"
#include "detectorTowerLiftAxis.h"
#include "detectorTowerSupportAxis.h"
#include "turboPmacController.h"
#include <epicsExport.h>
#include <errlog.h>
@@ -32,17 +34,16 @@ static void deferredMovementCollectorLoop(void *drvPvt) {
detectorTowerAngleAxis *axis = (detectorTowerAngleAxis *)drvPvt;
while (1) {
if (axis->receivedTarget_) {
// Wait for 100 ms and then start the movement with the information
// available
axis->startingDeferredMovement_ = true;
// Wait for the time span defined in deferredMovementWait_ and then
// start the movement with the information available
epicsThreadSleep(axis->deferredMovementWait_);
axis->startCombinedMove();
// After the movement command has been send, reset the flag
axis->receivedTarget_ = false;
}
// Limit this loop to an idle frequency of 1 kHz
epicsThreadSleep(0.001);
// Limit this loop to an idle frequency of 10 kHz
epicsThreadSleep(0.01);
}
}
@@ -74,11 +75,10 @@ detectorTowerAngleAxis::detectorTowerAngleAxis(detectorTowerController *pC,
}
// Initialize all member variables
// Assumed to be not ready by default, this is overwritten in the next poll
error_ = 0;
waitingForStart_ = false;
receivedTarget_ = false;
startingDeferredMovement_ = false;
deferredMovementWait_ = 0.1; // seconds
deferredMovementWait_ = 0.5; // seconds
// Will be populated in the init() method
beamRadius_ = 0.0;
@@ -157,17 +157,8 @@ asynStatus detectorTowerAngleAxis::init() {
}
// Initialize the motorStatusMoving flag
status = setIntegerParam(pC_->motorStatusMoving(), 0);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorStatusMoving_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
status = setIntegerParam(pC_->changeStateRBV(), positionState == 2);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "changeStateRBV", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, motorStatusMoving, false);
setAxisParamChecked(this, changeStateRBV, positionState == 2);
return callParamCallbacks();
}
@@ -181,13 +172,7 @@ asynStatus detectorTowerAngleAxis::poll(bool *moving) {
if (axisNo() < liftAxis()->axisNo() && axisNo() < supportAxis()->axisNo()) {
status = pC_->pollDetectorAxes(moving, this, liftAxis(), supportAxis());
} else {
status = pC_->getIntegerParam(axisNo(), pC_->motorStatusMoving(),
(int *)moving);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorStatusMoving",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
getAxisParamChecked(this, motorStatusMoving, moving);
}
setWasMoving(*moving);
return status;
@@ -206,29 +191,20 @@ asynStatus detectorTowerAngleAxis::doMove(double position, int relative,
double max_velocity,
double acceleration) {
double motorRecResolution = 0.0;
asynStatus plStatus = pC_->getDoubleParam(
axisNo_, pC_->motorRecResolution(), &motorRecResolution);
if (plStatus != asynSuccess) {
return pC_->paramLibAccessFailed(plStatus, "motorRecResolution_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
getAxisParamChecked(this, motorRecResolution, &motorRecResolution);
// Signal to the deferredMovementCollectorLoop that a movement should be
// started to the defined target position.
setTargetPosition(position * motorRecResolution);
receivedTarget_ = true;
waitingForStart_ = true;
return asynSuccess;
}
asynStatus detectorTowerAngleAxis::startCombinedMove() {
// Status of read-write-operations of ASCII commands to the controller
asynStatus rwStatus = asynSuccess;
// Status of parameter library operations
asynStatus plStatus = asynSuccess;
asynStatus status = asynSuccess;
char command[pC_->MAXBUF_] = {0};
char response[pC_->MAXBUF_] = {0};
@@ -237,12 +213,7 @@ asynStatus detectorTowerAngleAxis::startCombinedMove() {
// =========================================================================
plStatus =
pC_->getIntegerParam(axisNo_, pC_->positionStateRBV(), &positionState);
if (plStatus != asynSuccess) {
return pC_->paramLibAccessFailed(plStatus, "positionStateRBV_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
getAxisParamChecked(this, positionStateRBV, &positionState);
// If the axis is in changer position, it must be moved into working
// position before any move can be started.
@@ -259,23 +230,11 @@ asynStatus detectorTowerAngleAxis::startCombinedMove() {
pC_->getMsgPrintControl().getSuffix());
}
if (isInChangerPos) {
plStatus = setStringParam(pC_->motorMessageText(),
"Move the axis to working state first.");
if (plStatus != asynSuccess) {
return pC_->paramLibAccessFailed(plStatus, "motorMessageText",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
plStatus = setIntegerParam(pC_->motorStatusProblem(), true);
if (plStatus != asynSuccess) {
return pC_->paramLibAccessFailed(plStatus, "motorStatusProblem_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
setAxisParamChecked(this, motorMessageText,
"Move the axis to working state first.");
setAxisParamChecked(this, motorStatusProblem, true);
callParamCallbacks();
startingDeferredMovement_ = false;
return asynError;
}
@@ -289,74 +248,57 @@ asynStatus detectorTowerAngleAxis::startCombinedMove() {
pC_->lock();
// We don't expect an answer
rwStatus = pC_->writeRead(axisNo_, command, response, 0);
status = pC_->writeRead(axisNo_, command, response, 0);
// Free the controller again
pC_->unlock();
if (rwStatus != asynSuccess) {
if (status != asynSuccess) {
asynPrint(
pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d\nStarting movement to "
"target position %lf failed.\n",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
motorCoordinatesPosition);
plStatus = setIntegerParam(pC_->motorStatusProblem(), true);
if (plStatus != asynSuccess) {
return pC_->paramLibAccessFailed(plStatus, "motorStatusProblem_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
setAxisParamChecked(this, motorStatusProblem, true);
callParamCallbacks();
}
return rwStatus;
return status;
}
asynStatus detectorTowerAngleAxis::stop(double acceleration) {
// Status of read-write-operations of ASCII commands to the controller
asynStatus rwStatus = asynSuccess;
// Status of parameter library operations
asynStatus plStatus = asynSuccess;
asynStatus status = asynSuccess;
char response[pC_->MAXBUF_] = {0};
// =========================================================================
rwStatus = pC_->writeRead(axisNo_, "P350=8", response, 0);
status = pC_->writeRead(axisNo_, "P350=8", response, 0);
if (rwStatus != 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__);
plStatus = setIntegerParam(pC_->motorStatusProblem(), true);
if (plStatus != asynSuccess) {
return pC_->paramLibAccessFailed(plStatus, "motorStatusProblem_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
setAxisParamChecked(this, motorStatusProblem, true);
return asynError;
}
// Reset the deferred movement flags
startingDeferredMovement_ = false;
deferredMovementWait_ = false;
return rwStatus;
receivedTarget_ = false;
waitingForStart_ = false;
liftAxis()->waitingForStart_ = false;
return status;
}
// The detector tower axis uses absolute encoders
asynStatus detectorTowerAngleAxis::readEncoderType() {
asynStatus status = setStringParam(pC_->encoderType(), AbsoluteEncoder);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "encoderType_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, encoderType, AbsoluteEncoder);
return asynSuccess;
}
@@ -366,27 +308,19 @@ detectorTowerAngleAxis::toggleWorkingChangerState(bool toChangingPosition) {
char response[pC_->MAXBUF_] = {0};
// Status of read-write-operations of ASCII commands to the controller
asynStatus rwStatus = asynSuccess;
// Status of parameter library operations
asynStatus plStatus = asynSuccess;
asynStatus status = asynSuccess;
bool moving = false;
int positionState = 0;
// =========================================================================
rwStatus = poll(&moving);
if (rwStatus != asynSuccess) {
return rwStatus;
status = poll(&moving);
if (status != asynSuccess) {
return status;
}
plStatus =
pC_->getIntegerParam(axisNo_, pC_->positionStateRBV(), &positionState);
if (plStatus != asynSuccess) {
return pC_->paramLibAccessFailed(plStatus, "positionStateRBV_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
getAxisParamChecked(this, positionStateRBV, &positionState);
if (moving) {
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
@@ -396,21 +330,10 @@ detectorTowerAngleAxis::toggleWorkingChangerState(bool toChangingPosition) {
toChangingPosition ? "changer" : "working",
pC_->getMsgPrintControl().getSuffix());
plStatus = setStringParam(
pC_->motorMessageText(),
setAxisParamChecked(
this, motorMessageText,
"Axis cannot be moved to changer position while it is moving.");
if (plStatus != asynSuccess) {
return pC_->paramLibAccessFailed(plStatus, "motorMessageText_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
plStatus = setIntegerParam(pC_->changeStateRBV(), !toChangingPosition);
if (plStatus != asynSuccess) {
return pC_->paramLibAccessFailed(plStatus, "changeStateRBV",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
setAxisParamChecked(this, changeStateRBV, !toChangingPosition);
return asynError;
}
@@ -428,39 +351,20 @@ detectorTowerAngleAxis::toggleWorkingChangerState(bool toChangingPosition) {
pC_->getMsgPrintControl().getSuffix());
// Update the PV anyway, even though nothing changed.
plStatus = setIntegerParam(pC_->changeStateRBV(), toChangingPosition);
if (plStatus != asynSuccess) {
return pC_->paramLibAccessFailed(plStatus, "changeStateRBV",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
setAxisParamChecked(this, changeStateRBV, toChangingPosition);
return asynSuccess;
}
// Move the axis into changer or working position
if (toChangingPosition) {
rwStatus = pC_->writeRead(axisNo_, "P350=2", response, 0);
status = pC_->writeRead(axisNo_, "P350=2", response, 0);
} else {
rwStatus = pC_->writeRead(axisNo_, "P350=3", response, 0);
status = pC_->writeRead(axisNo_, "P350=3", response, 0);
}
if (plStatus != asynSuccess) {
plStatus = setIntegerParam(pC_->changeStateRBV(), !toChangingPosition);
if (plStatus != asynSuccess) {
return pC_->paramLibAccessFailed(plStatus, "changeStateRBV",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
}
plStatus = setIntegerParam(pC_->changeStateRBV(), toChangingPosition);
if (plStatus != asynSuccess) {
return pC_->paramLibAccessFailed(plStatus, "changeStateRBV", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
return rwStatus;
setAxisParamChecked(this, changeStateRBV, toChangingPosition);
return asynSuccess;
}
asynStatus detectorTowerAngleAxis::adjustOrigin(double newOrigin) {
@@ -472,12 +376,7 @@ asynStatus detectorTowerAngleAxis::adjustOrigin(double newOrigin) {
// =========================================================================
status =
pC_->getIntegerParam(axisNo_, pC_->positionStateRBV(), &positionState);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "positionStateRBV_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
getAxisParamChecked(this, positionStateRBV, &positionState);
// If the axis is in changer position, it must be moved into working
// position before any move can be started.
@@ -506,12 +405,7 @@ asynStatus detectorTowerAngleAxis::adjustOrigin(double newOrigin) {
"angle 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__);
}
setAxisParamChecked(this, motorStatusProblem, true);
}
return status;
@@ -520,19 +414,14 @@ asynStatus detectorTowerAngleAxis::adjustOrigin(double newOrigin) {
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__);
}
getAxisParamChecked(this, positionStateRBV, &positionState);
// Reset the deferred movement flags
startingDeferredMovement_ = false;
deferredMovementWait_ = false;
receivedTarget_ = false;
waitingForStart_ = false;
liftAxis()->waitingForStart_ = false;
/*
Check which action should be performed:
@@ -661,11 +550,12 @@ static void configDetectorTowerCreateAxisCallFunc(const iocshArgBuf *args) {
// =============================================================================
/**
* @brief Set the setDeferredMovementWait (FFI implementation)
* @brief Set the setDeferredMovementWait time (FFI implementation)
*
* @param portName Name of the controller
* @param axisNo Axis number
* @param scaleMovTimeout Scaling factor (in seconds)
* @param deferredMovementWait Time (in seconds) the driver waits to collect
* all movement commands from the different axes
* @return asynStatus
*/
asynStatus setDeferredMovementWait(const char *portName, int axisNo,

View File

@@ -1,16 +1,9 @@
#ifndef detectorTowerAngleAxis_H
#define detectorTowerAngleAxis_H
#include "detectorTowerController.h"
#include "turboPmacAxis.h"
#include <errlog.h>
// Forward declaration of the controller class to resolve the cyclic dependency
// between the controller and the axis .h-file. See
// https://en.cppreference.com/w/cpp/language/class.
class detectorTowerController;
class detectorTowerLiftAxis;
class detectorTowerSupportAxis;
class detectorTowerAngleAxis : public turboPmacAxis {
class HIDDEN detectorTowerAngleAxis : public turboPmacAxis {
public:
/**
* @brief Construct a new detectorTowerAngleAxis
@@ -143,15 +136,15 @@ class detectorTowerAngleAxis : public turboPmacAxis {
*/
detectorTowerSupportAxis *supportAxis() { return supportAxis_; }
/**
* @brief Return a pointer to the axis controller
*/
virtual detectorTowerController *pController() override { return pC_; };
// If true, either this axis or one of the detectorTowerLiftAxis
// attached to it received a movement command.
bool receivedTarget_;
// If set to true, the virtual axis is about to start a deferred movement
// (but is currently still collecting movement commands from its component
// axes)
bool startingDeferredMovement_;
/*
The collector cycle waits until this time in seconds has passed before
starting a deferred movement
@@ -164,6 +157,10 @@ class detectorTowerAngleAxis : public turboPmacAxis {
*/
int error_;
// True, if this axis has received a move command and the driver is
// currently starting a deferred movement.
bool waitingForStart_;
protected:
detectorTowerController *pC_;
detectorTowerLiftAxis *liftAxis_;

View File

@@ -1,6 +1,7 @@
#include "detectorTowerController.h"
#include "detectorTowerAngleAxis.h"
#include "turboPmacController.h"
#include "detectorTowerLiftAxis.h"
#include "detectorTowerSupportAxis.h"
#include <epicsExport.h>
#include <errlog.h>
#include <iocsh.h>
@@ -286,7 +287,7 @@ asynStatus detectorTowerController::pollDetectorAxes(
int error = 0;
int positionState = 0;
int inPosition = 0;
int notInPosition = 0;
double angle = 0.0;
double prevAngle = 0.0;
@@ -336,37 +337,13 @@ asynStatus detectorTowerController::pollDetectorAxes(
The motorStatusProblem_ field changes the motor record fields SEVR and STAT.
*/
plStatus = angleAxis->setIntegerParam(motorStatusProblem(), false);
if (plStatus != asynSuccess) {
paramLibAccessFailed(plStatus, "motorStatusProblem_", angleAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
plStatus = liftAxis->setIntegerParam(motorStatusProblem(), false);
if (plStatus != asynSuccess) {
paramLibAccessFailed(plStatus, "motorStatusProblem_", liftAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
plStatus = supportAxis->setIntegerParam(motorStatusProblem(), false);
if (plStatus != asynSuccess) {
paramLibAccessFailed(plStatus, "motorStatusProblem_", supportAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(angleAxis, motorStatusProblem, false);
setAxisParamChecked(liftAxis, motorStatusProblem, false);
setAxisParamChecked(supportAxis, motorStatusProblem, false);
plStatus = angleAxis->setIntegerParam(motorStatusCommsError(), false);
if (plStatus != asynSuccess) {
paramLibAccessFailed(plStatus, "motorStatusCommsError_", angleAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
plStatus = liftAxis->setIntegerParam(motorStatusCommsError(), false);
if (plStatus != asynSuccess) {
paramLibAccessFailed(plStatus, "motorStatusCommsError_", liftAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
plStatus = supportAxis->setIntegerParam(motorStatusCommsError(), false);
if (plStatus != asynSuccess) {
paramLibAccessFailed(plStatus, "motorStatusCommsError_", supportAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(angleAxis, motorStatusCommsError, false);
setAxisParamChecked(liftAxis, motorStatusCommsError, false);
setAxisParamChecked(supportAxis, motorStatusCommsError, false);
// Read the previous motor positions
plStatus = angleAxis->motorPosition(&prevAngle);
@@ -403,7 +380,7 @@ asynStatus detectorTowerController::pollDetectorAxes(
nvals =
sscanf(response,
"%d %d %d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
&inPosition, &positionState, &error, &angle, &angleHighLimit,
&notInPosition, &positionState, &error, &angle, &angleHighLimit,
&angleLowLimit, &angleOrigin, &angleAdjustOriginHighLimit,
&angleAdjustOriginLowLimit, &lift, &liftHighLimit, &liftLowLimit,
&liftOrigin, &liftAdjustOriginHighLimit,
@@ -427,20 +404,12 @@ asynStatus detectorTowerController::pollDetectorAxes(
*/
// Angle
plStatus = getDoubleParam(angleAxisNo, motorLimitsOffset(), &limitsOffset);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorLimitsOffset_", angleAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
getAxisParamChecked(angleAxis, motorLimitsOffset, &limitsOffset);
angleHighLimit = angleHighLimit - limitsOffset;
angleLowLimit = angleLowLimit + limitsOffset;
// Lift
plStatus = getDoubleParam(liftAxisNo, motorLimitsOffset(), &limitsOffset);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorLimitsOffset_", liftAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
getAxisParamChecked(liftAxis, motorLimitsOffset, &limitsOffset);
liftHighLimit = liftHighLimit - limitsOffset;
liftLowLimit = liftLowLimit + limitsOffset;
@@ -448,16 +417,15 @@ asynStatus detectorTowerController::pollDetectorAxes(
angleAxis->error_ = error;
// Check if the tower is moving
if (inPosition == 1 || positionState > 2) {
// By now, the controller has actually started the movement
angleAxis->startingDeferredMovement_ = false;
if (notInPosition == 1 || positionState > 2) {
*moving = true;
// Since the tower is now moving, the axis by definition do not wait for
// movement start anymore.
liftAxis->waitingForStart_ = false;
angleAxis->waitingForStart_ = false;
} else {
if (angleAxis->startingDeferredMovement_) {
*moving = true;
} else {
*moving = false;
}
*moving = false;
}
// Calculate the lift position /w consideration of the angle
@@ -812,258 +780,96 @@ asynStatus detectorTowerController::pollDetectorAxes(
Does the paramLib already contain an error message? If either this is the
case or if error != 0, report a status problem for all axes.
*/
getStringParam(angleAxisNo, motorMessageText(), sizeof(waitingErrorMessage),
waitingErrorMessage);
getAxisParamChecked(angleAxis, motorMessageText, &waitingErrorMessage);
if (error != 0 || errorMessage[0] != '\0' ||
waitingErrorMessage[0] != '\0') {
plStatus = angleAxis->setIntegerParam(motorStatusProblem(), true);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorStatusProblem_",
angleAxisNo, __PRETTY_FUNCTION__,
__LINE__);
}
plStatus = liftAxis->setIntegerParam(motorStatusProblem(), true);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorStatusProblem_",
liftAxisNo, __PRETTY_FUNCTION__,
__LINE__);
}
plStatus = supportAxis->setIntegerParam(motorStatusProblem(), true);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorStatusProblem_",
supportAxisNo, __PRETTY_FUNCTION__,
__LINE__);
}
setAxisParamChecked(angleAxis, motorStatusProblem, true);
setAxisParamChecked(liftAxis, motorStatusProblem, true);
setAxisParamChecked(supportAxis, motorStatusProblem, true);
}
// Update the error message text with the one created in this poll (in case
// it is not empty).
if (errorMessage[0] != '\0') {
plStatus = angleAxis->setStringParam(motorMessageText(), errorMessage);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorMessageText_",
angleAxisNo, __PRETTY_FUNCTION__,
__LINE__);
}
plStatus = liftAxis->setStringParam(motorMessageText(), errorMessage);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorMessageText_",
liftAxisNo, __PRETTY_FUNCTION__,
__LINE__);
}
plStatus =
supportAxis->setStringParam(motorMessageText(), errorMessage);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorMessageText_",
supportAxisNo, __PRETTY_FUNCTION__,
__LINE__);
}
setAxisParamChecked(angleAxis, motorMessageText, errorMessage);
setAxisParamChecked(liftAxis, motorMessageText, errorMessage);
setAxisParamChecked(supportAxis, motorMessageText, errorMessage);
}
// Update the working position state PV
plStatus = angleAxis->setIntegerParam(positionStateRBV(), positionState);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "positionStateRBV_", angleAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
plStatus = liftAxis->setIntegerParam(positionStateRBV(), positionState);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "positionStateRBV_", liftAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
plStatus = supportAxis->setIntegerParam(positionStateRBV(), positionState);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "positionStateRBV_",
supportAxisNo, __PRETTY_FUNCTION__,
__LINE__);
}
setAxisParamChecked(angleAxis, positionStateRBV, positionState);
setAxisParamChecked(liftAxis, positionStateRBV, positionState);
setAxisParamChecked(supportAxis, positionStateRBV, positionState);
// The axes are always enabled
plStatus = angleAxis->setIntegerParam(motorEnableRBV(), 1);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorEnableRBV_", angleAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
plStatus = liftAxis->setIntegerParam(motorEnableRBV(), 1);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorEnableRBV_", liftAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
plStatus = supportAxis->setIntegerParam(motorEnableRBV(), 1);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorEnableRBV_", supportAxisNo,
__PRETTY_FUNCTION__, __LINE__);
setAxisParamChecked(angleAxis, motorEnableRBV, true);
setAxisParamChecked(liftAxis, motorEnableRBV, true);
setAxisParamChecked(supportAxis, motorEnableRBV, true);
// If the axis is starting a movement, mark it as moving. Otherwise use the
// moving parameter.
if (angleAxis->waitingForStart_) {
setAxisParamChecked(angleAxis, motorStatusMoving, true);
setAxisParamChecked(angleAxis, motorStatusDone, false);
} else {
setAxisParamChecked(angleAxis, motorStatusMoving, *moving);
setAxisParamChecked(angleAxis, motorStatusDone, !(*moving));
}
// Are the axes currently moving?
plStatus = angleAxis->setIntegerParam(motorStatusMoving(), *moving);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorStatusMoving_", angleAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
plStatus = liftAxis->setIntegerParam(motorStatusMoving(), *moving);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorStatusMoving_", liftAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
plStatus = supportAxis->setIntegerParam(motorStatusMoving(), *moving);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorStatusMoving_",
supportAxisNo, __PRETTY_FUNCTION__,
__LINE__);
if (liftAxis->waitingForStart_) {
setAxisParamChecked(liftAxis, motorStatusMoving, true);
setAxisParamChecked(liftAxis, motorStatusDone, false);
} else {
setAxisParamChecked(liftAxis, motorStatusMoving, *moving);
setAxisParamChecked(liftAxis, motorStatusDone, !(*moving));
}
// Is the axis movement done?
plStatus = angleAxis->setIntegerParam(motorStatusDone(), !(*moving));
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorStatusDone_", angleAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
plStatus = liftAxis->setIntegerParam(motorStatusDone(), !(*moving));
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorStatusDone_", liftAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
plStatus = supportAxis->setIntegerParam(motorStatusDone(), !(*moving));
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorStatusDone_", supportAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
// Support axis status is solely deduced from system movement state
setAxisParamChecked(supportAxis, motorStatusMoving, *moving);
setAxisParamChecked(supportAxis, motorStatusDone, !(*moving));
// In which direction are the axes currently moving?
plStatus = angleAxis->setIntegerParam(motorStatusDirection(), angleDir);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorStatusDirection_",
angleAxisNo, __PRETTY_FUNCTION__, __LINE__);
}
plStatus = liftAxis->setIntegerParam(motorStatusDirection(), liftDir);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorStatusDirection_",
liftAxisNo, __PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(angleAxis, motorStatusDirection, angleDir);
setAxisParamChecked(liftAxis, motorStatusDirection, liftDir);
// 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__);
}
setAxisParamChecked(supportAxis, motorStatusDirection, liftDir);
// High limits from hardware
plStatus =
setDoubleParam(angleAxisNo, motorHighLimitFromDriver(), angleHighLimit);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorHighLimitFromDriver",
angleAxisNo, __PRETTY_FUNCTION__, __LINE__);
}
plStatus =
setDoubleParam(liftAxisNo, motorHighLimitFromDriver(), liftHighLimit);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorHighLimitFromDriver",
liftAxisNo, __PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(angleAxis, motorHighLimitFromDriver, angleHighLimit);
setAxisParamChecked(liftAxis, motorHighLimitFromDriver, liftHighLimit);
// 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__);
}
setAxisParamChecked(supportAxis, motorHighLimitFromDriver, liftHighLimit);
// Low limits from hardware
plStatus =
setDoubleParam(angleAxisNo, motorLowLimitFromDriver(), angleLowLimit);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorLowLimitFromDriver",
angleAxisNo, __PRETTY_FUNCTION__, __LINE__);
}
plStatus =
setDoubleParam(liftAxisNo, motorLowLimitFromDriver(), liftLowLimit);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorLowLimitFromDriver",
liftAxisNo, __PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(angleAxis, motorLowLimitFromDriver, angleLowLimit);
setAxisParamChecked(liftAxis, motorLowLimitFromDriver, liftLowLimit);
// 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__);
}
setAxisParamChecked(supportAxis, motorLowLimitFromDriver, liftLowLimit);
// Write the motor origin
plStatus = setDoubleParam(angleAxisNo, motorOrigin(), angleOrigin);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorOrigin", angleAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
plStatus = setDoubleParam(liftAxisNo, motorOrigin(), liftOrigin);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorOrigin", liftAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
plStatus = setDoubleParam(supportAxisNo, motorOrigin(), supportOrigin);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "supportOrigin", supportAxisNo,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(angleAxis, motorOrigin, angleOrigin);
setAxisParamChecked(liftAxis, motorOrigin, liftOrigin);
setAxisParamChecked(supportAxis, motorOrigin, supportOrigin);
// Origin adjustment high limit
plStatus =
setDoubleParam(angleAxisNo, motorAdjustOriginHighLimitFromDriver(),
angleAdjustOriginHighLimit);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorOriginHighLimitFromDriver",
angleAxisNo, __PRETTY_FUNCTION__, __LINE__);
}
plStatus =
setDoubleParam(liftAxisNo, motorAdjustOriginHighLimitFromDriver(),
liftAdjustOriginHighLimit);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus, "motorOriginHighLimitFromDriver",
liftAxisNo, __PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(angleAxis, motorAdjustOriginHighLimitFromDriver,
angleAdjustOriginHighLimit);
setAxisParamChecked(liftAxis, motorAdjustOriginHighLimitFromDriver,
liftAdjustOriginHighLimit);
// 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__);
}
setAxisParamChecked(supportAxis, motorAdjustOriginHighLimitFromDriver,
liftAdjustOriginHighLimit);
// Origin adjustment low limit
plStatus =
setDoubleParam(angleAxisNo, motorAdjustOriginLowLimitFromDriver(),
angleAdjustOriginLowLimit);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus,
"motorAdjustOriginLowLimitFromDriver",
angleAxisNo, __PRETTY_FUNCTION__, __LINE__);
}
plStatus = setDoubleParam(liftAxisNo, motorAdjustOriginLowLimitFromDriver(),
liftAdjustOriginLowLimit);
if (plStatus != asynSuccess) {
return paramLibAccessFailed(plStatus,
"motorAdjustOriginLowLimitFromDriver",
liftAxisNo, __PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(angleAxis, motorAdjustOriginLowLimitFromDriver,
angleAdjustOriginLowLimit);
setAxisParamChecked(liftAxis, motorAdjustOriginLowLimitFromDriver,
liftAdjustOriginLowLimit);
// 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__);
}
setAxisParamChecked(supportAxis, motorAdjustOriginLowLimitFromDriver,
liftAdjustOriginLowLimit);
// Axes positions
plStatus = angleAxis->setMotorPosition(angle);
@@ -1137,22 +943,9 @@ asynStatus detectorTowerController::pollDetectorAxes(
one poll cycle, but are cleared afterwards. Persisting error messages will
be recreated during each poll.
*/
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__);
}
setAxisParamChecked(angleAxis, motorMessageText, "");
setAxisParamChecked(liftAxis, motorMessageText, "");
setAxisParamChecked(supportAxis, motorMessageText, "");
return pollStatus;
}

View File

@@ -8,12 +8,16 @@
#ifndef detectorTowerController_H
#define detectorTowerController_H
#include "detectorTowerAngleAxis.h"
#include "detectorTowerLiftAxis.h"
#include "detectorTowerSupportAxis.h"
#include "turboPmacController.h"
class detectorTowerController : public turboPmacController {
// Forward declaration of the axis classes to resolve the cyclic dependency
// between the controller and the axis .h-file. See
// https://en.cppreference.com/w/cpp/language/class.
class HIDDEN detectorTowerAngleAxis;
class HIDDEN detectorTowerLiftAxis;
class HIDDEN detectorTowerSupportAxis;
class HIDDEN detectorTowerController : public turboPmacController {
public:
/**

View File

@@ -1,6 +1,7 @@
#include "detectorTowerLiftAxis.h"
#include "detectorTowerAngleAxis.h"
#include "detectorTowerController.h"
#include "detectorTowerSupportAxis.h"
#include "turboPmacController.h"
#include <epicsExport.h>
#include <errlog.h>
@@ -69,6 +70,9 @@ detectorTowerLiftAxis::detectorTowerLiftAxis(detectorTowerController *pC,
angleAxis_ = angleAxis;
angleAxis->liftAxis_ = this;
// Initialize the flag to false
waitingForStart_ = false;
}
detectorTowerLiftAxis::~detectorTowerLiftAxis(void) {
@@ -111,11 +115,7 @@ asynStatus detectorTowerLiftAxis::init() {
}
// Initialize the motorStatusMoving flag
status = setIntegerParam(pC_->motorStatusMoving(), 0);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorStatusMoving_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, motorStatusMoving, false);
// Check if we are currently in the changer position and update the PV
// accordingly
@@ -126,11 +126,7 @@ asynStatus detectorTowerLiftAxis::init() {
__PRETTY_FUNCTION__, __LINE__);
}
status = setIntegerParam(pC_->changeStateRBV(), positionState == 2);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "changeStateRBV", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, changeStateRBV, positionState == 2);
return callParamCallbacks();
}
@@ -146,13 +142,7 @@ asynStatus detectorTowerLiftAxis::poll(bool *moving) {
status = pC_->pollDetectorAxes(moving, angleAxis(), this,
angleAxis()->supportAxis());
} else {
status = pC_->getIntegerParam(axisNo(), pC_->motorStatusMoving(),
(int *)moving);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorStatusMoving",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
getAxisParamChecked(this, motorStatusMoving, moving);
}
setWasMoving(*moving);
return status;
@@ -170,22 +160,15 @@ asynStatus detectorTowerLiftAxis::doMove(double position, int relative,
double min_velocity,
double max_velocity,
double acceleration) {
double motorRecResolution = 0.0;
asynStatus plStatus = pC_->getDoubleParam(
axisNo_, pC_->motorRecResolution(), &motorRecResolution);
if (plStatus != asynSuccess) {
return pC_->paramLibAccessFailed(plStatus, "motorRecResolution_",
axisNo_, __PRETTY_FUNCTION__,
__LINE__);
}
getAxisParamChecked(this, motorRecResolution, &motorRecResolution);
// Signal to the deferredMovementCollectorLoop (of the
// detectorTowerAngleAxis) that a movement should be started to the
// defined target position.
setTargetPosition(position * motorRecResolution);
angleAxis_->receivedTarget_ = true;
waitingForStart_ = true;
return asynSuccess;
}
@@ -208,12 +191,7 @@ asynStatus detectorTowerLiftAxis::adjustOrigin(double newOrigin) {
// =========================================================================
status =
pC_->getIntegerParam(axisNo_, pC_->positionStateRBV(), &positionState);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "positionStateRBV_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
getAxisParamChecked(this, positionStateRBV, &positionState);
// If the axis is in changer position, it must be moved into working
// position before any move can be started.
@@ -242,13 +220,8 @@ asynStatus detectorTowerLiftAxis::adjustOrigin(double newOrigin) {
"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__);
}
setAxisParamChecked(this, motorStatusProblem, true);
}
return status;
}
}

View File

@@ -1,14 +1,9 @@
#ifndef detectorTowerLiftAxis_H
#define detectorTowerLiftAxis_H
#include "detectorTowerController.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;
class detectorTowerLiftAxis : public turboPmacAxis {
class HIDDEN detectorTowerLiftAxis : public turboPmacAxis {
public:
/**
* @brief Construct a new detectorTowerAngleAxis
@@ -110,6 +105,15 @@ class detectorTowerLiftAxis : public turboPmacAxis {
*/
asynStatus readEncoderType();
/**
* @brief Return a pointer to the axis controller
*/
virtual detectorTowerController *pController() override { return pC_; };
// True, if this axis has received a move command and the driver is
// currently starting a deferred movement.
bool waitingForStart_;
protected:
detectorTowerController *pC_;
detectorTowerAngleAxis *angleAxis_;

View File

@@ -1,6 +1,7 @@
#include "detectorTowerSupportAxis.h"
#include "detectorTowerAngleAxis.h"
#include "detectorTowerController.h"
#include "detectorTowerLiftAxis.h"
#include "turboPmacController.h"
#include <epicsExport.h>
#include <errlog.h>
@@ -111,11 +112,7 @@ asynStatus detectorTowerSupportAxis::init() {
}
// Initialize the motorStatusMoving flag
status = setIntegerParam(pC_->motorStatusMoving(), 0);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "motorStatusMoving_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, motorStatusMoving, false);
// Check if we are currently in the changer position and update the PV
// accordingly
@@ -126,12 +123,7 @@ asynStatus detectorTowerSupportAxis::init() {
__PRETTY_FUNCTION__, __LINE__);
}
status = setIntegerParam(pC_->changeStateRBV(), positionState == 2);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "changeStateRBV", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
setAxisParamChecked(this, changeStateRBV, positionState == 2);
return callParamCallbacks();
}
@@ -147,13 +139,7 @@ asynStatus detectorTowerSupportAxis::poll(bool *moving) {
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__);
}
getAxisParamChecked(this, motorStatusMoving, moving);
}
setWasMoving(*moving);
return status;
@@ -186,12 +172,7 @@ asynStatus detectorTowerSupportAxis::adjustOrigin(double newOrigin) {
// =========================================================================
status =
pC_->getIntegerParam(axisNo_, pC_->positionStateRBV(), &positionState);
if (status != asynSuccess) {
return pC_->paramLibAccessFailed(status, "positionStateRBV_", axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
getAxisParamChecked(this, positionStateRBV, &positionState);
// If the axis is in changer position, it must be moved into working
// position before any move can be started.
@@ -220,12 +201,8 @@ asynStatus detectorTowerSupportAxis::adjustOrigin(double newOrigin) {
"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__);
}
setAxisParamChecked(this, motorStatusProblem, true);
}
return status;

View File

@@ -1,18 +1,13 @@
#ifndef detectorTowerSupportAxis_H
#define detectorTowerSupportAxis_H
#include "detectorTowerController.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 {
class HIDDEN detectorTowerSupportAxis : public turboPmacAxis {
public:
/**
* @brief Construct a new detectorTowerSupportAxis
@@ -112,6 +107,11 @@ class detectorTowerSupportAxis : public turboPmacAxis {
*/
asynStatus readEncoderType();
/**
* @brief Return a pointer to the axis controller
*/
virtual detectorTowerController *pController() override { return pC_; };
protected:
detectorTowerController *pC_;
detectorTowerAngleAxis *angleAxis_;