diff --git a/Makefile.RHEL8 b/Makefile.RHEL8 index 9f0713d..99d85b5 100644 --- a/Makefile.RHEL8 +++ b/Makefile.RHEL8 @@ -13,7 +13,7 @@ REQUIRED+=scaler REQUIRED+=asynMotor # Release version -LIBVERSION=2024-dev +LIBVERSION=2024-amor-no-autoenable-lift-axis # DB files to include in the release TEMPLATES += sinqEPICSApp/Db/dimetix.db diff --git a/sinqEPICSApp/src/C804Axis.cpp b/sinqEPICSApp/src/C804Axis.cpp index c1e1500..3d571fe 100644 --- a/sinqEPICSApp/src/C804Axis.cpp +++ b/sinqEPICSApp/src/C804Axis.cpp @@ -1,14 +1,14 @@ #include "C804Axis.h" #include "C804Controller.h" -#include -#include -#include #include -#include +#include #include +#include +#include +#include -C804Axis::C804Axis(C804Controller *pC, int axisNo) : SINQAxis(pC, axisNo), pC_(pC) -{ +C804Axis::C804Axis(C804Controller *pC, int axisNo) + : SINQAxis(pC, axisNo), pC_(pC) { /* The superclass constructor SINQAxis calls in turn its superclass constructor asynMotorAxis. In the latter, a pointer to the constructed object this is @@ -16,13 +16,14 @@ C804Axis::C804Axis(C804Controller *pC, int axisNo) : SINQAxis(pC, axisNo), pC_(p pC->pAxes_[axisNo] = this; - Therefore, the axes are managed by the controller pC. See C804Controller.cpp for further explanation. - If axisNo is out of bounds, asynMotorAxis prints an error (see - https://github.com/epics-modules/motor/blob/master/motorApp/MotorSrc/asynMotorAxis.cpp, line 40). - However, we want the IOC creation to stop completely, since this is a configuration error. + Therefore, the axes are managed by the controller pC. See C804Controller.cpp + for further explanation. If axisNo is out of bounds, asynMotorAxis prints an + error (see + https://github.com/epics-modules/motor/blob/master/motorApp/MotorSrc/asynMotorAxis.cpp, + line 40). However, we want the IOC creation to stop completely, since this + is a configuration error. */ - if (axisNo >= pC->numAxes_) - { + if (axisNo >= pC->numAxes_) { exit(-1); } last_position_steps_ = 0; @@ -30,8 +31,7 @@ C804Axis::C804Axis(C804Controller *pC, int axisNo) : SINQAxis(pC, axisNo), pC_(p last_poll_ = 0.0; } -C804Axis::~C804Axis(void) -{ +C804Axis::~C804Axis(void) { // Since the controller memory is managed somewhere else, we don't need to // clean up the pointer pC here. } @@ -39,47 +39,44 @@ C804Axis::~C804Axis(void) /* The polling function informs us about the state of the axis, in particular if it is currently moving. It is called periodically, with the period defined by -the controller constructor arguments idlePollPeriod and movingPollPeriod depending on -the current axis state. +the controller constructor arguments idlePollPeriod and movingPollPeriod +depending on the current axis state. */ -asynStatus C804Axis::poll(bool *moving) -{ +asynStatus C804Axis::poll(bool *moving) { // Local variable declaration static const char *functionName = "C804Axis::poll"; - // The poll function is just a wrapper around poll_no_param_lib_update and handles mainly - // the callParamCallbacks() function + // The poll function is just a wrapper around poll_no_param_lib_update and + // handles mainly the callParamCallbacks() function asynStatus status_poll = C804Axis::poll_no_param_lib_update(moving); // According to the function documentation of asynMotorAxis::poll, this // function should be called at the end of a poll implementation. asynStatus status_callback = callParamCallbacks(); - if (status_callback != asynSuccess) - {d + if (status_callback != asynSuccess) { asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, - "%s: Updating the parameter library failed for axis %d\n", functionName, axisNo_); + "%s: Updating the parameter library failed for axis %d\n", + functionName, axisNo_); return status_callback; - } - else - { + } else { return status_poll; } } // Perform the actual poll -asynStatus C804Axis::poll_no_param_lib_update(bool *moving) -{ +asynStatus C804Axis::poll_no_param_lib_update(bool *moving) { // Local variable declaration static const char *functionName = "C804Axis::poll"; asynStatus status; int axis_status = 0; // The controller returns the position and velocity in encoder steps. - // This value needs to be converted in user units (engineering units EGU) via - // the record field MRES of the motor record. This field has already been read - // by the constructor into the member variable motorRecResolution_. - // To go from steps to user units, multiply with motorRecResolution_ - // Example: If 10 steps correspond to 1 mm, MRES should be 0.1. + // This value needs to be converted in user units (engineering units EGU) + // via the record field MRES of the motor record. This field has already + // been read by the constructor into the member variable + // motorRecResolution_. To go from steps to user units, multiply with + // motorRecResolution_ Example: If 10 steps correspond to 1 mm, MRES should + // be 0.1. int position_error_steps = 0; int motor_position_steps = 0; int motor_velocity_steps = 0; @@ -89,28 +86,28 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving) double motor_velocity = .0; double programmed_motor_velocity = .0; - // The buffer sizes for command and response are defined in the controller (see the corresponding source code files) + // The buffer sizes for command and response are defined in the controller + // (see the corresponding source code files) char command[pC_->C804_MAXBUF_], response[pC_->C804_MAXBUF_]; /* Cancel the poll if the last poll has "just" happened. */ - if (time(NULL) < last_poll_ + 0.5 * pC_->movingPollPeriod_) - { + if (time(NULL) < last_poll_ + 0.5 * pC_->movingPollPeriod_) { asynPrint(pC_->pasynUserSelf, ASYN_TRACE_WARNING, - "%s: Aborted poll since the last poll for axis %d happened a short time ago\n", functionName, axisNo_); + "%s: Aborted poll since the last poll for axis %d happened a " + "short time ago\n", + functionName, axisNo_); return asynSuccess; - } - else - { + } else { last_poll_ = time(NULL); } /* The parameter motorRecResolution_ is coupled to the field MRES of the motor record in the following manner: - - In sinq_asyn_motor.db, the PV (motor_record_pv_name)MOTOR_REC_RESOLUTION is - defined as a copy of the field (motor_record_pv_name).MRES: + - In sinq_asyn_motor.db, the PV (motor_record_pv_name)MOTOR_REC_RESOLUTION + is defined as a copy of the field (motor_record_pv_name).MRES: record(ao,"$(P)$(M):Resolution") { field(DESC, "$(M) resolution") @@ -121,27 +118,30 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving) field(PREC, "$(PREC)") } - - The PV name MOTOR_REC_RESOLUTION is coupled in asynMotorController.h to the constant motorRecResolutionString - - ... which in turn is assigned to motorRecResolution_ in asynMotorController.cpp - This way of making the field visible to the driver is described here: https://epics.anl.gov/tech-talk/2020/msg00378.php - This is a one-way coupling, changes to the parameter library via setDoubleParam - are NOT transferred to (motor_record_pv_name).MRES or to (motor_record_pv_name):Resolution. + - The PV name MOTOR_REC_RESOLUTION is coupled in asynMotorController.h to + the constant motorRecResolutionString + - ... which in turn is assigned to motorRecResolution_ in + asynMotorController.cpp This way of making the field visible to the driver + is described here: https://epics.anl.gov/tech-talk/2020/msg00378.php This is + a one-way coupling, changes to the parameter library via setDoubleParam are + NOT transferred to (motor_record_pv_name).MRES or to + (motor_record_pv_name):Resolution. NOTE: This function must not be called in the constructor (e.g. in order to - save the read result to the member variable earlier), since the parameter library - is updated at a later stage! + save the read result to the member variable earlier), since the parameter + library is updated at a later stage! */ - pC_->getDoubleParam(axisNo_, pC_->motorRecResolution_, &motorRecResolution_); + pC_->getDoubleParam(axisNo_, pC_->motorRecResolution_, + &motorRecResolution_); - asynPrint(pC_->pasynUserSelf,ASYN_TRACE_FLOW,"Poll axis %d\n", axisNo_); + asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW, "Poll axis %d\n", axisNo_); /* - We know that the motor resolution must not be zero. During the startup of the - IOC, polls can happen before the record is fully initialized. In that case, - all values are zero. + We know that the motor resolution must not be zero. During the startup of + the IOC, polls can happen before the record is fully initialized. In that + case, all values are zero. */ - if (motorRecResolution_ == 0) - { + if (motorRecResolution_ == 0) { return asynError; } @@ -154,11 +154,11 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving) */ setIntegerParam(pC_->motorStatusProblem_, false); - // Read out the position error of the axis (delta of target position to actual position) + // Read out the position error of the axis (delta of target position to + // actual position) snprintf(command, pC_->C804_MAXBUF_ - 1, "%dTE", axisNo_); status = pC_->lowLevelWriteRead(axisNo_, command, response, true); - if (status == asynSuccess) - { + if (status == asynSuccess) { int parsed_axis; sscanf(response, "%2dE%10d", &parsed_axis, &position_error_steps); @@ -166,12 +166,12 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving) position_error = double(position_error_steps) * motorRecResolution_; asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW, - "%s: Axis %d, response %s, position error %f\n", functionName, axisNo_, response, position_error); - } - else - { + "%s: Axis %d, response %s, position error %f\n", functionName, + axisNo_, response, position_error); + } else { asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, - "%s: Reading the position error failed for axis %d\n", functionName, axisNo_); + "%s: Reading the position error failed for axis %d\n", + functionName, axisNo_); setIntegerParam(pC_->motorStatusProblem_, true); // Stop the evaluation prematurely @@ -180,9 +180,9 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving) // Read the current position. snprintf(command, this->pC_->C804_MAXBUF_ - 1, "%dTP", this->axisNo_); - status = this->pC_->lowLevelWriteRead(this->axisNo_, command, response, true); - if (status == asynSuccess) - { + status = + this->pC_->lowLevelWriteRead(this->axisNo_, command, response, true); + if (status == asynSuccess) { int parsed_axis; sscanf(response, "%2dP%10d", &parsed_axis, &motor_position_steps); @@ -190,14 +190,14 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving) motor_position = double(motor_position_steps) * motorRecResolution_; asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW, - "%s: Axis %d, response %s, position %f\n", functionName, axisNo_, response, motor_position); + "%s: Axis %d, response %s, position %f\n", functionName, + axisNo_, response, motor_position); setDoubleParam(pC_->motorPosition_, motor_position); setDoubleParam(pC_->motorEncoderPosition_, motor_position); - } - else - { + } else { asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, - "%s: Reading the position failed for axis %d\n", functionName, axisNo_); + "%s: Reading the position failed for axis %d\n", functionName, + axisNo_); setIntegerParam(pC_->motorStatusProblem_, true); return status; @@ -205,9 +205,9 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving) // Read the current velocity snprintf(command, this->pC_->C804_MAXBUF_ - 1, "%dTV", this->axisNo_); - status = this->pC_->lowLevelWriteRead(this->axisNo_, command, response, true); - if (status == asynSuccess) - { + status = + this->pC_->lowLevelWriteRead(this->axisNo_, command, response, true); + if (status == asynSuccess) { int parsed_axis; sscanf(response, "%2dV%10d", &parsed_axis, &motor_velocity_steps); @@ -215,12 +215,12 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving) motor_velocity = double(motor_velocity_steps) * motorRecResolution_; asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW, - "%s: Axis %d, response %s, velocity %f\n", functionName, axisNo_, response, motor_velocity); - } - else - { + "%s: Axis %d, response %s, velocity %f\n", functionName, + axisNo_, response, motor_velocity); + } else { asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, - "%s: Reading the velocity failed for axis %d\n", functionName, axisNo_); + "%s: Reading the velocity failed for axis %d\n", functionName, + axisNo_); setIntegerParam(pC_->motorStatusProblem_, true); return status; @@ -228,23 +228,25 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving) // Read the programmed velocity snprintf(command, this->pC_->C804_MAXBUF_ - 1, "%dTY", this->axisNo_); - status = this->pC_->lowLevelWriteRead(this->axisNo_, command, response, true); - if (status == asynSuccess) - { + status = + this->pC_->lowLevelWriteRead(this->axisNo_, command, response, true); + if (status == asynSuccess) { int parsed_axis; - sscanf(response, "%2dY%10d", &parsed_axis, &programmed_motor_velocity_steps); + sscanf(response, "%2dY%10d", &parsed_axis, + &programmed_motor_velocity_steps); // Scale from the encoder resultion to user units - programmed_motor_velocity = double(programmed_motor_velocity_steps) * motorRecResolution_; + programmed_motor_velocity = + double(programmed_motor_velocity_steps) * motorRecResolution_; asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW, - "%s: Axis %d, response %s, programmed velocity %f\n", functionName, axisNo_, response, programmed_motor_velocity); - } - else - { + "%s: Axis %d, response %s, programmed velocity %f\n", + functionName, axisNo_, response, programmed_motor_velocity); + } else { asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, - "%s: Reading the programmed velocity failed for axis %d\n", functionName, axisNo_); + "%s: Reading the programmed velocity failed for axis %d\n", + functionName, axisNo_); setIntegerParam(pC_->motorStatusProblem_, true); return status; @@ -253,15 +255,13 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving) // Read the motor status snprintf(command, pC_->C804_MAXBUF_ - 1, "%dTS", axisNo_); status = pC_->lowLevelWriteRead(this->axisNo_, command, response, true); - if (status == asynSuccess) - { + if (status == asynSuccess) { int parsed_axis; sscanf(response, "%2dS%10d", &parsed_axis, &axis_status); asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW, - "%s: Axis %d, response %s, status %d\n", functionName, axisNo_, response, axis_status); - } - else - { + "%s: Axis %d, response %s, status %d\n", functionName, + axisNo_, response, axis_status); + } else { asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: Reading the motor status %d\n", functionName, axisNo_); setIntegerParam(pC_->motorStatusProblem_, true); @@ -270,24 +270,22 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving) return status; } - // Check if the axis is enabled by reading out bit 2 (see https://stackoverflow.com/questions/2249731/how-do-i-get-bit-by-bit-data-from-an-integer-value-in-c) + // Check if the axis is enabled by reading out bit 2 (see + // https://stackoverflow.com/questions/2249731/how-do-i-get-bit-by-bit-data-from-an-integer-value-in-c) int mask = 1 << 2; int masked_n = axis_status & mask; // Is 1 if the axis is disabled int disabled = masked_n >> 2; - if (disabled) - { + if (disabled) { enabled_ = false; - } - else - { + } else { enabled_ = true; } /* - Determine if the motor is moving. This is determined by the following criteria: - 1) The motor position changes from poll to poll - 2) The motor is enabled + Determine if the motor is moving. This is determined by the following + criteria: 1) The motor position changes from poll to poll 2) The motor is + enabled */ *moving = enabled_ && motor_position_steps != this->last_position_steps_; @@ -300,22 +298,21 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving) moving. If it has spent too much time in a moving state without reaching the target, stop the motor and return an error. */ - if (*moving) - { + if (*moving) { int motorStatusMoving = 0; - pC_->getIntegerParam(axisNo_, pC_->motorStatusMoving_, &motorStatusMoving); + pC_->getIntegerParam(axisNo_, pC_->motorStatusMoving_, + &motorStatusMoving); // motor is moving, but didn't move in the last poll - if (motorStatusMoving == 0) - { + if (motorStatusMoving == 0) { time_t current_time = time(NULL); // Factor 2 of the calculated moving time - estimatedArrivalTime_ = current_time + std::ceil(2 * std::fabs(position_error) / programmed_motor_velocity); - } - else - { + estimatedArrivalTime_ = + current_time + std::ceil(2 * std::fabs(position_error) / + programmed_motor_velocity); + } else { // /* // Motor is moving for a longer time than it should: Stop it // */ @@ -323,7 +320,9 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving) // { // snprintf(command, pC_->C804_MAXBUF_ - 1, "%dST", axisNo_); // status = pC_->lowLevelWriteRead(axisNo_, command, response); - // asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: Stopped axis %d since it moved for double the time it should to reach its target\n", functionName, axisNo_); + // asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: Stopped + // axis %d since it moved for double the time it should to reach + // its target\n", functionName, axisNo_); // } } } @@ -339,54 +338,58 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving) return status; } -asynStatus C804Axis::move(double position, int relative, double minVelocity, double maxVelocity, double acceleration) -{ +asynStatus C804Axis::move(double position, int relative, double minVelocity, + double maxVelocity, double acceleration) { asynStatus status; static const char *functionName = "C804Axis::move"; char command[pC_->C804_MAXBUF_], response[pC_->C804_MAXBUF_]; double position_c_units = 0.0; // Controller units int position_steps = 0; - // Convert from user coordinates (EGU) to controller coordinates (steps). Check for overflow - if (motorRecResolution_ == 0.0) - { - asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: MRES must not be zero. Movement is aborted", functionName); + // Convert from user coordinates (EGU) to controller coordinates (steps). + // Check for overflow + if (motorRecResolution_ == 0.0) { + asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, + "%s: MRES must not be zero. Movement is aborted", + functionName); return asynError; } position_c_units = position / motorRecResolution_; // Check for overflow during the division - if (position_c_units * motorRecResolution_ != position) - { - asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, - "%s: could not convert from user units (%f) to controller units (user units divided by resolution MRES %f) due to overflow.", - functionName, position, motorRecResolution_); + if (position_c_units * motorRecResolution_ != position) { + asynPrint( + pC_->pasynUserSelf, ASYN_TRACE_ERROR, + "%s: could not convert from user units (%f) to controller units " + "(user units divided by resolution MRES %f) due to overflow.", + functionName, position, motorRecResolution_); return asynError; } - // Steps can only be integer values => cast to integer while checking for overflow - if (std::numeric_limits::max() < position_c_units || std::numeric_limits::min() > position_c_units) - { + // Steps can only be integer values => cast to integer while checking for + // overflow + if (std::numeric_limits::max() < position_c_units || + std::numeric_limits::min() > position_c_units) { asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, - "%s: target position %f cannot be converted to int (overflow). Check target value %f and MRES %f", - functionName, position_c_units, position_c_units, motorRecResolution_); + "%s: target position %f cannot be converted to int " + "(overflow). Check target value %f and MRES %f", + functionName, position_c_units, position_c_units, + motorRecResolution_); return asynError; } position_steps = static_cast(position_c_units); // Convert from relative to absolute values - if (relative) - { + if (relative) { position_steps += last_position_steps_; } // If the axis is currently disabled, enable it - if (!enabled_) - { + if (!enabled_) { snprintf(command, pC_->C804_MAXBUF_ - 1, "%dGO", axisNo_); - status = pC_->lowLevelWriteRead(this->axisNo_, command, response, false); - if (status != asynSuccess) - { + status = + pC_->lowLevelWriteRead(this->axisNo_, command, response, false); + if (status != asynSuccess) { asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: Enabling axis %d\n failed", functionName, axisNo_); return status; @@ -396,10 +399,10 @@ asynStatus C804Axis::move(double position, int relative, double minVelocity, dou // Start movement snprintf(command, pC_->C804_MAXBUF_ - 1, "%dMA%d", axisNo_, position_steps); status = pC_->lowLevelWriteRead(this->axisNo_, command, response, false); - if (status != asynSuccess) - { + if (status != asynSuccess) { asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, - "%s: Setting the target position %d failed for axis %d\n", functionName, position_steps, axisNo_); + "%s: Setting the target position %d failed for axis %d\n", + functionName, position_steps, axisNo_); setIntegerParam(pC_->motorStatusProblem_, true); return status; } @@ -411,14 +414,13 @@ asynStatus C804Axis::move(double position, int relative, double minVelocity, dou return status; } -asynStatus C804Axis::moveVelocity(double min_velocity, double max_velocity, double acceleration) -{ +asynStatus C804Axis::moveVelocity(double min_velocity, double max_velocity, + double acceleration) { static const char *functionName = "C804Axis::moveVelocity"; return asynError; } -asynStatus C804Axis::stop(double acceleration) -{ +asynStatus C804Axis::stop(double acceleration) { asynStatus status = asynSuccess; static const char *functionName = "C804Axis::stop"; char command[pC_->C804_MAXBUF_], response[pC_->C804_MAXBUF_]; @@ -426,26 +428,28 @@ asynStatus C804Axis::stop(double acceleration) bool moving = false; poll(&moving); - if (moving) - { + if (moving) { // ST = Stop snprintf(command, pC_->C804_MAXBUF_ - 1, "%dST", axisNo_); status = pC_->lowLevelWriteRead(axisNo_, command, response, false); - asynPrint(pC_->pasynUserSelf, ASYN_TRACEIO_DEVICE, "%s: Stop axis %d\n", functionName, axisNo_); + asynPrint(pC_->pasynUserSelf, ASYN_TRACEIO_DEVICE, "%s: Stop axis %d\n", + functionName, axisNo_); } return status; } -asynStatus C804Axis::home(double minVelocity, double maxVelocity, double acceleration, int forwards) -{ +asynStatus C804Axis::home(double minVelocity, double maxVelocity, + double acceleration, int forwards) { asynStatus status = asynSuccess; static const char *functionName = "C804Axis::home"; char command[pC_->C804_MAXBUF_], response[pC_->C804_MAXBUF_]; - snprintf(command, pC_->C804_MAXBUF_ - 1, "%dFE0", axisNo_); // Home to the upper limit of the axis (25 mm) + snprintf(command, pC_->C804_MAXBUF_ - 1, "%dFE0", + axisNo_); // Home to the upper limit of the axis (25 mm) status = pC_->lowLevelWriteRead(axisNo_, command, response, false); - asynPrint(pC_->pasynUserSelf, ASYN_TRACEIO_DEVICE, "%s: Homing axis %d\n", functionName, axisNo_); + asynPrint(pC_->pasynUserSelf, ASYN_TRACEIO_DEVICE, "%s: Homing axis %d\n", + functionName, axisNo_); return status; } @@ -453,23 +457,21 @@ asynStatus C804Axis::home(double minVelocity, double maxVelocity, double acceler /** If on is 0, disable the motor, otherwise enable it. */ -asynStatus C804Axis::enable(int on) -{ +asynStatus C804Axis::enable(int on) { asynStatus status = asynSuccess; static const char *functionName = "C804Axis::enable"; char command[pC_->C804_MAXBUF_], response[pC_->C804_MAXBUF_]; - if (on == 0) - { + if (on == 0) { snprintf(command, pC_->C804_MAXBUF_ - 1, "%dMF", axisNo_); status = pC_->lowLevelWriteRead(axisNo_, command, response, false); - asynPrint(pC_->pasynUserSelf, ASYN_TRACEIO_DEVICE, "%s: Disable axis %d\n", functionName, axisNo_); - } - else - { + asynPrint(pC_->pasynUserSelf, ASYN_TRACEIO_DEVICE, + "%s: Disable axis %d\n", functionName, axisNo_); + } else { snprintf(command, pC_->C804_MAXBUF_ - 1, "%dMN", axisNo_); status = pC_->lowLevelWriteRead(axisNo_, command, response, false); - asynPrint(pC_->pasynUserSelf, ASYN_TRACEIO_DEVICE, "%s: Enable axis %d\n", functionName, axisNo_); + asynPrint(pC_->pasynUserSelf, ASYN_TRACEIO_DEVICE, + "%s: Enable axis %d\n", functionName, axisNo_); } return status; } diff --git a/sinqEPICSApp/src/pmacAxis.h b/sinqEPICSApp/src/pmacAxis.h index 1fc6454..0f4f385 100644 --- a/sinqEPICSApp/src/pmacAxis.h +++ b/sinqEPICSApp/src/pmacAxis.h @@ -1,169 +1,180 @@ /******************************************** * pmacAxis.cpp - * - * PMAC Asyn motor based on the + * + * PMAC Asyn motor based on the * asynMotorAxis class. - * + * * Matthew Pearson * 23 May 2012 - * + * * Modified to use the MsgTxt field for SINQ * * Mark Koennecke, January 2019 * - * EXtended with special motor axis for the Selene + * EXtended with special motor axis for the Selene * guide, Mark Koennecke, February 2020 ********************************************/ #ifndef pmacAxis_H #define pmacAxis_H -#include "SINQController.h" #include "SINQAxis.h" +#include "SINQController.h" class pmacController; class SeleneController; -class pmacAxis : public SINQAxis -{ +class pmacAxis : public SINQAxis { public: - /* These are the methods we override from the base class */ - pmacAxis(pmacController *pController, int axisNo, bool enable=true); - virtual ~pmacAxis(); - asynStatus move(double position, int relative, double min_velocity, double max_velocity, double acceleration); - asynStatus moveVelocity(double min_velocity, double max_velocity, double acceleration); - asynStatus home(double min_velocity, double max_velocity, double acceleration, int forwards); - asynStatus stop(double acceleration); - asynStatus poll(bool *moving); - asynStatus setPosition(double position); - asynStatus enable(int on); + /* These are the methods we override from the base class */ + pmacAxis(pmacController *pController, int axisNo, bool enable = true); + virtual ~pmacAxis(); + asynStatus move(double position, int relative, double min_velocity, + double max_velocity, double acceleration); + asynStatus moveVelocity(double min_velocity, double max_velocity, + double acceleration); + asynStatus home(double min_velocity, double max_velocity, + double acceleration, int forwards); + asynStatus stop(double acceleration); + asynStatus poll(bool *moving); + asynStatus setPosition(double position); + asynStatus enable(int on); -protected: - pmacController *pC_; - - asynStatus getAxisStatus(bool *moving); - asynStatus getAxisInitialStatus(void); + protected: + pmacController *pC_; - double setpointPosition_; - double encoderPosition_; - double currentVelocity_; - double velocity_; - double accel_; - double highLimit_; - double lowLimit_; - double scale_; - double previous_position_; - int previous_direction_; - int encoder_axis_; - int axisErrorCount; + asynStatus getAxisStatus(bool *moving); + asynStatus getAxisInitialStatus(void); - time_t startTime; - time_t status6Time; - int starting; - int homing; - double statusPos; + double setpointPosition_; + double encoderPosition_; + double currentVelocity_; + double velocity_; + double accel_; + double highLimit_; + double lowLimit_; + double scale_; + double previous_position_; + int previous_direction_; + int encoder_axis_; + int axisErrorCount; - time_t next_poll; + time_t startTime; + time_t status6Time; + int starting; + int homing; + double statusPos; - bool autoEnable; - - friend class pmacController; - friend class pmacV3Controller; + time_t next_poll; + + bool autoEnable; + + friend class pmacController; + friend class pmacV3Controller; }; /*--------------------------------------------------------------------------------------------*/ -class SeleneAxis : public pmacAxis -{ +class SeleneAxis : public pmacAxis { public: - SeleneAxis(SeleneController *pController, int axisNo, double limitTarget); - asynStatus move(double position, int relative, double min_velocity, double max_velocity, double acceleration); - asynStatus setPosition(double position); - asynStatus home(double min_velocity, double max_velocity, double acceleration, int forwards); + SeleneAxis(SeleneController *pController, int axisNo, double limitTarget); + asynStatus move(double position, int relative, double min_velocity, + double max_velocity, double acceleration); + asynStatus setPosition(double position); + asynStatus home(double min_velocity, double max_velocity, + double acceleration, int forwards); - protected: - friend class SeleneController; - friend class pmacController; - - private: - double limitTarget; - asynStatus getSeleneAxisInitialStatus(void); + protected: + friend class SeleneController; + friend class pmacController; + private: + double limitTarget; + asynStatus getSeleneAxisInitialStatus(void); }; /* - Yet another special set of motors for the Selene Guide at AMOR. Each segment can be lifted or tilted. This is - two motors. One acts as a slave and only writes a new target, the other also sets a new target and sends the - actual movement command. Both motors are coordianted in the motor controller in order to avoid tension on - the guide elements. This gaves rise to the function code LIFTSLAVE and LIFTMASTER. + Yet another special set of motors for the Selene Guide at AMOR. Each segment + can be lifted or tilted. This is two motors. One acts as a slave and only + writes a new target, the other also sets a new target and sends the actual + movement command. Both motors are coordianted in the motor controller in order + to avoid tension on the guide elements. This gaves rise to the function code + LIFTSLAVE and LIFTMASTER. - In another mode the whole guide can be lifted or tilted. Then motor 1 and 6 get new values and one of them - sends the drive command. This causes all 6 motors to drive synchronously to their new targets. This is - implemented through the LIFTSEGMENT function code. + In another mode the whole guide can be lifted or tilted. Then motor 1 and 6 + get new values and one of them sends the drive command. This causes all 6 + motors to drive synchronously to their new targets. This is implemented + through the LIFTSEGMENT function code. - Mark Koennecke, February 2020 + Mark Koennecke, February 2020 The axis should not be enabled automatically - Michele Brambilla, February 2020 + Michele Brambilla, February 2020 */ -class LiftAxis : public pmacAxis -{ - public: - LiftAxis(pmacController *pController, int axisNo) : pmacAxis((pmacController *)pController,axisNo) {}; - asynStatus move(double position, int relative, double min_velocity, double max_velocity, double acceleration); - asynStatus poll(bool *moving); - asynStatus stop(double acceleration); - private: - int waitStart; +class LiftAxis : public pmacAxis { + public: + /* + The default constructor of LiftAxis just forwards to the pmacAxis + constructor, which has an optional argument "autoenable" with the default + value "true". However, we want that argument to be false, hence we provide + an explicit constructor + */ + LiftAxis(pmacController *pController, int axisNo) + : pmacAxis((pmacController *)pController, axisNo, false) {}; + asynStatus move(double position, int relative, double min_velocity, + double max_velocity, double acceleration); + asynStatus poll(bool *moving); + asynStatus stop(double acceleration); + + private: + int waitStart; }; - /******************************************** +/******************************************** * Protocol version 3 requires just some minor change * * Michele Brambilla, February 2022 ********************************************/ class pmacV3Axis : public pmacAxis { -public: + public: + pmacV3Axis(pmacController *pController, int axisNo); - pmacV3Axis(pmacController *pController, int axisNo); + asynStatus move(double position, int relative, double min_velocity, + double max_velocity, double acceleration); + asynStatus poll(bool *moving); - asynStatus move(double position, int relative, double min_velocity, - double max_velocity, double acceleration); - asynStatus poll(bool *moving); - protected: - int IsEnable; - double Speed; + protected: + int IsEnable; + double Speed; - asynStatus getAxisStatus(bool *moving); + asynStatus getAxisStatus(bool *moving); - friend class pmacController; - friend class pmacV3Controller; - }; - -/*----------------------------------------------------------------------------------------------*/ -class pmacHRPTAxis : public pmacV3Axis -{ - public: - pmacHRPTAxis(pmacController *pController, int axisNo) : pmacV3Axis(pController,axisNo) {}; - /** - * Override getAxisStatus in order to read the special parameter indicating a - * slit blade crash at HRPT - */ - asynStatus getAxisStatus(bool *moving); - - protected: - friend class pmacController; - + friend class pmacController; + friend class pmacV3Controller; }; +/*----------------------------------------------------------------------------------------------*/ +class pmacHRPTAxis : public pmacV3Axis { + public: + pmacHRPTAxis(pmacController *pController, int axisNo) + : pmacV3Axis(pController, axisNo) {}; + /** + * Override getAxisStatus in order to read the special parameter indicating + * a slit blade crash at HRPT + */ + asynStatus getAxisStatus(bool *moving); + + protected: + friend class pmacController; +}; /* * Special motors for the AMOR detector movement. The whole * command set is different but on a pmac controller. This implements * a coordinated movement of cox, coz and ftz in order not to break * the flight tube which may have been mounted. This is mapped to three - * motors selected via the function code: com, the detector omega, coz, + * motors selected via the function code: com, the detector omega, coz, * the detector z offset and park, for parking the flightpath. */ @@ -171,39 +182,41 @@ class pmacHRPTAxis : public pmacV3Axis #define ADCOZ 2 #define ADPARK 3 -class AmorDetectorAxis: public pmacAxis { -public: - AmorDetectorAxis(pmacController *pController, int axisNo, int function); +class AmorDetectorAxis : public pmacAxis { + public: + AmorDetectorAxis(pmacController *pController, int axisNo, int function); - asynStatus move(double position, int relative, double min_velocity, - double max_velocity, double acceleration); - asynStatus poll(bool *moving); - asynStatus moveVelocity(double min_velocity, double max_velocity, double acceleration); - asynStatus home(double min_velocity, double max_velocity, double acceleration, int forwards); - asynStatus stop(double acceleration); - asynStatus setPosition(double position); + asynStatus move(double position, int relative, double min_velocity, + double max_velocity, double acceleration); + asynStatus poll(bool *moving); + asynStatus moveVelocity(double min_velocity, double max_velocity, + double acceleration); + asynStatus home(double min_velocity, double max_velocity, + double acceleration, int forwards); + asynStatus stop(double acceleration); + asynStatus setPosition(double position); -protected: - int _function; - int det_starting; - time_t det_startTime; + protected: + int _function; + int det_starting; + time_t det_startTime; }; /*----------------------------------------------------------------------------------------------*/ - -class GirderAxis: public pmacV3Axis { +class GirderAxis : public pmacV3Axis { public: GirderAxis(pmacController *pController, int axisNo); - asynStatus move(double position, int relative, double min_velocity, double max_velocity, double acceleration); + asynStatus move(double position, int relative, double min_velocity, + double max_velocity, double acceleration); asynStatus stop(double acceleration); asynStatus poll(bool *moving); protected: int IsEnable; - friend class pmacController; - friend class pmacV3Controller; + friend class pmacController; + friend class pmacV3Controller; }; #endif /* pmacAxis_H */