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)