Adjusted driver with auxiliary axes offsets
This commit is contained in:
246
.clang-format
Normal file
246
.clang-format
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
# BasedOnStyle: LLVM
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignArrayOfStructures: None
|
||||||
|
AlignConsecutiveAssignments:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: true
|
||||||
|
AlignConsecutiveBitFields:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveDeclarations:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveMacros:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveShortCaseStatements:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCaseColons: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: Align
|
||||||
|
AlignTrailingComments:
|
||||||
|
Kind: Always
|
||||||
|
OverEmptyLines: 0
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowBreakBeforeNoexceptSpecifier: Never
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortCompoundRequirementOnASingleLine: true
|
||||||
|
AllowShortEnumsOnASingleLine: true
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: MultiLine
|
||||||
|
AttributeMacros:
|
||||||
|
- __capability
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: Never
|
||||||
|
AfterEnum: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakAdjacentStringLiterals: true
|
||||||
|
BreakAfterAttributes: Leave
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakArrays: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeConceptDeclarations: Always
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeInlineASMColon: OnlyMultiline
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 80
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
EmptyLineAfterAccessModifier: Never
|
||||||
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IfMacros:
|
||||||
|
- KJ_IF_MAYBE
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IncludeIsMainSourceRegex: ''
|
||||||
|
IndentAccessModifiers: false
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentExternBlock: AfterExternBlock
|
||||||
|
IndentGotoLabels: true
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentRequiresClause: true
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
InsertBraces: false
|
||||||
|
InsertNewlineAtEOF: false
|
||||||
|
InsertTrailingCommas: None
|
||||||
|
IntegerLiteralSeparator:
|
||||||
|
Binary: 0
|
||||||
|
BinaryMinDigits: 0
|
||||||
|
Decimal: 0
|
||||||
|
DecimalMinDigits: 0
|
||||||
|
Hex: 0
|
||||||
|
HexMinDigits: 0
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
KeepEmptyLinesAtEOF: false
|
||||||
|
LambdaBodyIndentation: Signature
|
||||||
|
LineEnding: DeriveLF
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBinPackProtocolList: Auto
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCBreakBeforeNestedBlockParam: true
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PackConstructorInitializers: BinPack
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakOpenParenthesis: 0
|
||||||
|
PenaltyBreakScopeResolution: 500
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyIndentedWhitespace: 0
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PointerAlignment: Right
|
||||||
|
PPIndentWidth: -1
|
||||||
|
QualifierAlignment: Leave
|
||||||
|
ReferenceAlignment: Pointer
|
||||||
|
ReflowComments: true
|
||||||
|
RemoveBracesLLVM: false
|
||||||
|
RemoveParentheses: Leave
|
||||||
|
RemoveSemicolon: false
|
||||||
|
RequiresClausePosition: OwnLine
|
||||||
|
RequiresExpressionIndentation: OuterScope
|
||||||
|
SeparateDefinitionBlocks: Leave
|
||||||
|
ShortNamespaceLines: 1
|
||||||
|
SkipMacroDefinitionBody: false
|
||||||
|
SortIncludes: CaseSensitive
|
||||||
|
SortJavaStaticImport: Before
|
||||||
|
SortUsingDeclarations: LexicographicNumeric
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCaseColon: false
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeJsonColon: false
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeParensOptions:
|
||||||
|
AfterControlStatements: true
|
||||||
|
AfterForeachMacros: true
|
||||||
|
AfterFunctionDefinitionName: false
|
||||||
|
AfterFunctionDeclarationName: false
|
||||||
|
AfterIfMacros: true
|
||||||
|
AfterOverloadedOperator: false
|
||||||
|
AfterPlacementOperator: true
|
||||||
|
AfterRequiresInClause: false
|
||||||
|
AfterRequiresInExpression: false
|
||||||
|
BeforeNonEmptyParentheses: false
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: Never
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInLineCommentPrefix:
|
||||||
|
Minimum: 1
|
||||||
|
Maximum: -1
|
||||||
|
SpacesInParens: Never
|
||||||
|
SpacesInParensOptions:
|
||||||
|
InCStyleCasts: false
|
||||||
|
InConditionalStatements: false
|
||||||
|
InEmptyParentheses: false
|
||||||
|
Other: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Latest
|
||||||
|
StatementAttributeLikeMacros:
|
||||||
|
- Q_EMIT
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 8
|
||||||
|
UseTab: Never
|
||||||
|
VerilogBreakBetweenInstancePorts: true
|
||||||
|
WhitespaceSensitiveMacros:
|
||||||
|
- BOOST_PP_STRINGIZE
|
||||||
|
- CF_SWIFT_NAME
|
||||||
|
- NS_SWIFT_NAME
|
||||||
|
- PP_STRINGIZE
|
||||||
|
- STRINGIZE
|
||||||
|
...
|
||||||
|
|
9
Makefile
9
Makefile
@ -13,15 +13,18 @@ REQUIRED+=motorBase
|
|||||||
motorBase_VERSION=7.2.2
|
motorBase_VERSION=7.2.2
|
||||||
|
|
||||||
# Specify the version of turboPmac we want to build against
|
# Specify the version of turboPmac we want to build against
|
||||||
turboPmac_VERSION=0.10.0
|
sinqMotor_VERSION=mathis_s
|
||||||
|
|
||||||
|
# Specify the version of turboPmac we want to build against
|
||||||
|
turboPmac_VERSION=mathis_s
|
||||||
|
|
||||||
# These headers allow to depend on this library for derived drivers.
|
# These headers allow to depend on this library for derived drivers.
|
||||||
HEADERS += src/auxiliaryAxis.h
|
HEADERS += src/detectorTowerAuxiliaryAxis.h
|
||||||
HEADERS += src/detectorTowerAxis.h
|
HEADERS += src/detectorTowerAxis.h
|
||||||
HEADERS += src/detectorTowerController.h
|
HEADERS += src/detectorTowerController.h
|
||||||
|
|
||||||
# Source files to build
|
# Source files to build
|
||||||
SOURCES += src/auxiliaryAxis.cpp
|
SOURCES += src/detectorTowerAuxiliaryAxis.cpp
|
||||||
SOURCES += src/detectorTowerAxis.cpp
|
SOURCES += src/detectorTowerAxis.cpp
|
||||||
SOURCES += src/detectorTowerController.cpp
|
SOURCES += src/detectorTowerController.cpp
|
||||||
|
|
||||||
|
@ -7,15 +7,17 @@
|
|||||||
This is a driver for the detector tower which is based on the Turbo PMAC driver (https://git.psi.ch/sinq-epics-modules/turboPmac). It consists of the following three objects:
|
This is a driver for the detector tower which is based on the Turbo PMAC driver (https://git.psi.ch/sinq-epics-modules/turboPmac). It consists of the following three objects:
|
||||||
- `detectorTowerAxis`: This is a virtual axis which controls multiple physical motors in order to provide a synchronized movement.
|
- `detectorTowerAxis`: This is a virtual axis which controls multiple physical motors in order to provide a synchronized movement.
|
||||||
- `detectorTowerController`: This is an expanded variant of `turboPmacController` provided by the Turbo PMAC library linked above.It is needed to operate a `detectorTowerAxis`, but it can also be used to operate a "normal" `turboPmacAxis`.
|
- `detectorTowerController`: This is an expanded variant of `turboPmacController` provided by the Turbo PMAC library linked above.It is needed to operate a `detectorTowerAxis`, but it can also be used to operate a "normal" `turboPmacAxis`.
|
||||||
- `auxiliaryAxis`: This is an auxiliary axis type attached to the main detector axis. Multiple instances of these axes are constructed automatically when creating a `detectorTowerAxis`.
|
- `detectorTowerAuxiliaryAxis`: This is an auxiliary axis type attached to the main detector axis. Multiple instances of these axes are constructed automatically when creating a `detectorTowerAxis`.
|
||||||
The header files contain detailed documentation for all public functions. The headers themselves are exported when building the library to allow other drivers to depend on this one.
|
The header files contain detailed documentation for all public functions. The headers themselves are exported when building the library to allow other drivers to depend on this one.
|
||||||
|
|
||||||
## User guide
|
## User guide
|
||||||
|
|
||||||
The centerpiece of this driver is the `detectorTowerAxis`, which controls the angle of the detector flight tube. Creating an instance of this axis type also creates multiple so-called `auxiliaryAxis`, which are used to perform secondary movements.
|
The centerpiece of this driver is the `detectorTowerAxis`, which controls the angle of the detector flight tube. Creating an instance of this axis type also creates multiple so-called `detectorTowerAuxiliaryAxis`, which are used to perform secondary movements.
|
||||||
|
|
||||||
The utilities provided in the `utils` folder of https://git.psi.ch/sinq-epics-modules/turboPmac work with this driver as well.
|
The utilities provided in the `utils` folder of https://git.psi.ch/sinq-epics-modules/turboPmac work with this driver as well.
|
||||||
|
|
||||||
|
TODO: How to start combined movement
|
||||||
|
|
||||||
### Usage in IOC shell
|
### Usage in IOC shell
|
||||||
|
|
||||||
detectorTower exports the following IOC shell functions:
|
detectorTower exports the following IOC shell functions:
|
||||||
@ -99,7 +101,7 @@ Note that the speed of the detector tower axes 1, 2 and 3 cannot be set. Setting
|
|||||||
|
|
||||||
The code is designed around the `detectorTowerAxis`, which controls the angle of the beam guide and acts as a "master" axis. Other movements are realized as auxiliary axes (e.g. for the vertical lift offset and the tilt offset). The `detectorTowerAxis` has pointers to all associated auxiliary axes and (as described above) its IOC shell constructor also builds the associated auxiliary axes.
|
The code is designed around the `detectorTowerAxis`, which controls the angle of the beam guide and acts as a "master" axis. Other movements are realized as auxiliary axes (e.g. for the vertical lift offset and the tilt offset). The `detectorTowerAxis` has pointers to all associated auxiliary axes and (as described above) its IOC shell constructor also builds the associated auxiliary axes.
|
||||||
|
|
||||||
The `doPoll` implementation for `detectorTowerAxis` queries the status of both the `detectorTowerAxis` itself and all associated auxiliary axes. If any of the axes is moving, the `detectorTowerAxis` is set to "moving" as well. In turn, the `doPoll` implementation of a `auxiliaryAxis` checks if its associated `detectorTowerAxis` is moving and sets its own movement status accordingly.
|
The `doPoll` implementation for `detectorTowerAxis` queries the status of both the `detectorTowerAxis` itself and all associated auxiliary axes. If any of the axes is moving, the `detectorTowerAxis` is set to "moving" as well. In turn, the `doPoll` implementation of a `detectorTowerAuxiliaryAxis` checks if its associated `detectorTowerAxis` is moving and sets its own movement status accordingly.
|
||||||
|
|
||||||
The `detectorTowerController` is a thin wrapper around a `turboPmacController` which overwrites the `readInt32` and `writeInt32` in order to support the PVs "$(INSTR)$(M):ChangeState", "$(INSTR)$(M):PositionStateRBV" and "$(INSTR)$(M):ChangingStateRBV". Any calls to these two methods not concerning the aforementioned PVs are directly forwarded to `turboPmacController::readInt32` / `turboPmacController::writeInt32`.
|
The `detectorTowerController` is a thin wrapper around a `turboPmacController` which overwrites the `readInt32` and `writeInt32` in order to support the PVs "$(INSTR)$(M):ChangeState", "$(INSTR)$(M):PositionStateRBV" and "$(INSTR)$(M):ChangingStateRBV". Any calls to these two methods not concerning the aforementioned PVs are directly forwarded to `turboPmacController::readInt32` / `turboPmacController::writeInt32`.
|
||||||
|
|
||||||
|
@ -36,3 +36,12 @@ record(longout, "$(INSTR)$(M):ChangingStateRBV_int") {
|
|||||||
field(DOL, "$(INSTR)$(M):ChangingStateRBV CP")
|
field(DOL, "$(INSTR)$(M):ChangingStateRBV CP")
|
||||||
field(OMSL, "closed_loop")
|
field(OMSL, "closed_loop")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Set an additional offset to the target position of an auxiliary axis
|
||||||
|
# For all other axis types, writing to this parameter does nothing.
|
||||||
|
record(ao, "$(INSTR)$(M):TargetOffset") {
|
||||||
|
field(DTYP, "asynFloat64")
|
||||||
|
field(OUT, "@asyn($(CONTROLLER),$(AXIS),1) MOTOR_TARGET_OFFSET")
|
||||||
|
field(PINI, "YES")
|
||||||
|
field(VAL, "0")
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
#include "auxiliaryAxis.h"
|
#include "detectorTowerAuxiliaryAxis.h"
|
||||||
#include "detectorTowerAxis.h"
|
#include "detectorTowerAxis.h"
|
||||||
#include "detectorTowerController.h"
|
#include "detectorTowerController.h"
|
||||||
#include "turboPmacController.h"
|
#include "turboPmacController.h"
|
||||||
@ -7,10 +7,10 @@
|
|||||||
#include <iocsh.h>
|
#include <iocsh.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Contains all instances of auxiliaryAxis which have been created and is used
|
Contains all instances of detectorTowerAuxiliaryAxis which have been created and
|
||||||
in the initialization hook function.
|
is used in the initialization hook function.
|
||||||
*/
|
*/
|
||||||
static std::vector<auxiliaryAxis *> axes;
|
static std::vector<detectorTowerAuxiliaryAxis *> axes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Hook function to perform certain actions during the IOC initialization
|
* @brief Hook function to perform certain actions during the IOC initialization
|
||||||
@ -21,15 +21,17 @@ static void epicsInithookFunction(initHookState iState) {
|
|||||||
if (iState == initHookAfterDatabaseRunning) {
|
if (iState == initHookAfterDatabaseRunning) {
|
||||||
// Iterate through all axes of each and call the initialization method
|
// Iterate through all axes of each and call the initialization method
|
||||||
// on each one of them.
|
// on each one of them.
|
||||||
for (std::vector<auxiliaryAxis *>::iterator itA = axes.begin();
|
for (std::vector<detectorTowerAuxiliaryAxis *>::iterator itA =
|
||||||
|
axes.begin();
|
||||||
itA != axes.end(); ++itA) {
|
itA != axes.end(); ++itA) {
|
||||||
auxiliaryAxis *axis = *itA;
|
detectorTowerAuxiliaryAxis *axis = *itA;
|
||||||
axis->init();
|
axis->init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auxiliaryAxis::auxiliaryAxis(detectorTowerController *pC, int axisNo)
|
detectorTowerAuxiliaryAxis::detectorTowerAuxiliaryAxis(
|
||||||
|
detectorTowerController *pC, int axisNo)
|
||||||
: turboPmacAxis(pC, axisNo, false), pC_(pC) {
|
: turboPmacAxis(pC, axisNo, false), pC_(pC) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -46,7 +48,7 @@ auxiliaryAxis::auxiliaryAxis(detectorTowerController *pC, int axisNo)
|
|||||||
is a configuration error.
|
is a configuration error.
|
||||||
*/
|
*/
|
||||||
if (axisNo >= pC->numAxes()) {
|
if (axisNo >= pC->numAxes()) {
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d: FATAL ERROR: "
|
"Controller \"%s\", axis %d => %s, line %d: FATAL ERROR: "
|
||||||
"Axis index %d must be smaller than the total number of axes "
|
"Axis index %d must be smaller than the total number of axes "
|
||||||
"%d",
|
"%d",
|
||||||
@ -65,12 +67,12 @@ auxiliaryAxis::auxiliaryAxis(detectorTowerController *pC, int axisNo)
|
|||||||
axes.push_back(this);
|
axes.push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
auxiliaryAxis::~auxiliaryAxis(void) {
|
detectorTowerAuxiliaryAxis::~detectorTowerAuxiliaryAxis(void) {
|
||||||
// Since the controller memory is managed somewhere else, we don't need to
|
// Since the controller memory is managed somewhere else, we don't need to
|
||||||
// clean up the pointer pC here.
|
// clean up the pointer pC here.
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus auxiliaryAxis::init() {
|
asynStatus detectorTowerAuxiliaryAxis::init() {
|
||||||
|
|
||||||
// Local variable declaration
|
// Local variable declaration
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
@ -85,7 +87,7 @@ asynStatus auxiliaryAxis::init() {
|
|||||||
&motorRecResolution);
|
&motorRecResolution);
|
||||||
if (status == asynParamUndefined) {
|
if (status == asynParamUndefined) {
|
||||||
if (now + maxInitTime < time(NULL)) {
|
if (now + maxInitTime < time(NULL)) {
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line "
|
"Controller \"%s\", axis %d => %s, line "
|
||||||
"%d\nInitializing the parameter library failed.\n",
|
"%d\nInitializing the parameter library failed.\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__,
|
||||||
@ -104,7 +106,7 @@ asynStatus auxiliaryAxis::init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Perform the actual poll
|
// Perform the actual poll
|
||||||
asynStatus auxiliaryAxis::doPoll(bool *moving) {
|
asynStatus detectorTowerAuxiliaryAxis::doPoll(bool *moving) {
|
||||||
|
|
||||||
// Return value for the poll
|
// Return value for the poll
|
||||||
asynStatus poll_status = asynSuccess;
|
asynStatus poll_status = asynSuccess;
|
||||||
@ -167,8 +169,8 @@ asynStatus auxiliaryAxis::doPoll(bool *moving) {
|
|||||||
bool wantToPrint = pl_status != asynSuccess;
|
bool wantToPrint = pl_status != asynSuccess;
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(
|
if (pC_->getMsgPrintControl().shouldBePrinted(
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, wantToPrint,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, wantToPrint,
|
||||||
pC_->asynUserSelf())) {
|
pC_->pasynUser())) {
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line "
|
"Controller \"%s\", axis %d => %s, line "
|
||||||
"%d:\ncallParamCallbacks failed with %s.%s\n",
|
"%d:\ncallParamCallbacks failed with %s.%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -184,8 +186,9 @@ asynStatus auxiliaryAxis::doPoll(bool *moving) {
|
|||||||
return poll_status;
|
return poll_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus auxiliaryAxis::doMove(double position, int relative,
|
asynStatus detectorTowerAuxiliaryAxis::doMove(double position, int relative,
|
||||||
double min_velocity, double max_velocity,
|
double min_velocity,
|
||||||
|
double max_velocity,
|
||||||
double acceleration) {
|
double acceleration) {
|
||||||
|
|
||||||
double motorRecResolution = 0.0;
|
double motorRecResolution = 0.0;
|
||||||
@ -205,7 +208,7 @@ asynStatus auxiliaryAxis::doMove(double position, int relative,
|
|||||||
return asynSuccess;
|
return asynSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus auxiliaryAxis::stop(double acceleration) {
|
asynStatus detectorTowerAuxiliaryAxis::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 rw_status = asynSuccess;
|
||||||
@ -213,7 +216,7 @@ asynStatus auxiliaryAxis::stop(double acceleration) {
|
|||||||
// Status of parameter library operations
|
// Status of parameter library operations
|
||||||
asynStatus pl_status = asynSuccess;
|
asynStatus pl_status = asynSuccess;
|
||||||
|
|
||||||
char response[pC_->MAXBUF_];
|
char response[pC_->MAXBUF_] = {0};
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
@ -221,7 +224,7 @@ asynStatus auxiliaryAxis::stop(double acceleration) {
|
|||||||
|
|
||||||
if (rw_status != asynSuccess) {
|
if (rw_status != asynSuccess) {
|
||||||
asynPrint(
|
asynPrint(
|
||||||
pC_->asynUserSelf(), 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__);
|
||||||
@ -238,4 +241,4 @@ asynStatus auxiliaryAxis::stop(double acceleration) {
|
|||||||
return rw_status;
|
return rw_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus auxiliaryAxis::reset() { return dTA_->reset(); };
|
asynStatus detectorTowerAuxiliaryAxis::reset() { return dTA_->reset(); };
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef auxiliaryAxis_H
|
#ifndef detectorTowerAuxiliaryAxis_H
|
||||||
#define auxiliaryAxis_H
|
#define detectorTowerAuxiliaryAxis_H
|
||||||
#include "turboPmacAxis.h"
|
#include "turboPmacAxis.h"
|
||||||
|
|
||||||
// Forward declaration of the controller class to resolve the cyclic dependency
|
// Forward declaration of the controller class to resolve the cyclic dependency
|
||||||
@ -8,7 +8,7 @@
|
|||||||
class detectorTowerController;
|
class detectorTowerController;
|
||||||
class detectorTowerAxis;
|
class detectorTowerAxis;
|
||||||
|
|
||||||
class auxiliaryAxis : public turboPmacAxis {
|
class detectorTowerAuxiliaryAxis : public turboPmacAxis {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Construct a new detectorTowerAxis
|
* @brief Construct a new detectorTowerAxis
|
||||||
@ -16,13 +16,14 @@ class auxiliaryAxis : public turboPmacAxis {
|
|||||||
* @param pController Pointer to the associated controller
|
* @param pController Pointer to the associated controller
|
||||||
* @param axisNo Index of the axis
|
* @param axisNo Index of the axis
|
||||||
*/
|
*/
|
||||||
auxiliaryAxis(detectorTowerController *pController, int axisNo);
|
detectorTowerAuxiliaryAxis(detectorTowerController *pController,
|
||||||
|
int axisNo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Destroy the turboPmacAxis
|
* @brief Destroy the turboPmacAxis
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual ~auxiliaryAxis();
|
virtual ~detectorTowerAuxiliaryAxis();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Readout of some values from the controller at IOC startup
|
* @brief Readout of some values from the controller at IOC startup
|
@ -47,9 +47,10 @@ static void deferredMovementCollectorLoop(void *drvPvt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
detectorTowerAxis::detectorTowerAxis(detectorTowerController *pC, int axisNo,
|
detectorTowerAxis::detectorTowerAxis(
|
||||||
auxiliaryAxis *liftOffsetAxis,
|
detectorTowerController *pC, int axisNo,
|
||||||
auxiliaryAxis *tiltOffsetAxis)
|
detectorTowerAuxiliaryAxis *liftZeroCorrAxis,
|
||||||
|
detectorTowerAuxiliaryAxis *tiltZeroCorrAxis)
|
||||||
: turboPmacAxis(pC, axisNo, false), pC_(pC) {
|
: turboPmacAxis(pC, axisNo, false), pC_(pC) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -66,7 +67,7 @@ detectorTowerAxis::detectorTowerAxis(detectorTowerController *pC, int axisNo,
|
|||||||
is a configuration error.
|
is a configuration error.
|
||||||
*/
|
*/
|
||||||
if (axisNo >= pC->numAxes()) {
|
if (axisNo >= pC->numAxes()) {
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d: FATAL ERROR: "
|
"Controller \"%s\", axis %d => %s, line %d: FATAL ERROR: "
|
||||||
"Axis index %d must be smaller than the total number of axes "
|
"Axis index %d must be smaller than the total number of axes "
|
||||||
"%d",
|
"%d",
|
||||||
@ -81,10 +82,13 @@ detectorTowerAxis::detectorTowerAxis(detectorTowerController *pC, int axisNo,
|
|||||||
receivedTarget_ = false;
|
receivedTarget_ = false;
|
||||||
startingDeferredMovement_ = false;
|
startingDeferredMovement_ = false;
|
||||||
deferredMovementWait_ = 0.1; // seconds
|
deferredMovementWait_ = 0.1; // seconds
|
||||||
liftOffsetAxis_ = liftOffsetAxis;
|
liftZeroCorrAxis_ = liftZeroCorrAxis;
|
||||||
tiltOffsetAxis_ = tiltOffsetAxis;
|
tiltZeroCorrAxis_ = tiltZeroCorrAxis;
|
||||||
liftOffsetAxis->dTA_ = this;
|
liftZeroCorrAxis->dTA_ = this;
|
||||||
tiltOffsetAxis->dTA_ = this;
|
tiltZeroCorrAxis->dTA_ = this;
|
||||||
|
|
||||||
|
// Will be populated in the init() method
|
||||||
|
beamRadius_ = 0.0;
|
||||||
|
|
||||||
// Register the hook function during construction of the first axis object
|
// Register the hook function during construction of the first axis object
|
||||||
if (axes.empty()) {
|
if (axes.empty()) {
|
||||||
@ -116,6 +120,8 @@ asynStatus detectorTowerAxis::init() {
|
|||||||
// Local variable declaration
|
// Local variable declaration
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
double motorRecResolution = 0.0;
|
double motorRecResolution = 0.0;
|
||||||
|
char response[pC_->MAXBUF_] = {0};
|
||||||
|
int nvals = 0;
|
||||||
|
|
||||||
// The parameter library takes some time to be initialized. Therefore we
|
// The parameter library takes some time to be initialized. Therefore we
|
||||||
// wait until the status is not asynParamUndefined anymore.
|
// wait until the status is not asynParamUndefined anymore.
|
||||||
@ -126,7 +132,7 @@ asynStatus detectorTowerAxis::init() {
|
|||||||
&motorRecResolution);
|
&motorRecResolution);
|
||||||
if (status == asynParamUndefined) {
|
if (status == asynParamUndefined) {
|
||||||
if (now + maxInitTime < time(NULL)) {
|
if (now + maxInitTime < time(NULL)) {
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis "
|
"Controller \"%s\", axis "
|
||||||
"%ddeferredMovementCollectorLoop => %s, line "
|
"%ddeferredMovementCollectorLoop => %s, line "
|
||||||
"%d\nInitializing the parameter library failed.\n",
|
"%d\nInitializing the parameter library failed.\n",
|
||||||
@ -143,10 +149,22 @@ asynStatus detectorTowerAxis::init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read the detector radius
|
||||||
|
const char *command = "RADIUS";
|
||||||
|
status = pC_->writeRead(axisNo_, command, response, 10);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
nvals = sscanf(response, "%lf", &beamRadius_);
|
||||||
|
if (nvals != 1) {
|
||||||
|
return pC_->couldNotParseResponse(command, response, axisNo_,
|
||||||
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform the actual poll
|
|
||||||
asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
||||||
|
|
||||||
// Return value for the poll
|
// Return value for the poll
|
||||||
@ -158,7 +176,8 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
// Status of parameter library operations
|
// Status of parameter library operations
|
||||||
asynStatus pl_status = asynSuccess;
|
asynStatus pl_status = asynSuccess;
|
||||||
|
|
||||||
char response[pC_->MAXBUF_], userMessage[pC_->MAXBUF_];
|
char userMessage[pC_->MAXBUF_] = {0};
|
||||||
|
char response[pC_->MAXBUF_] = {0};
|
||||||
int nvals = 0;
|
int nvals = 0;
|
||||||
|
|
||||||
int direction = 0;
|
int direction = 0;
|
||||||
@ -172,11 +191,10 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
double highLimit = 0.0;
|
double highLimit = 0.0;
|
||||||
double lowLimit = 0.0;
|
double lowLimit = 0.0;
|
||||||
double detectorHeight = 0.0;
|
double detectorHeight = 0.0;
|
||||||
double detectorRadius = 0.0;
|
double liftZeroCorrHighLimit = 0.0;
|
||||||
double liftOffsetHighLimit = 0.0;
|
double liftZeroCorrLowLimit = 0.0;
|
||||||
double liftOffsetLowLimit = 0.0;
|
double tiltZeroCorrHighLimit = 0.0;
|
||||||
double tiltOffsetHighLimit = 0.0;
|
double tiltZeroCorrLowLimit = 0.0;
|
||||||
double tiltOffsetLowLimit = 0.0;
|
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
@ -202,20 +220,22 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
- Axis error
|
- Axis error
|
||||||
- Beam tilt angle
|
- Beam tilt angle
|
||||||
- Beam tilt angle limits
|
- Beam tilt angle limits
|
||||||
|
- Beam lift position
|
||||||
- Beam lift offset limits
|
- Beam lift offset limits
|
||||||
- Detector tilt offset limits
|
- Detector tilt offset limits
|
||||||
*/
|
*/
|
||||||
const char *command = "P354 P358 P359 Q510 Q513 Q514 Q353 Q354 Q553 Q554";
|
const char *command =
|
||||||
|
"P354 P358 P359 Q510 Q513 Q514 Q310 Q353 Q354 Q553 Q554";
|
||||||
rw_status = pC_->writeRead(axisNo_, command, response, 10);
|
rw_status = pC_->writeRead(axisNo_, command, response, 10);
|
||||||
if (rw_status != asynSuccess) {
|
if (rw_status != asynSuccess) {
|
||||||
return rw_status;
|
return rw_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
nvals =
|
nvals = sscanf(response, "%d %d %d %lf %lf %lf %lf %lf %lf %lf %lf",
|
||||||
sscanf(response, "%d %d %d %lf %lf %lf %lf %lf %lf %lf", &inPosition,
|
&inPosition, &positionState, &error, &beamTiltAngle,
|
||||||
&positionState, &error, &beamTiltAngle, &highLimit, &lowLimit,
|
&highLimit, &lowLimit, &detectorHeight,
|
||||||
&liftOffsetHighLimit, &liftOffsetLowLimit, &tiltOffsetHighLimit,
|
&liftZeroCorrHighLimit, &liftZeroCorrLowLimit,
|
||||||
&tiltOffsetLowLimit);
|
&tiltZeroCorrHighLimit, &tiltZeroCorrLowLimit);
|
||||||
if (nvals != 10) {
|
if (nvals != 10) {
|
||||||
return pC_->couldNotParseResponse(command, response, axisNo_,
|
return pC_->couldNotParseResponse(command, response, axisNo_,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
@ -300,9 +320,9 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
default:
|
default:
|
||||||
|
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyPosState, true,
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyPosState, true,
|
||||||
pC_->asynUserSelf())) {
|
pC_->pasynUser())) {
|
||||||
asynPrint(
|
asynPrint(
|
||||||
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nReached unknown "
|
"Controller \"%s\", axis %d => %s, line %d\nReached unknown "
|
||||||
"state P354 = %d.%s\n",
|
"state P354 = %d.%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -323,7 +343,7 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (resetCountPosState) {
|
if (resetCountPosState) {
|
||||||
pC_->getMsgPrintControl().resetCount(keyPosState, pC_->asynUserSelf());
|
pC_->getMsgPrintControl().resetCount(keyPosState, pC_->pasynUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*moving) {
|
if (*moving) {
|
||||||
@ -348,9 +368,9 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
pC_->asynUserSelf())) {
|
pC_->pasynUser())) {
|
||||||
asynPrint(
|
asynPrint(
|
||||||
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nBrake COZ not "
|
"Controller \"%s\", axis %d => %s, line %d\nBrake COZ not "
|
||||||
"released (P359=1).%s\n",
|
"released (P359=1).%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -373,9 +393,9 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
pC_->asynUserSelf())) {
|
pC_->pasynUser())) {
|
||||||
asynPrint(
|
asynPrint(
|
||||||
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nMove command "
|
"Controller \"%s\", axis %d => %s, line %d\nMove command "
|
||||||
"rejected because axis is already moving.%s\n",
|
"rejected because axis is already moving.%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -397,8 +417,8 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
pC_->asynUserSelf())) {
|
pC_->pasynUser())) {
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nError motor "
|
"Controller \"%s\", axis %d => %s, line %d\nError motor "
|
||||||
"FTZ.%s\n",
|
"FTZ.%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -421,9 +441,9 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
pC_->asynUserSelf())) {
|
pC_->pasynUser())) {
|
||||||
asynPrint(
|
asynPrint(
|
||||||
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nAxis stopped "
|
"Controller \"%s\", axis %d => %s, line %d\nAxis stopped "
|
||||||
"unexpectedly.%s\n",
|
"unexpectedly.%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -447,9 +467,9 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
pC_->asynUserSelf())) {
|
pC_->pasynUser())) {
|
||||||
asynPrint(
|
asynPrint(
|
||||||
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nRelease removed "
|
"Controller \"%s\", axis %d => %s, line %d\nRelease removed "
|
||||||
"while moving.%s\n",
|
"while moving.%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -473,9 +493,9 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
pC_->asynUserSelf())) {
|
pC_->pasynUser())) {
|
||||||
asynPrint(
|
asynPrint(
|
||||||
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nEmergency stop "
|
"Controller \"%s\", axis %d => %s, line %d\nEmergency stop "
|
||||||
"activated.%s\n",
|
"activated.%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -496,8 +516,8 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
pC_->asynUserSelf())) {
|
pC_->pasynUser())) {
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nError motor "
|
"Controller \"%s\", axis %d => %s, line %d\nError motor "
|
||||||
"COZ.%s\n",
|
"COZ.%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -520,8 +540,8 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
pC_->asynUserSelf())) {
|
pC_->pasynUser())) {
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nError motor "
|
"Controller \"%s\", axis %d => %s, line %d\nError motor "
|
||||||
"COM.%s\n",
|
"COM.%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -544,8 +564,8 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
|
|
||||||
case 9:
|
case 9:
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
pC_->asynUserSelf())) {
|
pC_->pasynUser())) {
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nError motor "
|
"Controller \"%s\", axis %d => %s, line %d\nError motor "
|
||||||
"COX.%s\n",
|
"COX.%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -568,8 +588,8 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
|
|
||||||
case 10:
|
case 10:
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
pC_->asynUserSelf())) {
|
pC_->pasynUser())) {
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nHit end "
|
"Controller \"%s\", axis %d => %s, line %d\nHit end "
|
||||||
"switch FTZ.%s\n",
|
"switch FTZ.%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -591,9 +611,9 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
case 11:
|
case 11:
|
||||||
// Following error
|
// Following error
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
pC_->asynUserSelf())) {
|
pC_->pasynUser())) {
|
||||||
asynPrint(
|
asynPrint(
|
||||||
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nMaximum allowed "
|
"Controller \"%s\", axis %d => %s, line %d\nMaximum allowed "
|
||||||
"following error FTZ exceeded.%s\n",
|
"following error FTZ exceeded.%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -618,9 +638,9 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
pC_->asynUserSelf())) {
|
pC_->pasynUser())) {
|
||||||
asynPrint(
|
asynPrint(
|
||||||
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nUnknown error "
|
"Controller \"%s\", axis %d => %s, line %d\nUnknown error "
|
||||||
"P359 = %d.%s\n",
|
"P359 = %d.%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, error,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, error,
|
||||||
@ -642,7 +662,7 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (resetError) {
|
if (resetError) {
|
||||||
pC_->getMsgPrintControl().resetCount(keyError, pC_->asynUserSelf());
|
pC_->getMsgPrintControl().resetCount(keyError, pC_->pasynUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the parameter library
|
// Update the parameter library
|
||||||
@ -701,46 +721,46 @@ asynStatus detectorTowerAxis::doPoll(bool *moving) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the values for the offset axes
|
// Set the values for the offset axes
|
||||||
int liftAxisNo = liftOffsetAxis_->axisNo_;
|
int liftAxisNo = liftZeroCorrAxis_->axisNo_;
|
||||||
double liftOffsetPosition =
|
double liftZeroCorrPosition =
|
||||||
detectorHeight + detectorRadius * sin(beamTiltAngle);
|
detectorHeight + beamRadius_ * sin(beamTiltAngle);
|
||||||
|
|
||||||
pl_status = setMotorPosition(liftOffsetPosition);
|
pl_status = setMotorPosition(liftZeroCorrPosition);
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return pl_status;
|
return pl_status;
|
||||||
}
|
}
|
||||||
pl_status = pC_->setDoubleParam(liftAxisNo, pC_->motorHighLimitFromDriver(),
|
pl_status = pC_->setDoubleParam(liftAxisNo, pC_->motorHighLimitFromDriver(),
|
||||||
liftOffsetHighLimit);
|
liftZeroCorrHighLimit);
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorHighLimitFromDriver_",
|
return pC_->paramLibAccessFailed(pl_status, "motorHighLimitFromDriver_",
|
||||||
liftAxisNo, __PRETTY_FUNCTION__,
|
liftAxisNo, __PRETTY_FUNCTION__,
|
||||||
__LINE__);
|
__LINE__);
|
||||||
}
|
}
|
||||||
pl_status = pC_->setDoubleParam(liftAxisNo, pC_->motorLowLimitFromDriver(),
|
pl_status = pC_->setDoubleParam(liftAxisNo, pC_->motorLowLimitFromDriver(),
|
||||||
liftOffsetLowLimit);
|
liftZeroCorrLowLimit);
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorLowLimitFromDriver_",
|
return pC_->paramLibAccessFailed(pl_status, "motorLowLimitFromDriver_",
|
||||||
liftAxisNo, __PRETTY_FUNCTION__,
|
liftAxisNo, __PRETTY_FUNCTION__,
|
||||||
__LINE__);
|
__LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tiltAxisNo = tiltOffsetAxis_->axisNo_;
|
int tiltAxisNo = tiltZeroCorrAxis_->axisNo_;
|
||||||
|
|
||||||
// There exists no readback value for tiltOffsetAxis_, hence we just set the
|
// There exists no readback value for tiltZeroCorrAxis_, hence we just set
|
||||||
// current position to the target position.
|
// the current position to the target position.
|
||||||
tiltOffsetAxis_->setMotorPosition(tiltOffsetAxis_->targetPosition_);
|
tiltZeroCorrAxis_->setMotorPosition(tiltZeroCorrAxis_->targetPosition_);
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return pl_status;
|
return pl_status;
|
||||||
}
|
}
|
||||||
pl_status = pC_->setDoubleParam(tiltAxisNo, pC_->motorHighLimitFromDriver(),
|
pl_status = pC_->setDoubleParam(tiltAxisNo, pC_->motorHighLimitFromDriver(),
|
||||||
tiltOffsetHighLimit);
|
tiltZeroCorrHighLimit);
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorHighLimitFromDriver_",
|
return pC_->paramLibAccessFailed(pl_status, "motorHighLimitFromDriver_",
|
||||||
tiltAxisNo, __PRETTY_FUNCTION__,
|
tiltAxisNo, __PRETTY_FUNCTION__,
|
||||||
__LINE__);
|
__LINE__);
|
||||||
}
|
}
|
||||||
pl_status = pC_->setDoubleParam(tiltAxisNo, pC_->motorLowLimitFromDriver(),
|
pl_status = pC_->setDoubleParam(tiltAxisNo, pC_->motorLowLimitFromDriver(),
|
||||||
tiltOffsetLowLimit);
|
tiltZeroCorrLowLimit);
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorLowLimitFromDriver_",
|
return pC_->paramLibAccessFailed(pl_status, "motorLowLimitFromDriver_",
|
||||||
tiltAxisNo, __PRETTY_FUNCTION__,
|
tiltAxisNo, __PRETTY_FUNCTION__,
|
||||||
@ -792,8 +812,11 @@ asynStatus detectorTowerAxis::startCombinedMove() {
|
|||||||
// Status of parameter library operations
|
// Status of parameter library operations
|
||||||
asynStatus pl_status = asynSuccess;
|
asynStatus pl_status = asynSuccess;
|
||||||
|
|
||||||
char command[pC_->MAXBUF_], response[pC_->MAXBUF_];
|
char command[pC_->MAXBUF_] = {0};
|
||||||
|
char response[pC_->MAXBUF_] = {0};
|
||||||
double motorCoordinatesPosition = 0.0;
|
double motorCoordinatesPosition = 0.0;
|
||||||
|
double offsetliftZeroCorr = 0.0;
|
||||||
|
double offsettiltZeroCorr = 0.0;
|
||||||
int positionState = 0;
|
int positionState = 0;
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
@ -803,8 +826,8 @@ asynStatus detectorTowerAxis::startCombinedMove() {
|
|||||||
bool isInChangerPos = positionState == 2 || positionState == 3;
|
bool isInChangerPos = positionState == 2 || positionState == 3;
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(
|
if (pC_->getMsgPrintControl().shouldBePrinted(
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
isInChangerPos, pC_->asynUserSelf())) {
|
isInChangerPos, pC_->pasynUser())) {
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nAxis cannot be "
|
"Controller \"%s\", axis %d => %s, line %d\nAxis cannot be "
|
||||||
"moved because it is moving from working to changer "
|
"moved because it is moving from working to changer "
|
||||||
"position, is in changer position or is moving from changer "
|
"position, is in changer position or is moving from changer "
|
||||||
@ -817,11 +840,30 @@ asynStatus detectorTowerAxis::startCombinedMove() {
|
|||||||
return asynError;
|
return asynError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read out any offsets for the zero correction axes
|
||||||
|
pl_status =
|
||||||
|
pC_->getDoubleParam(tiltZeroCorrAxis_->axisNo(),
|
||||||
|
pC_->motorTargetOffset(), &offsettiltZeroCorr);
|
||||||
|
if (pl_status != asynSuccess) {
|
||||||
|
return pC_->paramLibAccessFailed(pl_status, "motorTargetOffset",
|
||||||
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
|
}
|
||||||
|
pl_status =
|
||||||
|
pC_->getDoubleParam(liftZeroCorrAxis_->axisNo(),
|
||||||
|
pC_->motorTargetOffset(), &offsetliftZeroCorr);
|
||||||
|
if (pl_status != asynSuccess) {
|
||||||
|
return pC_->paramLibAccessFailed(pl_status, "motorTargetOffset",
|
||||||
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
// Set the target positions for beam tilt, detector tilt offset and lift
|
// Set the target positions for beam tilt, detector tilt offset and lift
|
||||||
// offset
|
// offset
|
||||||
snprintf(command, sizeof(command), "Q451=%lf Q454=%lf Q456=%lf P350=1",
|
snprintf(command, sizeof(command), "Q451=%lf Q454=%lf Q456=%lf P350=1",
|
||||||
targetPosition_, liftOffsetAxis_->targetPosition_,
|
targetPosition_,
|
||||||
tiltOffsetAxis_->targetPosition_);
|
liftZeroCorrAxis_->targetPosition_ + offsetliftZeroCorr,
|
||||||
|
tiltZeroCorrAxis_->targetPosition_ + offsettiltZeroCorr);
|
||||||
|
|
||||||
// Lock the access to the controller since this function runs in another
|
// Lock the access to the controller since this function runs in another
|
||||||
// thread than the poll method.
|
// thread than the poll method.
|
||||||
@ -835,7 +877,7 @@ asynStatus detectorTowerAxis::startCombinedMove() {
|
|||||||
|
|
||||||
if (rw_status != asynSuccess) {
|
if (rw_status != asynSuccess) {
|
||||||
asynPrint(
|
asynPrint(
|
||||||
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nStarting movement to "
|
"Controller \"%s\", axis %d => %s, line %d\nStarting movement to "
|
||||||
"target position %lf failed.\n",
|
"target position %lf failed.\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -859,7 +901,7 @@ asynStatus detectorTowerAxis::stop(double acceleration) {
|
|||||||
// Status of parameter library operations
|
// Status of parameter library operations
|
||||||
asynStatus pl_status = asynSuccess;
|
asynStatus pl_status = asynSuccess;
|
||||||
|
|
||||||
char response[pC_->MAXBUF_];
|
char response[pC_->MAXBUF_] = {0};
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
@ -867,7 +909,7 @@ asynStatus detectorTowerAxis::stop(double acceleration) {
|
|||||||
|
|
||||||
if (rw_status != asynSuccess) {
|
if (rw_status != asynSuccess) {
|
||||||
asynPrint(
|
asynPrint(
|
||||||
pC_->asynUserSelf(), 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__);
|
||||||
@ -897,7 +939,7 @@ asynStatus detectorTowerAxis::readEncoderType() {
|
|||||||
asynStatus
|
asynStatus
|
||||||
detectorTowerAxis::toggleWorkingChangerState(bool toChangingPosition) {
|
detectorTowerAxis::toggleWorkingChangerState(bool toChangingPosition) {
|
||||||
|
|
||||||
char response[pC_->MAXBUF_];
|
char response[pC_->MAXBUF_] = {0};
|
||||||
|
|
||||||
// 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 rw_status = asynSuccess;
|
||||||
@ -921,7 +963,7 @@ detectorTowerAxis::toggleWorkingChangerState(bool toChangingPosition) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (moving) {
|
if (moving) {
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is not "
|
"Controller \"%s\", axis %d => %s, line %d\nAxis is not "
|
||||||
"idle and can therefore not be moved to %s state.%s\n",
|
"idle and can therefore not be moved to %s state.%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -944,7 +986,7 @@ detectorTowerAxis::toggleWorkingChangerState(bool toChangingPosition) {
|
|||||||
(toChangingPosition == true && positionState == 2);
|
(toChangingPosition == true && positionState == 2);
|
||||||
|
|
||||||
if (isAlreadyThere) {
|
if (isAlreadyThere) {
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_WARNING,
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_WARNING,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is already "
|
"Controller \"%s\", axis %d => %s, line %d\nAxis is already "
|
||||||
"in %s position.%s\n",
|
"in %s position.%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
@ -973,7 +1015,7 @@ detectorTowerAxis::toggleWorkingChangerState(bool toChangingPosition) {
|
|||||||
|
|
||||||
asynStatus detectorTowerAxis::doReset() {
|
asynStatus detectorTowerAxis::doReset() {
|
||||||
|
|
||||||
char response[pC_->MAXBUF_];
|
char response[pC_->MAXBUF_] = {0};
|
||||||
asynStatus pl_status = asynSuccess;
|
asynStatus pl_status = asynSuccess;
|
||||||
int positionState = 0;
|
int positionState = 0;
|
||||||
|
|
||||||
@ -1014,7 +1056,8 @@ C wrapper for the axis constructor. Please refer to the detectorTower
|
|||||||
constructor documentation. The controller is read from the portName.
|
constructor documentation. The controller is read from the portName.
|
||||||
*/
|
*/
|
||||||
asynStatus detectorTowerCreateAxis(const char *portName, int axisDetectorTower,
|
asynStatus detectorTowerCreateAxis(const char *portName, int axisDetectorTower,
|
||||||
int liftOffsetaxisNo, int tiltOffsetaxisNo) {
|
int liftZeroCorraxisNo,
|
||||||
|
int tiltZeroCorraxisNo) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
findAsynPortDriver is a asyn library FFI function which uses the C ABI.
|
findAsynPortDriver is a asyn library FFI function which uses the C ABI.
|
||||||
@ -1053,9 +1096,9 @@ asynStatus detectorTowerCreateAxis(const char *portName, int axisDetectorTower,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Assert that the three indices are different from each other
|
// Assert that the three indices are different from each other
|
||||||
if (axisDetectorTower == liftOffsetaxisNo ||
|
if (axisDetectorTower == liftZeroCorraxisNo ||
|
||||||
axisDetectorTower == tiltOffsetaxisNo ||
|
axisDetectorTower == tiltZeroCorraxisNo ||
|
||||||
tiltOffsetaxisNo == liftOffsetaxisNo) {
|
tiltZeroCorraxisNo == liftZeroCorraxisNo) {
|
||||||
errlogPrintf("Controller \"%s\" => %s, line %d\nAll three axis indices "
|
errlogPrintf("Controller \"%s\" => %s, line %d\nAll three axis indices "
|
||||||
"must be unique.",
|
"must be unique.",
|
||||||
portName, __PRETTY_FUNCTION__, __LINE__);
|
portName, __PRETTY_FUNCTION__, __LINE__);
|
||||||
@ -1076,13 +1119,15 @@ asynStatus detectorTowerCreateAxis(const char *portName, int axisDetectorTower,
|
|||||||
be "leaked" here.
|
be "leaked" here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
auxiliaryAxis *liftOffsetAxis = new auxiliaryAxis(pC, liftOffsetaxisNo);
|
detectorTowerAuxiliaryAxis *liftZeroCorrAxis =
|
||||||
auxiliaryAxis *tiltOffsetAxis = new auxiliaryAxis(pC, tiltOffsetaxisNo);
|
new detectorTowerAuxiliaryAxis(pC, liftZeroCorraxisNo);
|
||||||
|
detectorTowerAuxiliaryAxis *tiltZeroCorrAxis =
|
||||||
|
new detectorTowerAuxiliaryAxis(pC, tiltZeroCorraxisNo);
|
||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||||
detectorTowerAxis *pAxis = new detectorTowerAxis(
|
detectorTowerAxis *pAxis = new detectorTowerAxis(
|
||||||
pC, axisDetectorTower, liftOffsetAxis, tiltOffsetAxis);
|
pC, axisDetectorTower, liftZeroCorrAxis, tiltZeroCorrAxis);
|
||||||
|
|
||||||
// Allow manipulation of the controller again
|
// Allow manipulation of the controller again
|
||||||
pC->unlock();
|
pC->unlock();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#ifndef detectorTowerAxis_H
|
#ifndef detectorTowerAxis_H
|
||||||
#define detectorTowerAxis_H
|
#define detectorTowerAxis_H
|
||||||
#include "auxiliaryAxis.h"
|
#include "detectorTowerAuxiliaryAxis.h"
|
||||||
#include "turboPmacAxis.h"
|
#include "turboPmacAxis.h"
|
||||||
|
|
||||||
// Forward declaration of the controller class to resolve the cyclic dependency
|
// Forward declaration of the controller class to resolve the cyclic dependency
|
||||||
@ -15,14 +15,14 @@ class detectorTowerAxis : public turboPmacAxis {
|
|||||||
*
|
*
|
||||||
* @param pController Pointer to the associated controller
|
* @param pController Pointer to the associated controller
|
||||||
* @param axisNo Index of the axis
|
* @param axisNo Index of the axis
|
||||||
* @param liftOffsetAxis Pointer to the attached axis which controls
|
* @param liftZeroCorrAxis Pointer to the attached axis which controls
|
||||||
* the lift offset
|
* the lift offset
|
||||||
* @param tiltOffsetAxis Pointer to the attached axis which controls
|
* @param tiltZeroCorrAxis Pointer to the attached axis which controls
|
||||||
* the tilt offset
|
* the tilt offset
|
||||||
*/
|
*/
|
||||||
detectorTowerAxis(detectorTowerController *pController, int axisNo,
|
detectorTowerAxis(detectorTowerController *pController, int axisNo,
|
||||||
auxiliaryAxis *liftOffsetAxis,
|
detectorTowerAuxiliaryAxis *liftZeroCorrAxis,
|
||||||
auxiliaryAxis *tiltOffsetAxis);
|
detectorTowerAuxiliaryAxis *tiltZeroCorrAxis);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Destroy the detectorTowerAxis
|
* @brief Destroy the detectorTowerAxis
|
||||||
@ -100,8 +100,8 @@ class detectorTowerAxis : public turboPmacAxis {
|
|||||||
*/
|
*/
|
||||||
asynStatus doReset();
|
asynStatus doReset();
|
||||||
|
|
||||||
// If true, either this axis or one of the auxiliaryAxis attached to it
|
// If true, either this axis or one of the detectorTowerAuxiliaryAxis
|
||||||
// received a movement command.
|
// attached to it received a movement command.
|
||||||
bool receivedTarget_;
|
bool receivedTarget_;
|
||||||
|
|
||||||
// If set to true, the virtual axis is about to start a deferred movement
|
// If set to true, the virtual axis is about to start a deferred movement
|
||||||
@ -118,11 +118,12 @@ class detectorTowerAxis : public turboPmacAxis {
|
|||||||
protected:
|
protected:
|
||||||
detectorTowerController *pC_;
|
detectorTowerController *pC_;
|
||||||
int error_;
|
int error_;
|
||||||
auxiliaryAxis *tiltOffsetAxis_;
|
detectorTowerAuxiliaryAxis *tiltZeroCorrAxis_;
|
||||||
auxiliaryAxis *liftOffsetAxis_;
|
detectorTowerAuxiliaryAxis *liftZeroCorrAxis_;
|
||||||
|
double beamRadius_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class auxiliaryAxis;
|
friend class detectorTowerAuxiliaryAxis;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -47,45 +47,73 @@ detectorTowerController::detectorTowerController(
|
|||||||
stringifyAsynStatus(status));
|
stringifyAsynStatus(status));
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = createParam("MOTOR_OFFSET", asynParamFloat64, &motorTargetOffset_);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
|
||||||
|
"parameter failed with %s).\nTerminating IOC",
|
||||||
|
portName, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
stringifyAsynStatus(status));
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus detectorTowerController::readInt32(asynUser *pasynUser,
|
asynStatus detectorTowerController::readInt32(asynUser *pasynUser,
|
||||||
epicsInt32 *value) {
|
epicsInt32 *value) {
|
||||||
|
|
||||||
// Check if the axis is a detectorTowerAxis
|
// The detector tower or its auxiliary axes cannot be disabled
|
||||||
detectorTowerAxis *axis = getDetectorTowerAxis(pasynUser);
|
|
||||||
if (axis == nullptr) {
|
|
||||||
// This is apparently a "normal" turboPmacAxis or an auxiliaryAxis
|
|
||||||
return turboPmacController::readInt32(pasynUser, value);
|
|
||||||
} else {
|
|
||||||
// The detector tower cannot be disabled
|
|
||||||
if (pasynUser->reason == motorCanDisable_) {
|
if (pasynUser->reason == motorCanDisable_) {
|
||||||
|
detectorTowerAxis *dTAxis = getDetectorTowerAxis(pasynUser);
|
||||||
|
if (dTAxis != nullptr) {
|
||||||
*value = 0;
|
*value = 0;
|
||||||
return asynSuccess;
|
return asynSuccess;
|
||||||
} else {
|
}
|
||||||
|
detectorTowerAuxiliaryAxis *dTAAxis =
|
||||||
|
getDetectorTowerAuxiliaryAxis(pasynUser);
|
||||||
|
if (dTAAxis != nullptr) {
|
||||||
|
*value = 0;
|
||||||
|
return asynSuccess;
|
||||||
|
}
|
||||||
|
}
|
||||||
return turboPmacController::readInt32(pasynUser, value);
|
return turboPmacController::readInt32(pasynUser, value);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
asynStatus detectorTowerController::writeInt32(asynUser *pasynUser,
|
asynStatus detectorTowerController::writeInt32(asynUser *pasynUser,
|
||||||
epicsInt32 value) {
|
epicsInt32 value) {
|
||||||
|
|
||||||
|
// =====================================================================
|
||||||
|
|
||||||
|
if (pasynUser->reason == motorCanDisable_) {
|
||||||
|
detectorTowerAxis *dTAxis = getDetectorTowerAxis(pasynUser);
|
||||||
|
if (dTAxis != nullptr) {
|
||||||
|
return dTAxis->toggleWorkingChangerState(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return turboPmacController::writeInt32(pasynUser, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
asynStatus detectorTowerController::writeFloat64(asynUser *pasynUser,
|
||||||
|
epicsFloat64 value) {
|
||||||
int function = pasynUser->reason;
|
int function = pasynUser->reason;
|
||||||
|
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
|
|
||||||
detectorTowerAxis *axis = getDetectorTowerAxis(pasynUser);
|
if (function == motorTargetOffset_) {
|
||||||
|
|
||||||
if (axis == nullptr) {
|
// Write into the parameter library and trigger a movement cycle, if the
|
||||||
// This is apparently a "normal" turboPmacAxis or an auxiliaryAxis
|
// writing succeeded
|
||||||
return turboPmacController::writeInt32(pasynUser, value);
|
asynStatus status = turboPmacController::writeFloat64(pasynUser, value);
|
||||||
} else {
|
if (status == asynSuccess) {
|
||||||
if (function == changeState_) {
|
detectorTowerAxis *dTAxis = getDetectorTowerAxis(pasynUser);
|
||||||
return axis->toggleWorkingChangerState(value);
|
if (dTAxis != nullptr) {
|
||||||
} else {
|
dTAxis->receivedTarget_ = true;
|
||||||
return turboPmacController::writeInt32(pasynUser, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return turboPmacController::writeFloat64(pasynUser, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -108,6 +136,27 @@ detectorTowerAxis *detectorTowerController::getDetectorTowerAxis(int axisNo) {
|
|||||||
return dynamic_cast<detectorTowerAxis *>(asynAxis);
|
return dynamic_cast<detectorTowerAxis *>(asynAxis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Access one of the axes of the controller via the axis adress stored in asynUser.
|
||||||
|
If the axis does not exist or is not a Axis, a nullptr is returned and an
|
||||||
|
error is emitted.
|
||||||
|
*/
|
||||||
|
detectorTowerAuxiliaryAxis *
|
||||||
|
detectorTowerController::getDetectorTowerAuxiliaryAxis(asynUser *pasynUser) {
|
||||||
|
asynMotorAxis *asynAxis = asynMotorController::getAxis(pasynUser);
|
||||||
|
return dynamic_cast<detectorTowerAuxiliaryAxis *>(asynAxis);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Access one of the axes of the controller via the axis index.
|
||||||
|
If the axis does not exist or is not a Axis, the function must return Null
|
||||||
|
*/
|
||||||
|
detectorTowerAuxiliaryAxis *
|
||||||
|
detectorTowerController::getDetectorTowerAuxiliaryAxis(int axisNo) {
|
||||||
|
asynMotorAxis *asynAxis = asynMotorController::getAxis(axisNo);
|
||||||
|
return dynamic_cast<detectorTowerAuxiliaryAxis *>(asynAxis);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************************/
|
/*************************************************************************************/
|
||||||
/** The following functions are C-wrappers, and can be called directly from
|
/** The following functions are C-wrappers, and can be called directly from
|
||||||
* iocsh */
|
* iocsh */
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#ifndef detectorTowerController_H
|
#ifndef detectorTowerController_H
|
||||||
#define detectorTowerController_H
|
#define detectorTowerController_H
|
||||||
#include "auxiliaryAxis.h"
|
#include "detectorTowerAuxiliaryAxis.h"
|
||||||
#include "detectorTowerAxis.h"
|
#include "detectorTowerAxis.h"
|
||||||
#include "turboPmacController.h"
|
#include "turboPmacController.h"
|
||||||
|
|
||||||
@ -52,6 +52,15 @@ class detectorTowerController : public turboPmacController {
|
|||||||
*/
|
*/
|
||||||
asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
|
asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Overloaded function of turboPmacController
|
||||||
|
*
|
||||||
|
* @param pasynUser Specify the axis via the asynUser
|
||||||
|
* @param value New value
|
||||||
|
* @return asynStatus
|
||||||
|
*/
|
||||||
|
asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the axis object
|
* @brief Get the axis object
|
||||||
*
|
*
|
||||||
@ -70,16 +79,37 @@ class detectorTowerController : public turboPmacController {
|
|||||||
*/
|
*/
|
||||||
detectorTowerAxis *getDetectorTowerAxis(int axisNo);
|
detectorTowerAxis *getDetectorTowerAxis(int axisNo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the axis object
|
||||||
|
*
|
||||||
|
* @param pasynUser Specify the axis via the asynUser
|
||||||
|
* @return detectorTowerAuxiliaryAxis* If no axis could be found,
|
||||||
|
* this is a nullptr
|
||||||
|
*/
|
||||||
|
detectorTowerAuxiliaryAxis *
|
||||||
|
getDetectorTowerAuxiliaryAxis(asynUser *pasynUser);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the axis object
|
||||||
|
*
|
||||||
|
* @param axisNo Specify the axis via its index
|
||||||
|
* @return detectorTowerAuxiliaryAxis* If no axis could be found,
|
||||||
|
* this is a nullptr
|
||||||
|
*/
|
||||||
|
detectorTowerAuxiliaryAxis *getDetectorTowerAuxiliaryAxis(int axisNo);
|
||||||
|
|
||||||
// Accessors for additional PVs
|
// Accessors for additional PVs
|
||||||
int positionStateRBV() { return positionStateRBV_; }
|
int positionStateRBV() { return positionStateRBV_; }
|
||||||
int changeState() { return changeState_; }
|
int changeState() { return changeState_; }
|
||||||
|
int motorTargetOffset() { return motorTargetOffset_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Indices of additional PVs
|
// Indices of additional PVs
|
||||||
#define FIRST_detectorTower_PARAM positionStateRBV_
|
#define FIRST_detectorTower_PARAM positionStateRBV_
|
||||||
int positionStateRBV_;
|
int positionStateRBV_;
|
||||||
int changeState_;
|
int changeState_;
|
||||||
#define LAST_detectorTower_PARAM changeState_
|
int motorTargetOffset_;
|
||||||
|
#define LAST_detectorTower_PARAM motorTargetOffset_
|
||||||
};
|
};
|
||||||
#define NUM_detectorTower_DRIVER_PARAMS \
|
#define NUM_detectorTower_DRIVER_PARAMS \
|
||||||
(&LAST_detectorTower_PARAM - &FIRST_detectorTower_PARAM + 1)
|
(&LAST_detectorTower_PARAM - &FIRST_detectorTower_PARAM + 1)
|
||||||
|
Reference in New Issue
Block a user