Removed typo from C804Axis.cpp
This commit is contained in:
@ -1,14 +1,14 @@
|
|||||||
#include "C804Axis.h"
|
#include "C804Axis.h"
|
||||||
#include "C804Controller.h"
|
#include "C804Controller.h"
|
||||||
#include <errlog.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <unistd.h>
|
#include <errlog.h>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
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
|
The superclass constructor SINQAxis calls in turn its superclass constructor
|
||||||
asynMotorAxis. In the latter, a pointer to the constructed object this is
|
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;
|
pC->pAxes_[axisNo] = this;
|
||||||
|
|
||||||
Therefore, the axes are managed by the controller pC. See C804Controller.cpp for further explanation.
|
Therefore, the axes are managed by the controller pC. See C804Controller.cpp
|
||||||
If axisNo is out of bounds, asynMotorAxis prints an error (see
|
for further explanation. If axisNo is out of bounds, asynMotorAxis prints an
|
||||||
https://github.com/epics-modules/motor/blob/master/motorApp/MotorSrc/asynMotorAxis.cpp, line 40).
|
error (see
|
||||||
However, we want the IOC creation to stop completely, since this is a configuration error.
|
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);
|
exit(-1);
|
||||||
}
|
}
|
||||||
last_position_steps_ = 0;
|
last_position_steps_ = 0;
|
||||||
@ -30,8 +31,7 @@ C804Axis::C804Axis(C804Controller *pC, int axisNo) : SINQAxis(pC, axisNo), pC_(p
|
|||||||
last_poll_ = 0.0;
|
last_poll_ = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
C804Axis::~C804Axis(void)
|
C804Axis::~C804Axis(void) {
|
||||||
{
|
|
||||||
// Since the controller memory is managed somewhere else, we don't need to
|
// Since the controller memory is managed somewhere else, we don't need to
|
||||||
// clean up the pointer pC here.
|
// 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
|
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
|
is currently moving. It is called periodically, with the period defined by
|
||||||
the controller constructor arguments idlePollPeriod and movingPollPeriod depending on
|
the controller constructor arguments idlePollPeriod and movingPollPeriod
|
||||||
the current axis state.
|
depending on the current axis state.
|
||||||
*/
|
*/
|
||||||
asynStatus C804Axis::poll(bool *moving)
|
asynStatus C804Axis::poll(bool *moving) {
|
||||||
{
|
|
||||||
// Local variable declaration
|
// Local variable declaration
|
||||||
static const char *functionName = "C804Axis::poll";
|
static const char *functionName = "C804Axis::poll";
|
||||||
|
|
||||||
// The poll function is just a wrapper around poll_no_param_lib_update and handles mainly
|
// The poll function is just a wrapper around poll_no_param_lib_update and
|
||||||
// the callParamCallbacks() function
|
// handles mainly the callParamCallbacks() function
|
||||||
asynStatus status_poll = C804Axis::poll_no_param_lib_update(moving);
|
asynStatus status_poll = C804Axis::poll_no_param_lib_update(moving);
|
||||||
|
|
||||||
// According to the function documentation of asynMotorAxis::poll, this
|
// According to the function documentation of asynMotorAxis::poll, this
|
||||||
// function should be called at the end of a poll implementation.
|
// function should be called at the end of a poll implementation.
|
||||||
asynStatus status_callback = callParamCallbacks();
|
asynStatus status_callback = callParamCallbacks();
|
||||||
if (status_callback != asynSuccess)
|
if (status_callback != asynSuccess) {
|
||||||
{d
|
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
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;
|
return status_callback;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return status_poll;
|
return status_poll;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform the actual 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
|
// Local variable declaration
|
||||||
static const char *functionName = "C804Axis::poll";
|
static const char *functionName = "C804Axis::poll";
|
||||||
asynStatus status;
|
asynStatus status;
|
||||||
int axis_status = 0;
|
int axis_status = 0;
|
||||||
|
|
||||||
// The controller returns the position and velocity in encoder steps.
|
// The controller returns the position and velocity in encoder steps.
|
||||||
// This value needs to be converted in user units (engineering units EGU) via
|
// This value needs to be converted in user units (engineering units EGU)
|
||||||
// the record field MRES of the motor record. This field has already been read
|
// via the record field MRES of the motor record. This field has already
|
||||||
// by the constructor into the member variable motorRecResolution_.
|
// been read by the constructor into the member variable
|
||||||
// To go from steps to user units, multiply with motorRecResolution_
|
// motorRecResolution_. To go from steps to user units, multiply with
|
||||||
// Example: If 10 steps correspond to 1 mm, MRES should be 0.1.
|
// motorRecResolution_ Example: If 10 steps correspond to 1 mm, MRES should
|
||||||
|
// be 0.1.
|
||||||
int position_error_steps = 0;
|
int position_error_steps = 0;
|
||||||
int motor_position_steps = 0;
|
int motor_position_steps = 0;
|
||||||
int motor_velocity_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 motor_velocity = .0;
|
||||||
double programmed_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_];
|
char command[pC_->C804_MAXBUF_], response[pC_->C804_MAXBUF_];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Cancel the poll if the last poll has "just" happened.
|
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,
|
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;
|
return asynSuccess;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
last_poll_ = time(NULL);
|
last_poll_ = time(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The parameter motorRecResolution_ is coupled to the field MRES of the motor
|
The parameter motorRecResolution_ is coupled to the field MRES of the motor
|
||||||
record in the following manner:
|
record in the following manner:
|
||||||
- In sinq_asyn_motor.db, the PV (motor_record_pv_name)MOTOR_REC_RESOLUTION is
|
- In sinq_asyn_motor.db, the PV (motor_record_pv_name)MOTOR_REC_RESOLUTION
|
||||||
defined as a copy of the field (motor_record_pv_name).MRES:
|
is defined as a copy of the field (motor_record_pv_name).MRES:
|
||||||
|
|
||||||
record(ao,"$(P)$(M):Resolution") {
|
record(ao,"$(P)$(M):Resolution") {
|
||||||
field(DESC, "$(M) resolution")
|
field(DESC, "$(M) resolution")
|
||||||
@ -121,27 +118,30 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving)
|
|||||||
field(PREC, "$(PREC)")
|
field(PREC, "$(PREC)")
|
||||||
}
|
}
|
||||||
|
|
||||||
- The PV name MOTOR_REC_RESOLUTION is coupled in asynMotorController.h to the constant motorRecResolutionString
|
- The PV name MOTOR_REC_RESOLUTION is coupled in asynMotorController.h to
|
||||||
- ... which in turn is assigned to motorRecResolution_ in asynMotorController.cpp
|
the constant motorRecResolutionString
|
||||||
This way of making the field visible to the driver is described here: https://epics.anl.gov/tech-talk/2020/msg00378.php
|
- ... which in turn is assigned to motorRecResolution_ in
|
||||||
This is a one-way coupling, changes to the parameter library via setDoubleParam
|
asynMotorController.cpp This way of making the field visible to the driver
|
||||||
are NOT transferred to (motor_record_pv_name).MRES or to (motor_record_pv_name):Resolution.
|
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
|
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
|
save the read result to the member variable earlier), since the parameter
|
||||||
is updated at a later stage!
|
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
|
We know that the motor resolution must not be zero. During the startup of
|
||||||
IOC, polls can happen before the record is fully initialized. In that case,
|
the IOC, polls can happen before the record is fully initialized. In that
|
||||||
all values are zero.
|
case, all values are zero.
|
||||||
*/
|
*/
|
||||||
if (motorRecResolution_ == 0)
|
if (motorRecResolution_ == 0) {
|
||||||
{
|
|
||||||
return asynError;
|
return asynError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,11 +154,11 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving)
|
|||||||
*/
|
*/
|
||||||
setIntegerParam(pC_->motorStatusProblem_, false);
|
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_);
|
snprintf(command, pC_->C804_MAXBUF_ - 1, "%dTE", axisNo_);
|
||||||
status = pC_->lowLevelWriteRead(axisNo_, command, response, true);
|
status = pC_->lowLevelWriteRead(axisNo_, command, response, true);
|
||||||
if (status == asynSuccess)
|
if (status == asynSuccess) {
|
||||||
{
|
|
||||||
int parsed_axis;
|
int parsed_axis;
|
||||||
sscanf(response, "%2dE%10d", &parsed_axis, &position_error_steps);
|
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_;
|
position_error = double(position_error_steps) * motorRecResolution_;
|
||||||
|
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||||
"%s: Axis %d, response %s, position error %f\n", functionName, axisNo_, response, position_error);
|
"%s: Axis %d, response %s, position error %f\n", functionName,
|
||||||
}
|
axisNo_, response, position_error);
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
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);
|
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||||
|
|
||||||
// Stop the evaluation prematurely
|
// Stop the evaluation prematurely
|
||||||
@ -180,9 +180,9 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving)
|
|||||||
|
|
||||||
// Read the current position.
|
// Read the current position.
|
||||||
snprintf(command, this->pC_->C804_MAXBUF_ - 1, "%dTP", this->axisNo_);
|
snprintf(command, this->pC_->C804_MAXBUF_ - 1, "%dTP", this->axisNo_);
|
||||||
status = this->pC_->lowLevelWriteRead(this->axisNo_, command, response, true);
|
status =
|
||||||
if (status == asynSuccess)
|
this->pC_->lowLevelWriteRead(this->axisNo_, command, response, true);
|
||||||
{
|
if (status == asynSuccess) {
|
||||||
int parsed_axis;
|
int parsed_axis;
|
||||||
sscanf(response, "%2dP%10d", &parsed_axis, &motor_position_steps);
|
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_;
|
motor_position = double(motor_position_steps) * motorRecResolution_;
|
||||||
|
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
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_->motorPosition_, motor_position);
|
||||||
setDoubleParam(pC_->motorEncoderPosition_, motor_position);
|
setDoubleParam(pC_->motorEncoderPosition_, motor_position);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
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);
|
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -205,9 +205,9 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving)
|
|||||||
|
|
||||||
// Read the current velocity
|
// Read the current velocity
|
||||||
snprintf(command, this->pC_->C804_MAXBUF_ - 1, "%dTV", this->axisNo_);
|
snprintf(command, this->pC_->C804_MAXBUF_ - 1, "%dTV", this->axisNo_);
|
||||||
status = this->pC_->lowLevelWriteRead(this->axisNo_, command, response, true);
|
status =
|
||||||
if (status == asynSuccess)
|
this->pC_->lowLevelWriteRead(this->axisNo_, command, response, true);
|
||||||
{
|
if (status == asynSuccess) {
|
||||||
int parsed_axis;
|
int parsed_axis;
|
||||||
sscanf(response, "%2dV%10d", &parsed_axis, &motor_velocity_steps);
|
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_;
|
motor_velocity = double(motor_velocity_steps) * motorRecResolution_;
|
||||||
|
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||||
"%s: Axis %d, response %s, velocity %f\n", functionName, axisNo_, response, motor_velocity);
|
"%s: Axis %d, response %s, velocity %f\n", functionName,
|
||||||
}
|
axisNo_, response, motor_velocity);
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
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);
|
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -228,23 +228,25 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving)
|
|||||||
|
|
||||||
// Read the programmed velocity
|
// Read the programmed velocity
|
||||||
snprintf(command, this->pC_->C804_MAXBUF_ - 1, "%dTY", this->axisNo_);
|
snprintf(command, this->pC_->C804_MAXBUF_ - 1, "%dTY", this->axisNo_);
|
||||||
status = this->pC_->lowLevelWriteRead(this->axisNo_, command, response, true);
|
status =
|
||||||
if (status == asynSuccess)
|
this->pC_->lowLevelWriteRead(this->axisNo_, command, response, true);
|
||||||
{
|
if (status == asynSuccess) {
|
||||||
|
|
||||||
int parsed_axis;
|
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
|
// 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,
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||||
"%s: Axis %d, response %s, programmed velocity %f\n", functionName, axisNo_, response, programmed_motor_velocity);
|
"%s: Axis %d, response %s, programmed velocity %f\n",
|
||||||
}
|
functionName, axisNo_, response, programmed_motor_velocity);
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
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);
|
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -253,15 +255,13 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving)
|
|||||||
// Read the motor status
|
// Read the motor status
|
||||||
snprintf(command, pC_->C804_MAXBUF_ - 1, "%dTS", axisNo_);
|
snprintf(command, pC_->C804_MAXBUF_ - 1, "%dTS", axisNo_);
|
||||||
status = pC_->lowLevelWriteRead(this->axisNo_, command, response, true);
|
status = pC_->lowLevelWriteRead(this->axisNo_, command, response, true);
|
||||||
if (status == asynSuccess)
|
if (status == asynSuccess) {
|
||||||
{
|
|
||||||
int parsed_axis;
|
int parsed_axis;
|
||||||
sscanf(response, "%2dS%10d", &parsed_axis, &axis_status);
|
sscanf(response, "%2dS%10d", &parsed_axis, &axis_status);
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||||
"%s: Axis %d, response %s, status %d\n", functionName, axisNo_, response, axis_status);
|
"%s: Axis %d, response %s, status %d\n", functionName,
|
||||||
}
|
axisNo_, response, axis_status);
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
"%s: Reading the motor status %d\n", functionName, axisNo_);
|
"%s: Reading the motor status %d\n", functionName, axisNo_);
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||||
@ -270,24 +270,22 @@ asynStatus C804Axis::poll_no_param_lib_update(bool *moving)
|
|||||||
return status;
|
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 mask = 1 << 2;
|
||||||
int masked_n = axis_status & mask;
|
int masked_n = axis_status & mask;
|
||||||
// Is 1 if the axis is disabled
|
// Is 1 if the axis is disabled
|
||||||
int disabled = masked_n >> 2;
|
int disabled = masked_n >> 2;
|
||||||
if (disabled)
|
if (disabled) {
|
||||||
{
|
|
||||||
enabled_ = false;
|
enabled_ = false;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
enabled_ = true;
|
enabled_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Determine if the motor is moving. This is determined by the following criteria:
|
Determine if the motor is moving. This is determined by the following
|
||||||
1) The motor position changes from poll to poll
|
criteria: 1) The motor position changes from poll to poll 2) The motor is
|
||||||
2) The motor is enabled
|
enabled
|
||||||
*/
|
*/
|
||||||
*moving = enabled_ && motor_position_steps != this->last_position_steps_;
|
*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
|
moving. If it has spent too much time in a moving state without reaching
|
||||||
the target, stop the motor and return an error.
|
the target, stop the motor and return an error.
|
||||||
*/
|
*/
|
||||||
if (*moving)
|
if (*moving) {
|
||||||
{
|
|
||||||
|
|
||||||
int motorStatusMoving = 0;
|
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
|
// motor is moving, but didn't move in the last poll
|
||||||
if (motorStatusMoving == 0)
|
if (motorStatusMoving == 0) {
|
||||||
{
|
|
||||||
time_t current_time = time(NULL);
|
time_t current_time = time(NULL);
|
||||||
|
|
||||||
// Factor 2 of the calculated moving time
|
// Factor 2 of the calculated moving time
|
||||||
estimatedArrivalTime_ = current_time + std::ceil(2 * std::fabs(position_error) / programmed_motor_velocity);
|
estimatedArrivalTime_ =
|
||||||
}
|
current_time + std::ceil(2 * std::fabs(position_error) /
|
||||||
else
|
programmed_motor_velocity);
|
||||||
{
|
} else {
|
||||||
// /*
|
// /*
|
||||||
// Motor is moving for a longer time than it should: Stop it
|
// 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_);
|
// snprintf(command, pC_->C804_MAXBUF_ - 1, "%dST", axisNo_);
|
||||||
// status = pC_->lowLevelWriteRead(axisNo_, command, response);
|
// 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;
|
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;
|
asynStatus status;
|
||||||
static const char *functionName = "C804Axis::move";
|
static const char *functionName = "C804Axis::move";
|
||||||
char command[pC_->C804_MAXBUF_], response[pC_->C804_MAXBUF_];
|
char command[pC_->C804_MAXBUF_], response[pC_->C804_MAXBUF_];
|
||||||
double position_c_units = 0.0; // Controller units
|
double position_c_units = 0.0; // Controller units
|
||||||
int position_steps = 0;
|
int position_steps = 0;
|
||||||
|
|
||||||
// Convert from user coordinates (EGU) to controller coordinates (steps). Check for overflow
|
// Convert from user coordinates (EGU) to controller coordinates (steps).
|
||||||
if (motorRecResolution_ == 0.0)
|
// Check for overflow
|
||||||
{
|
if (motorRecResolution_ == 0.0) {
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: MRES must not be zero. Movement is aborted", functionName);
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
|
"%s: MRES must not be zero. Movement is aborted",
|
||||||
|
functionName);
|
||||||
return asynError;
|
return asynError;
|
||||||
}
|
}
|
||||||
position_c_units = position / motorRecResolution_;
|
position_c_units = position / motorRecResolution_;
|
||||||
|
|
||||||
// Check for overflow during the division
|
// Check for overflow during the division
|
||||||
if (position_c_units * motorRecResolution_ != position)
|
if (position_c_units * motorRecResolution_ != position) {
|
||||||
{
|
asynPrint(
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
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.",
|
"%s: could not convert from user units (%f) to controller units "
|
||||||
|
"(user units divided by resolution MRES %f) due to overflow.",
|
||||||
functionName, position, motorRecResolution_);
|
functionName, position, motorRecResolution_);
|
||||||
return asynError;
|
return asynError;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Steps can only be integer values => cast to integer while checking for overflow
|
// Steps can only be integer values => cast to integer while checking for
|
||||||
if (std::numeric_limits<int>::max() < position_c_units || std::numeric_limits<int>::min() > position_c_units)
|
// overflow
|
||||||
{
|
if (std::numeric_limits<int>::max() < position_c_units ||
|
||||||
|
std::numeric_limits<int>::min() > position_c_units) {
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
"%s: target position %f cannot be converted to int (overflow). Check target value %f and MRES %f",
|
"%s: target position %f cannot be converted to int "
|
||||||
functionName, position_c_units, position_c_units, motorRecResolution_);
|
"(overflow). Check target value %f and MRES %f",
|
||||||
|
functionName, position_c_units, position_c_units,
|
||||||
|
motorRecResolution_);
|
||||||
return asynError;
|
return asynError;
|
||||||
}
|
}
|
||||||
position_steps = static_cast<int>(position_c_units);
|
position_steps = static_cast<int>(position_c_units);
|
||||||
|
|
||||||
// Convert from relative to absolute values
|
// Convert from relative to absolute values
|
||||||
if (relative)
|
if (relative) {
|
||||||
{
|
|
||||||
position_steps += last_position_steps_;
|
position_steps += last_position_steps_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the axis is currently disabled, enable it
|
// If the axis is currently disabled, enable it
|
||||||
if (!enabled_)
|
if (!enabled_) {
|
||||||
{
|
|
||||||
snprintf(command, pC_->C804_MAXBUF_ - 1, "%dGO", axisNo_);
|
snprintf(command, pC_->C804_MAXBUF_ - 1, "%dGO", axisNo_);
|
||||||
status = pC_->lowLevelWriteRead(this->axisNo_, command, response, false);
|
status =
|
||||||
if (status != asynSuccess)
|
pC_->lowLevelWriteRead(this->axisNo_, command, response, false);
|
||||||
{
|
if (status != asynSuccess) {
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
"%s: Enabling axis %d\n failed", functionName, axisNo_);
|
"%s: Enabling axis %d\n failed", functionName, axisNo_);
|
||||||
return status;
|
return status;
|
||||||
@ -396,10 +399,10 @@ asynStatus C804Axis::move(double position, int relative, double minVelocity, dou
|
|||||||
// Start movement
|
// Start movement
|
||||||
snprintf(command, pC_->C804_MAXBUF_ - 1, "%dMA%d", axisNo_, position_steps);
|
snprintf(command, pC_->C804_MAXBUF_ - 1, "%dMA%d", axisNo_, position_steps);
|
||||||
status = pC_->lowLevelWriteRead(this->axisNo_, command, response, false);
|
status = pC_->lowLevelWriteRead(this->axisNo_, command, response, false);
|
||||||
if (status != asynSuccess)
|
if (status != asynSuccess) {
|
||||||
{
|
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
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);
|
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -411,14 +414,13 @@ asynStatus C804Axis::move(double position, int relative, double minVelocity, dou
|
|||||||
return status;
|
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";
|
static const char *functionName = "C804Axis::moveVelocity";
|
||||||
return asynError;
|
return asynError;
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus C804Axis::stop(double acceleration)
|
asynStatus C804Axis::stop(double acceleration) {
|
||||||
{
|
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
static const char *functionName = "C804Axis::stop";
|
static const char *functionName = "C804Axis::stop";
|
||||||
char command[pC_->C804_MAXBUF_], response[pC_->C804_MAXBUF_];
|
char command[pC_->C804_MAXBUF_], response[pC_->C804_MAXBUF_];
|
||||||
@ -426,26 +428,28 @@ asynStatus C804Axis::stop(double acceleration)
|
|||||||
bool moving = false;
|
bool moving = false;
|
||||||
|
|
||||||
poll(&moving);
|
poll(&moving);
|
||||||
if (moving)
|
if (moving) {
|
||||||
{
|
|
||||||
// ST = Stop
|
// ST = Stop
|
||||||
snprintf(command, pC_->C804_MAXBUF_ - 1, "%dST", axisNo_);
|
snprintf(command, pC_->C804_MAXBUF_ - 1, "%dST", axisNo_);
|
||||||
status = pC_->lowLevelWriteRead(axisNo_, command, response, false);
|
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;
|
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;
|
asynStatus status = asynSuccess;
|
||||||
static const char *functionName = "C804Axis::home";
|
static const char *functionName = "C804Axis::home";
|
||||||
char command[pC_->C804_MAXBUF_], response[pC_->C804_MAXBUF_];
|
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);
|
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;
|
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.
|
If on is 0, disable the motor, otherwise enable it.
|
||||||
*/
|
*/
|
||||||
asynStatus C804Axis::enable(int on)
|
asynStatus C804Axis::enable(int on) {
|
||||||
{
|
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
static const char *functionName = "C804Axis::enable";
|
static const char *functionName = "C804Axis::enable";
|
||||||
char command[pC_->C804_MAXBUF_], response[pC_->C804_MAXBUF_];
|
char command[pC_->C804_MAXBUF_], response[pC_->C804_MAXBUF_];
|
||||||
|
|
||||||
if (on == 0)
|
if (on == 0) {
|
||||||
{
|
|
||||||
snprintf(command, pC_->C804_MAXBUF_ - 1, "%dMF", axisNo_);
|
snprintf(command, pC_->C804_MAXBUF_ - 1, "%dMF", axisNo_);
|
||||||
status = pC_->lowLevelWriteRead(axisNo_, command, response, false);
|
status = pC_->lowLevelWriteRead(axisNo_, command, response, false);
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACEIO_DEVICE, "%s: Disable axis %d\n", functionName, axisNo_);
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACEIO_DEVICE,
|
||||||
}
|
"%s: Disable axis %d\n", functionName, axisNo_);
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
snprintf(command, pC_->C804_MAXBUF_ - 1, "%dMN", axisNo_);
|
snprintf(command, pC_->C804_MAXBUF_ - 1, "%dMN", axisNo_);
|
||||||
status = pC_->lowLevelWriteRead(axisNo_, command, response, false);
|
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;
|
return status;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user