Prototype for version 0.3
This commit is contained in:
@ -393,54 +393,6 @@ asynStatus sinqAxis::startMovTimeoutWatchdog() {
|
||||
watchdogMovActive_ = true;
|
||||
|
||||
/*
|
||||
The motor record resolution (index motorRecResolution_ in the parameter
|
||||
library, MRES in the motor record) is NOT a conversion factor between
|
||||
user units (e.g. mm) and motor units (e.g. encoder steps), but a scaling
|
||||
factor defining the resolution of the position readback field RRBV. This
|
||||
is due to an implementation detail inside EPICS described here:
|
||||
https://epics.anl.gov/tech-talk/2018/msg00089.php
|
||||
https://github.com/epics-modules/motor/issues/8
|
||||
|
||||
Basically, the position value in the parameter library is a double which
|
||||
is then truncated to an integer in devMotorAsyn.c (because it was
|
||||
originally meant for converting from engineering units to encoder steps,
|
||||
which are by definition integer values). Therefore, if we want a
|
||||
precision of 1 millimeter, we need to set MRES to 1. If we want one of
|
||||
1 micrometer, we need to set MRES to 0.001. The readback value needs to
|
||||
be multiplied with MRES to get the actual value.
|
||||
|
||||
In the driver, we use user units. Therefore, when we interact with the
|
||||
parameter library, we need to account for MRES. This means:
|
||||
- When writing position or speed to the parameter library, we divide the
|
||||
value by the motor record resolution.
|
||||
- When reading position or speed from the parameter library, we multiply
|
||||
the value with the motor record resolution.
|
||||
|
||||
Index and motor record field are coupled as follows:
|
||||
The parameter motorRecResolution_ is coupled to the field MRES of the
|
||||
motor record in the following manner:
|
||||
- In sinqMotor.db, the PV (motor_record_pv_name) MOTOR_REC_RESOLUTION
|
||||
is defined as a copy of the field (motor_record_pv_name).MRES:
|
||||
|
||||
record(ao,"$(P)$(M):Resolution") {
|
||||
field(DESC, "$(M) resolution")
|
||||
field(DOL, "$(P)$(M).MRES CP MS")
|
||||
field(OMSL, "closed_loop")
|
||||
field(DTYP, "asynFloat64")
|
||||
field(OUT, "@asyn($(PORT),$(ADDR))MOTOR_REC_RESOLUTION")
|
||||
field(PREC, "$(PREC)")
|
||||
}
|
||||
|
||||
- The PV name MOTOR_REC_RESOLUTION is coupled in asynMotorController.h
|
||||
to the constant motorRecResolutionString
|
||||
- ... which in turn is assigned to motorRecResolution_ in
|
||||
asynMotorController.cpp This way of making the field visible to the
|
||||
driver is described here:
|
||||
https://epics.anl.gov/tech-talk/2020/msg00378.php This is a one-way
|
||||
coupling, changes to the parameter library via setDoubleParam are NOT
|
||||
transferred to (motor_record_pv_name).MRES or to
|
||||
(motor_record_pv_name):Resolution.
|
||||
|
||||
NOTE: This function must not be called in the constructor (e.g. in order
|
||||
to save the read result to the member variable earlier), since the
|
||||
parameter library is updated at a later stage!
|
||||
|
@ -251,7 +251,7 @@ asynStatus sinqController::readInt32(asynUser *pasynUser, epicsInt32 *value) {
|
||||
return asynSuccess;
|
||||
} else if (pasynUser->reason == motorCanDisable_) {
|
||||
// By default, motors cannot be disabled
|
||||
*value = 0;
|
||||
*value = 1;
|
||||
return asynSuccess;
|
||||
} else {
|
||||
return asynMotorController::readInt32(pasynUser, value);
|
||||
|
@ -67,7 +67,7 @@ class epicsShareClass sinqController : public asynMotorController {
|
||||
* @param value Read-out value
|
||||
* @return asynStatus
|
||||
*/
|
||||
virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
|
||||
asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
|
||||
|
||||
/**
|
||||
* @brief Error handling in case accessing the parameter library failed.
|
||||
|
Reference in New Issue
Block a user