diff --git a/docs/motorRecord.html b/docs/motorRecord.html
index ec9167e1..0bd14e2b 100644
--- a/docs/motorRecord.html
+++ b/docs/motorRecord.html
@@ -264,6 +264,14 @@ below.
DOUBLE |
acceleration time |
+
+ | ACCS |
+ R/W |
+ Acceleration (EGU/s^2) |
+ DOUBLE |
+
+ |
+
| ADEL |
R/W |
@@ -1713,7 +1721,8 @@ below.
The motor record expects the hardware to produce a trapezoidal
speed profile. That is, the motor speed is expected to increase linearly with
time from the base speed, VBAS, to the full speed, VELO, in ACCL seconds. At the
- end of a motion, the speed is expected to decrease similarly to VBAS. |
+ end of a motion, the speed is expected to decrease similarly to VBAS.
+ Note that the ACCS field can be use to specify the acceleration in EGU/s^2.
| JVEL |
@@ -2377,7 +2386,7 @@ below.
When one of these fields is set to 1, the record will
immediately reset it to 0, and the motor will move (with backlash takeout if
BDST is nonzero) by a distance TWV (in user coordinates) at the acceleration
- specified by ACCL and at speed VELO. |
+ specified by ACCL/ACCS and at speed VELO.
| TWV |
diff --git a/motorApp/MotorSrc/motorRecord.cc b/motorApp/MotorSrc/motorRecord.cc
index e4a106b8..feceda94 100644
--- a/motorApp/MotorSrc/motorRecord.cc
+++ b/motorApp/MotorSrc/motorRecord.cc
@@ -480,6 +480,83 @@ static void callbackFunc(struct callback *pcb)
}
+static double accEGUfromVelo(motorRecord *pmr, double veloEGU)
+{
+ double vmin = pmr->vbas;
+ double vmax = fabs(veloEGU);
+ double acc;
+ /* ACCL or ACCS */
+ if (pmr->accu == motorACCSused_Accs)
+ acc = pmr->accs;
+ else if (vmax > vmin)
+ acc = (vmax - vmin) / pmr->accl;
+ else
+ acc = vmax / pmr->accl;
+
+ return acc;
+}
+
+static void updateACCLfromACCS(motorRecord *pmr)
+{
+ if (pmr->accu != motorACCSused_Accs)
+ {
+ pmr->accu = motorACCSused_Accs;
+ db_post_events(pmr, &pmr->accu, DBE_VAL_LOG);
+ }
+ if (pmr->accs > 0.0)
+ {
+ double temp_dbl = pmr->velo / pmr->accs;
+ if (pmr->accl != temp_dbl)
+ {
+ pmr->accl = temp_dbl;
+ db_post_events(pmr, &pmr->accl, DBE_VAL_LOG);
+ }
+ }
+}
+
+static void updateACCSfromACCL(motorRecord *pmr)
+{
+ double temp_dbl;
+ if (pmr->accu != motorACCSused_Accl)
+ {
+ pmr->accu = motorACCSused_Accl;
+ db_post_events(pmr, &pmr->accu, DBE_VAL_LOG);
+ }
+ temp_dbl = pmr->velo / pmr->accl;
+ if (pmr->accs != temp_dbl)
+ {
+ pmr->accs = temp_dbl;
+ db_post_events(pmr, &pmr->accs, DBE_VAL_LOG);
+ }
+}
+
+static void updateACCL_ACCSfromVELO(motorRecord *pmr)
+{
+ if (pmr->accu == motorACCSused_Accs)
+ {
+ if (pmr->accs > 0.0)
+ {
+ double temp_dbl = pmr->velo / pmr->accs;
+ if (pmr->accl != temp_dbl)
+ {
+ pmr->accl = temp_dbl;
+ db_post_events(pmr, &pmr->accl, DBE_VAL_LOG);
+ }
+ }
+ }
+ else
+ {
+ double temp_dbl = pmr->velo / pmr->accl;
+ if (pmr->accs != temp_dbl)
+ {
+ pmr->accs = temp_dbl;
+ db_post_events(pmr, &pmr->accs, DBE_VAL_LOG);
+ }
+ }
+}
+
+
+
/******************************************************************************
enforceMinRetryDeadband()
@@ -864,7 +941,7 @@ static long postProcess(motorRecord * pmr)
if (pmr->mip & MIP_JOG_STOP)
{
- double acc = (vel - vbase) > 0 ? ((vel - vbase)/ pmr->accl) : (vel / pmr->accl);
+ double acc = accEGUfromVelo(pmr, pmr->velo);
if (vel <= vbase)
vel = vbase + 1;
@@ -2195,7 +2272,7 @@ static RTN_STATUS do_work(motorRecord * pmr, CALLBACK_VALUE proc_ind)
double newpos = pmr->dval / pmr->mres; /* where to go */
double vbase = pmr->vbas / fabs(pmr->mres); /* base speed */
double vel = pmr->velo / fabs(pmr->mres); /* normal speed */
- double acc = (vel - vbase) > 0 ? ((vel - vbase) / pmr->accl) : (vel / pmr->accl); /* normal accel. */
+ double acc = accEGUfromVelo(pmr, pmr->velo);
/*
* 'bpos' is one backlash distance away from 'newpos'.
*/
@@ -2612,6 +2689,7 @@ static long special(DBADDR *paddr, int after)
/* new velo: make s agree */
case motorRecordVELO:
range_check(pmr, &pmr->velo, pmr->vbas, pmr->vmax);
+ updateACCL_ACCSfromVELO(pmr);
if ((pmr->urev != 0.0) && (pmr->s != (temp_dbl = pmr->velo / fabs_urev)))
{
@@ -2629,6 +2707,7 @@ static long special(DBADDR *paddr, int after)
pmr->velo = temp_dbl;
db_post_events(pmr, &pmr->velo, DBE_VAL_LOG);
}
+ updateACCL_ACCSfromVELO(pmr);
break;
/* new bvel: make sbak agree */
@@ -2660,6 +2739,13 @@ static long special(DBADDR *paddr, int after)
pmr->accl = 0.1;
db_post_events(pmr, &pmr->accl, DBE_VAL_LOG);
}
+ updateACCSfromACCL(pmr);
+ break;
+
+ /* new accs */
+ case motorRecordACCS:
+ db_post_events(pmr, &pmr->accs, DBE_VAL_LOG);
+ updateACCLfromACCS(pmr);
break;
/* new bacc */
@@ -3898,6 +3984,14 @@ static void check_speed_and_resolution(motorRecord * pmr)
db_post_events(pmr, &pmr->sbak, DBE_VAL_LOG);
db_post_events(pmr, &pmr->bvel, DBE_VAL_LOG);
+ if (pmr->accs && !pmr->accl)
+ {
+ /* ACCL == 0.0, ACCS is != 0.0 -> Use ACCS
+ This is a (possible) new way to configure a database.
+ Existing Db files will have ACCS == 0.0 and this
+ is backwards compatibleamd behaves as before */
+ updateACCLfromACCS(pmr);
+ }
/* Sanity check on acceleration time. */
if (pmr->accl == 0.0)
{
@@ -3923,6 +4017,11 @@ static void check_speed_and_resolution(motorRecord * pmr)
pmr->hvel = pmr->vbas;
else
range_check(pmr, &pmr->hvel, pmr->vbas, pmr->vmax);
+ /* Make sure that ACCS/ACCU are initialized */
+ if (pmr->accu == motorACCSused_Undef)
+ {
+ updateACCSfromACCL(pmr);
+ }
}
/*
diff --git a/motorApp/MotorSrc/motorRecord.dbd b/motorApp/MotorSrc/motorRecord.dbd
index e524f36e..4877b2cd 100644
--- a/motorApp/MotorSrc/motorRecord.dbd
+++ b/motorApp/MotorSrc/motorRecord.dbd
@@ -68,12 +68,15 @@ menu(motorRMOD) {
choice(motorRMOD_G,"Geometric")
choice(motorRMOD_I,"In-Position")
}
-
menu(motorRSTM) {
choice(motorRSTM_Never, "Never")
choice(motorRSTM_Always, "Always")
choice(motorRSTM_NearZero, "NearZero")
choice(motorRSTM_Conditional, "Conditional")
+menu(motorACCSused) {
+ choice(motorACCSused_Undef,"Undef")
+ choice(motorACCSused_Accl, "Accl")
+ choice(motorACCSused_Accs, "Accs")
}
include "menuOmsl.dbd"
@@ -180,6 +183,17 @@ recordtype(motor) {
interest(1)
initial("0.2")
}
+ field(ACCS,DBF_DOUBLE) {
+ prompt("Move Accel. (EGU/s^2)")
+ promptgroup(GUI_COMMON)
+ special(SPC_MOD)
+ interest(1)
+ }
+ field(ACCU,DBF_MENU) {
+ prompt("ACCS used")
+ special(SPC_NOMOD)
+ menu(motorACCSused)
+ }
field(BDST,DBF_DOUBLE) {
prompt("BL Distance (EGU)")
asl(ASL0)