From 016ebe5f4f7dd0f5d9da6721159fa310837a854b Mon Sep 17 00:00:00 2001 From: Freddie Akeroyd Date: Wed, 19 Aug 2026 11:28:16 +0100 Subject: [PATCH] Fix homing and some undefined parameter exceptions --- GalilSup/Db/galil_homing_routines.template | 16 ++--- GalilSup/src/GalilAxis.cpp | 15 ++-- GalilSup/src/GalilAxis.h | 1 - GalilSup/src/GalilController.cpp | 84 +++++++++------------- GalilSup/src/GalilController.h | 18 +---- 5 files changed, 48 insertions(+), 86 deletions(-) diff --git a/GalilSup/Db/galil_homing_routines.template b/GalilSup/Db/galil_homing_routines.template index 93ddfc7c..620719ae 100644 --- a/GalilSup/Db/galil_homing_routines.template +++ b/GalilSup/Db/galil_homing_routines.template @@ -1,22 +1,14 @@ # P - PV prefix # M - CSMotor Name # PORT - Asyn port name -# ADDR - CS motor (8-15) -# C - Axis Character +# ADDR - Asyn addr for axis #Homing routine names -record(stringout,"$(P)$(M)_HMRNAM:SP") -{ - field(DESC, "$(M) Homing routine axis $(C)") - field(PINI, "YES") - field(DTYP, "asynOctetWrite") - field(OUT, "@asyn($(PORT),$(ADDR))HMRNAM_$(C)") - field(FLNK, "$(P)$(M)_HMRNAM") -} record(stringin,"$(P)$(M)_HMRNAM") { - field(DESC, "$(M) Homing routine axis $(C)") + field(DESC, "$(M) Homing routine") field(DTYP, "asynOctetRead") - field(INP, "@asyn($(PORT),$(ADDR))HMRNAM_$(C)") + field(INP, "@asyn($(PORT),$(ADDR))HMRNAM") + field(SCAN, "I/O Intr") } diff --git a/GalilSup/src/GalilAxis.cpp b/GalilSup/src/GalilAxis.cpp index 3d5f3313..4758be5d 100644 --- a/GalilSup/src/GalilAxis.cpp +++ b/GalilSup/src/GalilAxis.cpp @@ -225,8 +225,6 @@ asynStatus GalilAxis::setDefaults(char *enables_string, int switch_type) //Default event timeout requestedTimeout_ = BEGIN_TIMEOUT * multiplier; - homingRoutineName = ""; - //Store switch type setting for motor enable/disable function switch_type_ = (switch_type > 0) ? 1 : 0; @@ -1861,17 +1859,18 @@ asynStatus GalilAxis::getStatus(void) strcpy(src, "_TEx"); src[3] = axisName_; error_ = pC_->sourceValue(pC_->recdata_, src); - pC_->getDoubleParam(axisNo_, pC_->GalilError_, &errorlast); - if (error_ != errorlast) + if ( pC_->getDoubleParam(axisNo_, pC_->GalilError_, &errorlast) || + (error_ != errorlast) ) { pC_->setDoubleParam(axisNo_, pC_->GalilError_, error_); + } //Servo motor velocity strcpy(src, "_TVx"); src[3] = axisName_; velocity_ = pC_->sourceValue(pC_->recdata_, src); //Adjust velocity given controller time base setting velocity_ *= pC_->timeMultiplier_; - pC_->getDoubleParam(axisNo_, pC_->GalilMotorVelocityRAW_, &velocitylast); - if (velocity_ != velocitylast) { + if ( pC_->getDoubleParam(axisNo_, pC_->GalilMotorVelocityRAW_, &velocitylast) || + (velocity_ != velocitylast) ) { pC_->setDoubleParam(axisNo_, pC_->GalilMotorVelocityRAW_, velocity_); pC_->getDoubleParam(axisNo_, pC_->GalilEncoderResolution_, &eres); pC_->setDoubleParam(axisNo_, pC_->GalilMotorVelocityEGU_, velocity_ * eres); @@ -3602,8 +3601,8 @@ void GalilAxis::axisStatusThread() while (true) { //Retrieve required parameters - status = pC_->getIntegerParam(axisNo_, pC_->GalilSSICapable_, &ssiCapable); - status |= pC_->getIntegerParam(axisNo_, pC_->GalilBISSCapable_, &bissCapable); + status = pC_->getIntegerParam(pC_->GalilSSICapable_, &ssiCapable); + status |= pC_->getIntegerParam(pC_->GalilBISSCapable_, &bissCapable); if (event == epicsEventWaitTimeout && !shuttingDown_) { if (ssiCapable == 1 && !status && !shuttingDown_) { diff --git a/GalilSup/src/GalilAxis.h b/GalilSup/src/GalilAxis.h index 405d14c4..f2a8a905 100644 --- a/GalilSup/src/GalilAxis.h +++ b/GalilSup/src/GalilAxis.h @@ -354,7 +354,6 @@ class GalilAxis : public asynMotorAxis epicsEventId axisStatusShutdown_; //Signal indicating axis status thread has shutdown epicsEventId axisStatusShutRequest_; //Request axisStatus thread shutdown - std::string homingRoutineName = ""; bool inAutoOnWait_; friend class GalilController; diff --git a/GalilSup/src/GalilController.cpp b/GalilSup/src/GalilController.cpp index 33d87921..7d1433ab 100644 --- a/GalilSup/src/GalilController.cpp +++ b/GalilSup/src/GalilController.cpp @@ -715,14 +715,7 @@ GalilController::GalilController(const char *portName, const char *address, doub createParam(GalilMotorTypeString, asynParamInt32, &GalilMotorType_); createParam(GalilBrushTypeString, asynParamInt32, &GalilBrushType_); - createParam(GalilHomingRoutineAString, asynParamOctet, &GalilHomingRoutineA_); - createParam(GalilHomingRoutineBString, asynParamOctet, &GalilHomingRoutineB_); - createParam(GalilHomingRoutineCString, asynParamOctet, &GalilHomingRoutineC_); - createParam(GalilHomingRoutineDString, asynParamOctet, &GalilHomingRoutineD_); - createParam(GalilHomingRoutineEString, asynParamOctet, &GalilHomingRoutineE_); - createParam(GalilHomingRoutineFString, asynParamOctet, &GalilHomingRoutineF_); - createParam(GalilHomingRoutineGString, asynParamOctet, &GalilHomingRoutineG_); - createParam(GalilHomingRoutineHString, asynParamOctet, &GalilHomingRoutineH_); + createParam(GalilHomingRoutineString, asynParamOctet, &GalilHomingRoutine_); createParam(GalilEtherCatCapableString, asynParamInt32, &GalilEtherCatCapable_); createParam(GalilEtherCatNetworkString, asynParamInt32, &GalilEtherCatNetwork_); @@ -1287,6 +1280,8 @@ void GalilController::setParamDefaults(void) //Default controller error message to null string setStringParam(0, GalilCtrlError_, ""); + + setIntegerParam(GalilUserArrayUpload_, 0); } // extract the controller ethernet address from the output of the galil TH command @@ -4879,14 +4874,6 @@ asynStatus GalilController::writeOctet(asynUser *pasynUser, const char* value, } } } - else if (function >= GalilHomingRoutineA_ && function <= GalilHomingRoutineH_) - { - GalilAxis* pAxis = getAxis(pasynUser); //Retrieve the axis instance - if (pAxis != nullptr) { - std::string homingRoutineName = pAxis->homingRoutineName; - setStringParam(function, homingRoutineName); - } - } else if (function >= GalilCSMotorForward_ && function <= GalilCSMotorReverseH_) { //User has entered a new kinematic transform equation @@ -6912,10 +6899,10 @@ void GalilController::GalilStartController(char *code_file, int burn_program, in pAxis = getAxis(axisList_[i] - AASCII); if (!pAxis) continue; if (i < homingRoutineNames.size()) { - pAxis->homingRoutineName = homingRoutineNames[i]; + pAxis->setStringParam(GalilHomingRoutine_, homingRoutineNames[i].c_str()); } else { - pAxis->homingRoutineName = ""; + pAxis->setStringParam(GalilHomingRoutine_, ""); } } @@ -7096,7 +7083,6 @@ void GalilController::GalilStartController(char *code_file, int burn_program, in pAxis->limitsDirState_ = unknown; //Pass motor/limits consistency to paramList setIntegerParam(pAxis->axisNo_, GalilLimitConsistent_, pAxis->limitsDirState_); - pAxis->homingRoutineName = homingRoutineNames[i]; } //Retrieve controller time base @@ -7569,37 +7555,37 @@ void GalilController::InitializeDataRecord(void) double GalilController::sourceValue(const std::vector& record, const std::string& source) { - try - { - const Source& s = map.at(source); //use at() function so silent insert does not occur if bad source string is used. - int return_value = 0; - if (s.type[0] == 'U') //unsigned - switch (s.type[1]) - { - case 'B': return_value = *(unsigned char*)(&record[s.byte]); break; - case 'W': return_value = *(unsigned short*)(&record[s.byte]); break; - case 'L': return_value = *(unsigned int*)(&record[s.byte]); break; - } - else //s.type[0] == 'S' //signed - switch (s.type[1]) - { - case 'B': return_value = *(char*)(&record[s.byte]); break; - case 'W': return_value = *(short*)(&record[s.byte]); break; - case 'L': return_value = *(int*)(&record[s.byte]); break; - } - - if (s.bit >= 0) //this is a bit field - { - bool bTRUE = s.scale > 0; //invert logic if scale is <= 0 - return return_value & (1 << s.bit) ? bTRUE : !bTRUE; //check the bit - } - else - return (return_value / s.scale) + s.offset; + // want to avoid silent insert if bad source string is used. + const auto it = map.find(source); + if (it == map.end()) + { + return 0.0; // bad source + } + const Source& s = it->second; + int return_value = 0; + if (s.type[0] == 'U') //unsigned + switch (s.type[1]) + { + case 'B': return_value = *(unsigned char*)(&record[s.byte]); break; + case 'W': return_value = *(unsigned short*)(&record[s.byte]); break; + case 'L': return_value = *(unsigned int*)(&record[s.byte]); break; + } + else //s.type[0] == 'S' //signed + switch (s.type[1]) + { + case 'B': return_value = *(char*)(&record[s.byte]); break; + case 'W': return_value = *(short*)(&record[s.byte]); break; + case 'L': return_value = *(int*)(&record[s.byte]); break; + } - } - catch (const std::out_of_range& e) //bad source - { - return 0.0; + if (s.bit >= 0) //this is a bit field + { + bool bTRUE = s.scale > 0; //invert logic if scale is <= 0 + return return_value & (1 << s.bit) ? bTRUE : !bTRUE; //check the bit + } + else + { + return (return_value / s.scale) + s.offset; } } diff --git a/GalilSup/src/GalilController.h b/GalilSup/src/GalilController.h index 8b40cff9..37f72131 100644 --- a/GalilSup/src/GalilController.h +++ b/GalilSup/src/GalilController.h @@ -141,14 +141,7 @@ #define GalilMotorTypeString "MOTOR_TYPE" #define GalilBrushTypeString "BRUSH_TYPE" -#define GalilHomingRoutineAString "HMRNAM_A" -#define GalilHomingRoutineBString "HMRNAM_B" -#define GalilHomingRoutineCString "HMRNAM_C" -#define GalilHomingRoutineDString "HMRNAM_D" -#define GalilHomingRoutineEString "HMRNAM_E" -#define GalilHomingRoutineFString "HMRNAM_F" -#define GalilHomingRoutineGString "HMRNAM_G" -#define GalilHomingRoutineHString "HMRNAM_H" +#define GalilHomingRoutineString "HMRNAM" #define GalilEtherCatCapableString "CONTROLLER_ECATCAPABLE" #define GalilEtherCatNetworkString "CONTROLLER_ECAT_NETWORK" @@ -704,14 +697,7 @@ class GalilController : public asynMotorController { int GalilMotorDly_; int GalilMotorPosSyncTotal_; - int GalilHomingRoutineA_; - int GalilHomingRoutineB_; - int GalilHomingRoutineC_; - int GalilHomingRoutineD_; - int GalilHomingRoutineE_; - int GalilHomingRoutineF_; - int GalilHomingRoutineG_; - int GalilHomingRoutineH_; + int GalilHomingRoutine_; int GalilCommunicationError_; #define LAST_GALIL_PARAM GalilCommunicationError_