From 2e89b55279d849a511b3d678520fefb0f98b6a28 Mon Sep 17 00:00:00 2001 From: Jack Harper Date: Mon, 21 Nov 2022 13:03:46 +0000 Subject: [PATCH 1/3] Add raw limits so that soft limits are synced with motor resolution change --- motorApp/MotorSrc/motorRecord.cc | 313 ++++++++++++++++++++---------- motorApp/MotorSrc/motorRecord.dbd | 12 ++ 2 files changed, 224 insertions(+), 101 deletions(-) diff --git a/motorApp/MotorSrc/motorRecord.cc b/motorApp/MotorSrc/motorRecord.cc index bcf629dad..e7b264203 100644 --- a/motorApp/MotorSrc/motorRecord.cc +++ b/motorApp/MotorSrc/motorRecord.cc @@ -234,6 +234,8 @@ static void monitor(motorRecord *); static void process_motor_info(motorRecord *, bool); static void load_pos(motorRecord *); static void check_speed_and_resolution(motorRecord *); +static void set_user_highlimit(motorRecord*, struct motor_dset*); +static void set_user_lowlimit(motorRecord*, struct motor_dset*); static void set_dial_highlimit(motorRecord *, struct motor_dset *); static void set_dial_lowlimit(motorRecord *, struct motor_dset *); static void set_userlimits(motorRecord *); @@ -383,6 +385,8 @@ typedef union unsigned int M_JOGR :1; unsigned int M_HOMF :1; unsigned int M_HOMR :1; + unsigned int M_RHLM :1; + unsigned int M_RLLM :1; } Bits; } nmap_field; @@ -2495,7 +2499,7 @@ static long special(DBADDR *paddr, int after) int dir = dir_positive ? 1 : -1; bool changed = false; int fieldIndex = dbGetFieldIndex(paddr); - double offset, tmp_raw, tmp_limit, fabs_urev; + double fabs_urev; RTN_STATUS rtnval; motor_cmnd command; double temp_dbl; @@ -2700,110 +2704,12 @@ static long special(DBADDR *paddr, int after) /* new user high limit */ case motorRecordHLM: - offset = pmr->off; - if (dir_positive) - { - tmp_limit = pmr->hlm - offset; - MARK(M_DHLM); - } - else - { - tmp_limit = -(pmr->hlm) + offset; - MARK(M_DLLM); - } - - /* Which controller limit we set depends not only on dir, but - also on the sign of MRES */ - /* Direction +ve AND +ve MRES OR - Direction -ve AND -ve MRES */ - if (dir_positive ^ (pmr->mres < 0)) - { - command = SET_HIGH_LIMIT; - } - else - /* Direction -ve AND +ve MRES OR - Direction +ve AND -ve MRES */ - { - command = SET_LOW_LIMIT; - } - - tmp_raw = tmp_limit / pmr->mres; - - INIT_MSG(); - rtnval = (*pdset->build_trans)(command, &tmp_raw, pmr); - if (rtnval != OK) - { - /* If an error occured, build_trans() has reset - * dial high or low limit to controller's value. */ - - if (dir_positive) - pmr->hlm = pmr->dhlm + offset; - else - pmr->hlm = -(pmr->dllm) + offset; - } - else - { - SEND_MSG(); - if (dir_positive) - pmr->dhlm = tmp_limit; - else - pmr->dllm = tmp_limit; - } - MARK(M_HLM); + set_user_highlimit(pmr, pdset); break; /* new user low limit */ case motorRecordLLM: - offset = pmr->off; - if (dir_positive) - { - tmp_limit = pmr->llm - offset; - MARK(M_DLLM); - } - else - { - tmp_limit = -(pmr->llm) + offset; - MARK(M_DHLM); - } - - /* Which controller limit we set depends not only on dir, but - also on the sign of MRES */ - /* Direction +ve AND +ve MRES OR - Direction -ve AND -ve MRES */ - if (dir_positive ^ (pmr->mres < 0)) - { - command = SET_LOW_LIMIT; - } - else - /* Direction -ve AND +ve MRES OR - Direction +ve AND -ve MRES */ - { - command = SET_HIGH_LIMIT; - } - - tmp_raw = tmp_limit / pmr->mres; - - INIT_MSG(); - rtnval = (*pdset->build_trans)(command, &tmp_raw, pmr); - if (rtnval != OK) - { - /* If an error occured, build_trans() has reset - * dial high or low limit to controller's value. */ - - if (dir_positive) - pmr->llm = pmr->dllm + offset; - else - pmr->llm = -(pmr->dhlm) + offset; - } - else - { - SEND_MSG(); - if (dir_positive) - pmr->dllm = tmp_limit; - else - pmr->dhlm = tmp_limit; - } - MARK(M_LLM); + set_user_lowlimit(pmr, pdset); break; /* new dial high limit */ @@ -2877,6 +2783,19 @@ static long special(DBADDR *paddr, int after) pmr->vmax = temp_dbl; db_post_events(pmr, &pmr->vmax, DBE_VAL_LOG); } + if (pmr->dllm != (temp_dbl = pmr->rllm * pmr->mres)) + { + pmr->dllm = temp_dbl; + db_post_events(pmr, &pmr->dllm, DBE_VAL_LOG); + } + if (pmr->dhlm != (temp_dbl = pmr->rhlm * pmr->mres)) + { + pmr->dhlm = temp_dbl; + db_post_events(pmr, &pmr->dhlm, DBE_VAL_LOG); + } + set_userlimits(pmr); + db_post_events(pmr, &pmr->hlm, DBE_VAL_LOG); + db_post_events(pmr, &pmr->llm, DBE_VAL_LOG); break; /* new srev: make mres agree */ @@ -3828,6 +3747,20 @@ static void load_pos(motorRecord * pmr) * Range check; VBAS < VELO < VMAX. * S < - VELO / |UREV|. * ENDIF + * + * IF RLLM is nonzero. + * DLLM < - RLLM * MRES. + * ENDIF + * IF RLLM is not DLLM / MRES. + * RLLM < - DLLM / MRES. + * ENDIF + * + * IF RHLM is nonzero. + * DHLM < - RHLM * MRES. + * ENDIF + * IF RHLM is not DHLM / MRES. + * RHLM < - DHLM / MRES. + * ENDIF * * IF SBAK is nonzero. * Range check; SBAS < SBAK < SMAX. @@ -3917,6 +3850,35 @@ static void check_speed_and_resolution(motorRecord * pmr) db_post_events(pmr, &pmr->velo, DBE_VAL_LOG); db_post_events(pmr, &pmr->s, DBE_VAL_LOG); + /* RLLM <--> DLLM */ + if (pmr->rllm != 0.0) + { + pmr->dllm = pmr->rllm * pmr->mres; + MARK(M_DLLM); + } + if (pmr->rllm != pmr->dllm / pmr->mres) + { + pmr->rllm = pmr->dllm / pmr->mres; + MARK_AUX(M_RLLM); + } + db_post_events(pmr, &pmr->dllm, DBE_VAL_LOG); + db_post_events(pmr, &pmr->rllm, DBE_VAL_LOG); + + + /* RHLM <--> DHLM */ + if (pmr->rhlm != 0.0) + { + pmr->dhlm = pmr->rhlm * pmr->mres; + MARK(M_DHLM); + } + if (pmr->rhlm != pmr->dhlm / pmr->mres) + { + pmr->rhlm = pmr->dhlm / pmr->mres; + MARK_AUX(M_RHLM); + } + db_post_events(pmr, &pmr->rhlm, DBE_VAL_LOG); + db_post_events(pmr, &pmr->dhlm, DBE_VAL_LOG); + /* SBAK (revolutions/sec) <--> BVEL (EGU/sec) */ if (pmr->sbak != 0.0) { @@ -3958,6 +3920,149 @@ static void check_speed_and_resolution(motorRecord * pmr) range_check(pmr, &pmr->hvel, pmr->vbas, pmr->vmax); } +/* +FUNCTION... void set_user_highlimit(motorRecord *) +USAGE... Set user high limit. +NOTES... This function sends a command to the device to set the user high +limit. This is respective to the direction of the motor. +*/ +static void set_user_highlimit(motorRecord* pmr, struct motor_dset* pdset) +{ + int dir_positive = (pmr->dir == motorDIR_Pos); + double tmp_limit, offset, tmp_raw; + motor_cmnd command; + RTN_STATUS rtnval; + offset = pmr->off; + if (dir_positive) + { + tmp_limit = pmr->hlm - offset; + MARK(M_DHLM); + } + else + { + tmp_limit = -(pmr->hlm) + offset; + MARK(M_DLLM); + } + + /* Which controller limit we set depends not only on dir, but + also on the sign of MRES */ + /* Direction +ve AND +ve MRES OR + Direction -ve AND -ve MRES */ + if (dir_positive ^ (pmr->mres < 0)) + { + command = SET_HIGH_LIMIT; + } + else + /* Direction -ve AND +ve MRES OR + Direction +ve AND -ve MRES */ + { + command = SET_LOW_LIMIT; + } + + tmp_raw = tmp_limit / pmr->mres; + + INIT_MSG(); + rtnval = (*pdset->build_trans)(command, &tmp_raw, pmr); + if (rtnval != OK) + { + /* If an error occured, build_trans() has reset + * dial high or low limit to controller's value. */ + + if (dir_positive) + pmr->hlm = pmr->dhlm + offset; + else + pmr->hlm = -(pmr->dllm) + offset; + } + else + { + // set dial and raw limits + SEND_MSG(); + if (dir_positive) + { + pmr->dhlm = tmp_limit; + pmr->rhlm = tmp_raw; + } + else + { + pmr->dllm = tmp_limit; + pmr->rllm = tmp_limit; + } + } + MARK(M_HLM); +} + +/* +FUNCTION... void set_user_lowlimit(motorRecord *) +USAGE... Set user low limit. +NOTES... This function sends a command to the device to set the user low +limit. This is respective to the direction of the motor. +*/ +static void set_user_lowlimit(motorRecord* pmr, struct motor_dset* pdset) +{ + int dir_positive = (pmr->dir == motorDIR_Pos); + double tmp_limit, offset, tmp_raw; + motor_cmnd command; + RTN_STATUS rtnval; + offset = pmr->off; + if (dir_positive) + { + tmp_limit = pmr->llm - offset; + MARK(M_DLLM); + } + else + { + tmp_limit = -(pmr->llm) + offset; + MARK(M_DHLM); + } + + /* Which controller limit we set depends not only on dir, but + also on the sign of MRES */ + /* Direction +ve AND +ve MRES OR + Direction -ve AND -ve MRES */ + if (dir_positive ^ (pmr->mres < 0)) + { + command = SET_LOW_LIMIT; + } + else + /* Direction -ve AND +ve MRES OR + Direction +ve AND -ve MRES */ + { + command = SET_HIGH_LIMIT; + } + + tmp_raw = tmp_limit / pmr->mres; + + INIT_MSG(); + rtnval = (*pdset->build_trans)(command, &tmp_raw, pmr); + if (rtnval != OK) + { + /* If an error occured, build_trans() has reset + * dial high or low limit to controller's value. */ + + if (dir_positive) + pmr->llm = pmr->dllm + offset; + else + pmr->llm = -(pmr->dhlm) + offset; + } + else + { + // set dial and raw limits + SEND_MSG(); + if (dir_positive) { + pmr->dllm = tmp_limit; + pmr->rllm = tmp_raw; + } + else + { + pmr->dhlm = tmp_limit; + pmr->rhlm = tmp_raw; + } + + } + MARK(M_LLM); +} + + /* FUNCTION... void set_dial_highlimit(motorRecord *) USAGE... Set dial-coordinate high limit. @@ -3974,6 +4079,9 @@ static void set_dial_highlimit(motorRecord *pmr, struct motor_dset *pdset) RTN_STATUS rtnval; tmp_raw = pmr->dhlm / pmr->mres; + // set the raw high limit + pmr->rhlm = tmp_raw; + INIT_MSG(); if (pmr->mres < 0) { command = SET_LOW_LIMIT; @@ -4014,6 +4122,9 @@ static void set_dial_lowlimit(motorRecord *pmr, struct motor_dset *pdset) RTN_STATUS rtnval; tmp_raw = pmr->dllm / pmr->mres; + // set the raw low limit + pmr->rllm = tmp_raw; + INIT_MSG(); if (pmr->mres < 0) { diff --git a/motorApp/MotorSrc/motorRecord.dbd b/motorApp/MotorSrc/motorRecord.dbd index 05fd99b6a..e524f36e8 100644 --- a/motorApp/MotorSrc/motorRecord.dbd +++ b/motorApp/MotorSrc/motorRecord.dbd @@ -309,6 +309,18 @@ recordtype(motor) { interest(1) size(16) } + field(RHLM,DBF_DOUBLE) { + prompt("Raw High Limit") + promptgroup(GUI_COMMON) + special(SPC_NOMOD) + interest(1) + } + field(RLLM,DBF_DOUBLE) { + prompt("Raw Low Limit") + promptgroup(GUI_COMMON) + special(SPC_NOMOD) + interest(1) + } field(HLM,DBF_DOUBLE) { prompt("User High Limit") special(SPC_MOD) From 141d8aa430a0099b988a31cc602e9e5596f1f6d4 Mon Sep 17 00:00:00 2001 From: Jack Harper Date: Mon, 21 Nov 2022 13:10:40 +0000 Subject: [PATCH 2/3] add to changelog --- motorApp/MotorSrc/motorRecord.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/motorApp/MotorSrc/motorRecord.cc b/motorApp/MotorSrc/motorRecord.cc index e7b264203..776589931 100644 --- a/motorApp/MotorSrc/motorRecord.cc +++ b/motorApp/MotorSrc/motorRecord.cc @@ -190,6 +190,7 @@ USAGE... Motor Record Support. * .76 04-04-18 rls - If URIP is Yes and RDBL is inaccessible (e.g., CA server is down), do not start * a new target position move (sans Home search or Jog). * .78 08-21-18 kmp - Reverted .69 stop on RA_PROBLEM true. + * .79 21-11-22 jrh - Added raw limits, sync limits on motor resolution change */ #define VERSION 7.2 From 99d0c414157a9dcfcfc90cc196d8155df477ce12 Mon Sep 17 00:00:00 2001 From: Kevin Peterson Date: Fri, 12 May 2023 14:15:40 -0500 Subject: [PATCH 3/3] Fix for CA clients not seeing updates to RHLM and RLLM --- motorApp/MotorSrc/motorRecord.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/motorApp/MotorSrc/motorRecord.cc b/motorApp/MotorSrc/motorRecord.cc index 776589931..e4a106b8a 100644 --- a/motorApp/MotorSrc/motorRecord.cc +++ b/motorApp/MotorSrc/motorRecord.cc @@ -3527,6 +3527,10 @@ static void monitor(motorRecord * pmr) db_post_events(pmr, &pmr->homf, local_mask); if ((local_mask = monitor_mask | (MARKED_AUX(M_HOMR) ? DBE_VAL_LOG : 0))) db_post_events(pmr, &pmr->homr, local_mask); + if ((local_mask = monitor_mask | (MARKED_AUX(M_RHLM) ? DBE_VAL_LOG : 0))) + db_post_events(pmr, &pmr->rhlm, local_mask); + if ((local_mask = monitor_mask | (MARKED_AUX(M_RLLM) ? DBE_VAL_LOG : 0))) + db_post_events(pmr, &pmr->rllm, local_mask); UNMARK_ALL; } @@ -3982,11 +3986,13 @@ static void set_user_highlimit(motorRecord* pmr, struct motor_dset* pdset) { pmr->dhlm = tmp_limit; pmr->rhlm = tmp_raw; + MARK_AUX(M_RHLM); } else { pmr->dllm = tmp_limit; - pmr->rllm = tmp_limit; + pmr->rllm = tmp_raw; + MARK_AUX(M_RLLM); } } MARK(M_HLM); @@ -4052,11 +4058,13 @@ static void set_user_lowlimit(motorRecord* pmr, struct motor_dset* pdset) if (dir_positive) { pmr->dllm = tmp_limit; pmr->rllm = tmp_raw; + MARK_AUX(M_RLLM); } else { pmr->dhlm = tmp_limit; pmr->rhlm = tmp_raw; + MARK_AUX(M_RHLM); } } @@ -4082,6 +4090,7 @@ static void set_dial_highlimit(motorRecord *pmr, struct motor_dset *pdset) tmp_raw = pmr->dhlm / pmr->mres; // set the raw high limit pmr->rhlm = tmp_raw; + MARK_AUX(M_RHLM); INIT_MSG(); if (pmr->mres < 0) { @@ -4125,7 +4134,7 @@ static void set_dial_lowlimit(motorRecord *pmr, struct motor_dset *pdset) tmp_raw = pmr->dllm / pmr->mres; // set the raw low limit pmr->rllm = tmp_raw; - + MARK_AUX(M_RLLM); INIT_MSG(); if (pmr->mres < 0) {