diff --git a/docs/motorRecord.html b/docs/motorRecord.html
index ae433e0e..443f7fda 100644
--- a/docs/motorRecord.html
+++ b/docs/motorRecord.html
@@ -889,6 +889,14 @@ below.
|
+
+ | RSTM |
+ R/W |
+ Restory Mode |
+ RECCHOICE |
+ (0:"Never", 1:"Always", 2:"NearZero", 3:"Conditional")
+ |
+
| SPDB |
R/W |
diff --git a/motorApp/MotorSrc/devMotorAsyn.c b/motorApp/MotorSrc/devMotorAsyn.c
index c09834e9..aa02f9e2 100644
--- a/motorApp/MotorSrc/devMotorAsyn.c
+++ b/motorApp/MotorSrc/devMotorAsyn.c
@@ -172,28 +172,53 @@ static void init_controller(struct motorRecord *pmr, asynUser *pasynUser )
double rdbd = (fabs(pmr->rdbd) < fabs(pmr->mres) ? fabs(pmr->mres) : fabs(pmr->rdbd) );
double encRatio[2] = {pmr->mres, pmr->eres};
int use_rel = (pmr->rtry != 0 && pmr->rmod != motorRMOD_I && (pmr->ueip || pmr->urip));
+ int dval_non_zero_pos_near_zero = (fabs(pmr->dval) > rdbd) &&
+ (pmr->mres != 0) && (fabs(position * pmr->mres) < rdbd);
+ int initPos = 0;
/*Before setting position, set the correct encoder ratio.*/
start_trans(pmr);
build_trans(SET_ENC_RATIO, encRatio, pmr);
end_trans(pmr);
- if ((use_rel != 0) ||
- ((fabs(pmr->dval) > rdbd) && (pmr->mres != 0) && (fabs(position * pmr->mres) < rdbd))
- )
+ switch (pmr->rstm) {
+ case motorRSTM_NearZero:
+ {
+ if (dval_non_zero_pos_near_zero)
+ initPos = 1;
+
+ }
+ break;
+ case motorRSTM_Conditional:
+ {
+ if (use_rel || dval_non_zero_pos_near_zero)
+ initPos = 1;
+ }
+ break;
+ case motorRSTM_Always:
+ initPos = 1;
+ break;
+ }
+ if (initPos)
{
double setPos = pmr->dval / pmr->mres;
epicsEventId initEvent = epicsEventCreate( epicsEventEmpty );
+ RTN_STATUS rtnval;
pPvt->initEvent = initEvent;
start_trans(pmr);
- build_trans(LOAD_POS, &setPos, pmr);
+ rtnval = build_trans(LOAD_POS, &setPos, pmr);
end_trans(pmr);
-
- asynPrint(pasynUser, ASYN_TRACE_FLOW,
- "devMotorAsyn::init_controller, %s set position to %f\n",
- pmr->name, setPos );
+ if (rtnval != OK) {
+ asynPrint(pasynUser, ASYN_TRACE_ERROR,
+ "devMotorAsyn::init_controller, %s failed to set position to %f\n",
+ pmr->name, setPos );
+ } else {
+ asynPrint(pasynUser, ASYN_TRACE_FLOW,
+ "devMotorAsyn::init_controller, %s set position to %f\n",
+ pmr->name, setPos );
+ }
if ( initEvent )
{
diff --git a/motorApp/MotorSrc/motorRecord.dbd b/motorApp/MotorSrc/motorRecord.dbd
index 0e2d11c6..05fd99b6 100644
--- a/motorApp/MotorSrc/motorRecord.dbd
+++ b/motorApp/MotorSrc/motorRecord.dbd
@@ -69,6 +69,13 @@ menu(motorRMOD) {
choice(motorRMOD_I,"In-Position")
}
+menu(motorRSTM) {
+ choice(motorRSTM_Never, "Never")
+ choice(motorRSTM_Always, "Always")
+ choice(motorRSTM_NearZero, "NearZero")
+ choice(motorRSTM_Conditional, "Conditional")
+}
+
include "menuOmsl.dbd"
recordtype(motor) {
@@ -798,4 +805,11 @@ recordtype(motor) {
prompt("Ignore SET field")
interest(2)
}
+ field(RSTM,DBF_MENU) {
+ initial("NearZero")
+ prompt("Restore Mode")
+ promptgroup(GUI_COMMON)
+ interest(2)
+ menu(motorRSTM)
+ }
}
diff --git a/motorApp/MotorSrc/motordevCom.cc b/motorApp/MotorSrc/motordevCom.cc
index b82bc8fa..fb4c8d8b 100644
--- a/motorApp/MotorSrc/motordevCom.cc
+++ b/motorApp/MotorSrc/motordevCom.cc
@@ -152,9 +152,7 @@ LOGIC...
Set local encoder ratio to unity.
ENDIF
- Set Initialize position indicator based on (Use Relative Moves indicator == TRUE, OR,
- [|DVAL| > RDBD, AND, MRES != 0, AND, the above |"get_axis_info()" position| < RDBD)]
- [NOTE: |controller position| >= RDBD takes precedence over save/restore position].
+ Set Initialize position indicator based on the RSTM field
Set Command Primitive Initialization string indicator based on (non-NULL "init"
pointer, AND, non-zero string length.
@@ -189,7 +187,7 @@ motor_init_record_com(struct motorRecord *mr, int brdcnt, struct driver_table *t
struct motor_dset *pdset = (struct motor_dset *) (mr->dset);
struct board_stat *brdptr;
int card, signal;
- bool initEncoder, initPos, initString, initPID;
+ bool initEncoder, initPos = false, initString, initPID;
struct motor_trans *ptrans;
MOTOR_AXIS_QUERY axis_query;
struct mess_node *motor_call;
@@ -210,7 +208,7 @@ motor_init_record_com(struct motorRecord *mr, int brdcnt, struct driver_table *t
/* Semaphore on private to record field data transfers */
ptrans->lock = new epicsEvent(epicsEventFull);
-
+
motor_call = &(ptrans->motor_call);
callbackSetCallback((void (*)(struct callbackPvt *)) motor_callback,
@@ -288,9 +286,26 @@ motor_init_record_com(struct motorRecord *mr, int brdcnt, struct driver_table *t
else
ep_mp[0] = ep_mp[1] = 1.0;
- initPos = ((use_rel == true) ||
- (fabs(mr->dval) > mr->rdbd && mr->mres != 0 && fabs(axis_query.position * mr->mres) < mr->rdbd)
- ) ? true : false;
+ bool dval_non_zero_pos_near_zero = fabs(mr->dval) > mr->rdbd && mr->mres != 0 &&
+ fabs(axis_query.position * mr->mres) < mr->rdbd;
+ switch (mr->rstm) {
+ case motorRSTM_NearZero:
+ {
+ if (dval_non_zero_pos_near_zero)
+ initPos = 1;
+ }
+ break;
+ case motorRSTM_Conditional:
+ {
+ if (dval_non_zero_pos_near_zero || use_rel)
+ initPos = true;
+ }
+ break;
+ case motorRSTM_Always:
+ initPos = true;
+ break;
+ }
+
/* Test for command primitive initialization string. */
initString = (mr->init != NULL && strlen(mr->init)) ? true : false;
/* Test for PID support. */