diff --git a/docs/motorRecord.html b/docs/motorRecord.html
index df4721b9..e0902527 100644
--- a/docs/motorRecord.html
+++ b/docs/motorRecord.html
@@ -242,6 +242,14 @@ below.
DOUBLE |
acceleration time |
+
+ | ACCS |
+ R/W |
+ Acceleration (EGU/s^2) |
+ DOUBLE |
+
+ |
+
| ADEL |
R/W |
@@ -1675,7 +1683,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 |
@@ -2329,7 +2338,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 0129b879..4ddbeba4 100644
--- a/motorApp/MotorSrc/motorRecord.cc
+++ b/motorApp/MotorSrc/motorRecord.cc
@@ -475,6 +475,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()
@@ -859,7 +936,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;
@@ -2190,7 +2267,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'.
*/
@@ -2595,6 +2672,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)))
{
@@ -2612,6 +2690,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 */
@@ -2643,6 +2722,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 */
diff --git a/motorApp/MotorSrc/motorRecord.dbd b/motorApp/MotorSrc/motorRecord.dbd
index aa455cba..64c7bd13 100644
--- a/motorApp/MotorSrc/motorRecord.dbd
+++ b/motorApp/MotorSrc/motorRecord.dbd
@@ -69,6 +69,11 @@ menu(motorRMOD) {
choice(motorRMOD_I,"In-Position")
}
+menu(motorACCSused) {
+ choice(motorACCSused_Accl, "Accl")
+ choice(motorACCSused_Accs, "Accs")
+}
+
include "menuOmsl.dbd"
recordtype(motor) {
@@ -173,6 +178,18 @@ 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) {
+ initial("Default")
+ prompt("ACCS used")
+ special(SPC_NOMOD)
+ menu(motorACCSused)
+ }
field(BDST,DBF_DOUBLE) {
prompt("BL Distance (EGU)")
asl(ASL0)