Now using tolerance to compensate for backlash instead of the CLSLOOP code.

Added convenience function to get acceleration and speed from the controller.

r1025 | ffr | 2006-07-13 14:46:41 +1000 (Thu, 13 Jul 2006) | 3 lines
This commit is contained in:
Ferdi Franceschini
2006-07-13 14:46:41 +10:00
committed by Douglas Clowes
parent cb5b6e704e
commit d72d0b9905

View File

@@ -45,6 +45,12 @@ void KillRS232(/*@only@*/ void *pData);
/* The pointer to the Tcl interpreter is owned by SICS and should not be modified */ /* The pointer to the Tcl interpreter is owned by SICS and should not be modified */
/*@observer@*//*@dependent@*/ Tcl_Interp *InterpGetTcl(SicsInterp *pSics); /*@observer@*//*@dependent@*/ Tcl_Interp *InterpGetTcl(SicsInterp *pSics);
/*@+incondefs@*/ /*@+incondefs@*/
/** \brief Used to ensure that the getDMCSetting function is called
* with valid values.
* \see getDMCSetting
*/
enum dmcsetting {dmcspeed, dmcacceleration, dmcdeceleration};
/*----------------------------------------------------------------------- /*-----------------------------------------------------------------------
The motor driver structure. Please note that the first set of fields has The motor driver structure. Please note that the first set of fields has
be identical with the fields of AbstractModriv in ../modriv.h be identical with the fields of AbstractModriv in ../modriv.h
@@ -91,6 +97,7 @@ typedef struct __MoDriv {
int abs_endcoder; /**< Flag = 1 if there is an abs enc */ int abs_endcoder; /**< Flag = 1 if there is an abs enc */
int absEncHome; /**< Home position in counts for abs enc */ int absEncHome; /**< Home position in counts for abs enc */
int cntsPerX; /**< absolute encoder counts per physical unit */ int cntsPerX; /**< absolute encoder counts per physical unit */
int motOffDelay; /**< number of msec to wait before switching motor off, default=0 */
} DMC2280Driv, *pDMC2280Driv; } DMC2280Driv, *pDMC2280Driv;
/*------------------- error codes ----------------------------------*/ /*------------------- error codes ----------------------------------*/
#define BADADR -1 // NOT SET: Unknown host/port? #define BADADR -1 // NOT SET: Unknown host/port?
@@ -136,39 +143,44 @@ typedef struct __MoDriv {
#define DECEL "decel" #define DECEL "decel"
#define MAXDECEL "maxDecel" #define MAXDECEL "maxDecel"
static int DMC2280SetPar(void *pData, SConnection *pCon,
char *name, float newValue);
static int DMC2280Receive(pDMC2280Driv self, /*@out@*/ char *reply); static int DMC2280Receive(pDMC2280Driv self, /*@out@*/ char *reply);
/** \brief Convert motor speed from physical units to steps/sec /** \brief Convert axis speed in physical units to
* motor speed in steps/sec.
* \param self (r) provides access to the motor's data structure * \param self (r) provides access to the motor's data structure
* \param speed in physical units, eg mm/sec degrees/sec * \param speed in physical units, eg mm/sec degrees/sec
* \return the speed in motor steps/sec * \return the speed in motor steps/sec
*/ */
static int motSpeed(pDMC2280Driv self, float speed) { static int motSpeed(pDMC2280Driv self, float axisSpeed) {
int motSpeed; int speed;
motSpeed = abs((int)(speed * self->stepsPerX + 0.5)); speed = abs((int)(axisSpeed * self->stepsPerX + 0.5));
return motSpeed; return speed;
} }
/** \brief Convert motor acceleration from physical units to steps/sec^2 /** \brief Convert axis acceleration in physical units to
* to motor speed in steps/sec^2
* \param self (r) provides access to the motor's data structure * \param self (r) provides access to the motor's data structure
* \param acceleration in physical units, eg mm/sec^2 degrees/sec^2 * \param acceleration in physical units, eg mm/sec^2 degrees/sec^2
* \return the acceleration in motor steps/sec^2 * \return the acceleration in motor steps/sec^2
*/ */
static int motAccel(pDMC2280Driv self, float accel) { static int motAccel(pDMC2280Driv self, float axisAccel) {
int motAccel; int accel;
motAccel = abs((int)(accel * self->stepsPerX + 0.5)); accel = abs((int)(axisAccel * self->stepsPerX + 0.5));
return motAccel; return accel;
} }
/** \brief Convert motor deceleration from physical units to steps/sec^2 /** \brief Convert axis deceleration in physical units to
* motor deceleration in steps/sec^2
* \param self (r) provides access to the motor's data structure * \param self (r) provides access to the motor's data structure
* \param deceleration in physical units, eg mm/sec^2 degrees/sec^2 * \param deceleration in physical units, eg mm/sec^2 degrees/sec^2
* \return the deceleration in motor steps/sec^2 * \return the deceleration in motor steps/sec^2
*/ */
static int motDecel(pDMC2280Driv self, float decel) { static int motDecel(pDMC2280Driv self, float axisDecel) {
int motDecel; int decel;
motDecel = abs((int)(decel * self->stepsPerX + 0.5)); decel = abs((int)(axisDecel * self->stepsPerX + 0.5));
return motDecel; return decel;
} }
/** \brief Reads a single character from the DMC2280 controller. /** \brief Reads a single character from the DMC2280 controller.
@@ -296,6 +308,71 @@ static int DMC2280Receive(pDMC2280Driv self, /*@out@*/char *reply) {
return FAILURE; return FAILURE;
} }
/**\brief Convenience function for getting speed, acceleration
* or deceleration
*
* \param *pData provides access to a motor's data
* \param cmdIndex selects value to request from controller.
* \return Either speed acceleration or deceleration as requested.
* \see dmcsetting getMotSpeed getMotAccel getMotDecel
*/
static int getDMCSetting(void *pData, enum dmcsetting cmdIndex){
pDMC2280Driv self = NULL;
char cmd[CMDLEN], reply[256];
int dmcSetting;
self = (pDMC2280Driv)pData;
switch (cmdIndex) {
case dmcspeed:
snprintf(cmd, CMDLEN, "MG _SP%c", self->axisLabel);
break;
case dmcacceleration:
snprintf(cmd, CMDLEN, "MG _AC%c", self->axisLabel);
break;
case dmcdeceleration:
snprintf(cmd, CMDLEN, "MG _DC%c", self->axisLabel);
}
if (FAILURE == DMC2280Send(self, cmd))
return HWFault;
if (FAILURE == DMC2280Receive(self, reply))
return HWFault;
dmcSetting =atoi(reply);
return dmcSetting;
}
/** \brief Call this to make sure that the speed,
* acceleration and deceleration are set to the correct value.\n
* XXX Unused: This will interfere with progs running on the
* controller like #LIMSWI which sets maximum deceleration when a
* limit switch is hit.
*/
/*@unused@*/static void ckSpeedAccelDecel(pDMC2280Driv self) {
int motSetting;
char cmd[CMDLEN];
motSetting = getDMCSetting(self, dmcspeed);
/* Reset speed if it has been changed externally */
if (motSetting != motSpeed(self, self->speed)) {
snprintf(cmd,CMDLEN,"SP%c=%d", self->axisLabel, motSpeed(self,self->speed));
DMC2280Send(self, cmd);
}
/* Reset acceleration if it has been changed externally */
motSetting = getDMCSetting(self, dmcacceleration);
if (motSetting != motAccel(self, self->accel)) {
snprintf(cmd,CMDLEN,"AC%c=%d", self->axisLabel, motAccel(self,self->accel));
DMC2280Send(self, cmd);
}
/* Reset deceleration if it has been changed externally */
motSetting = getDMCSetting(self, dmcdeceleration);
if (motSetting != motDecel(self, self->decel)) {
snprintf(cmd,CMDLEN,"DC%c=%d", self->axisLabel, motDecel(self,self->decel));
DMC2280Send(self, cmd);
}
}
/** \brief Reads motor position, implements the GetPosition /** \brief Reads motor position, implements the GetPosition
* method in the MotorDriver interface. * method in the MotorDriver interface.
* *
@@ -368,9 +445,11 @@ static int DMC2280Run(void *pData,float fValue){
snprintf(cmd, CMDLEN, "DP%c=(_TP%c - %d)*(%d/%d) + %d",axis,axis,absEncHome,stepsPerX,cntsPerX,motorHome); snprintf(cmd, CMDLEN, "DP%c=(_TP%c - %d)*(%d/%d) + %d",axis,axis,absEncHome,stepsPerX,cntsPerX,motorHome);
if (FAILURE == DMC2280Send(self, cmd)) if (FAILURE == DMC2280Send(self, cmd))
return HWFault; return HWFault;
#ifdef BACKLASHFIX
snprintf(cmd, CMDLEN, "%cQTARGET=%d", axis, (int) (target * cntsPerX + absEncHome + 0.5)); snprintf(cmd, CMDLEN, "%cQTARGET=%d", axis, (int) (target * cntsPerX + absEncHome + 0.5));
if (FAILURE == DMC2280Send(self, cmd)) if (FAILURE == DMC2280Send(self, cmd))
return HWFault; return HWFault;
#endif
} }
if (FAILURE == DMC2280Send(self, absPosCmd)) if (FAILURE == DMC2280Send(self, absPosCmd))
@@ -398,13 +477,18 @@ static int DMC2280Status(void *pData){
pDMC2280Driv self = NULL; pDMC2280Driv self = NULL;
char cmd[CMDLEN]; char cmd[CMDLEN];
int switches; int switches;
char switchesAscii[10], reply[256]; char switchesAscii[10];
bool moving, fwd_limit_active, rvrs_limit_active, errorlimit; #ifdef BACKLASHFIX
char reply[256];
int SERVO_LOOP_NOT_RUNNING = -1, servoLoopStatus; int SERVO_LOOP_NOT_RUNNING = -1, servoLoopStatus;
int SHOULD_FIXPOS=1, should_fixpos; int SHOULD_FIXPOS=1, should_fixpos;
#endif
bool moving, fwd_limit_active, rvrs_limit_active, errorlimit;
self = (pDMC2280Driv)pData; self = (pDMC2280Driv)pData;
assert(self != NULL); assert(self != NULL);
/* Make sure that speed, accel and decel are set correctly */
/* ckSpeedAccelDecel(self); */
/* Get status of switches /* Get status of switches
* see TS (Tell Switches) in Galil manc2xx.pdf */ * see TS (Tell Switches) in Galil manc2xx.pdf */
snprintf(cmd, CMDLEN, "TS%c", self->axisLabel); snprintf(cmd, CMDLEN, "TS%c", self->axisLabel);
@@ -437,6 +521,7 @@ static int DMC2280Status(void *pData){
self->errorCode = ERRORLIM; self->errorCode = ERRORLIM;
return HWFault; return HWFault;
} }
#ifdef BACKLASHFIX
if (self->abs_endcoder == 1) { if (self->abs_endcoder == 1) {
/* Make sure that the servo loop is closed by checking if /* Make sure that the servo loop is closed by checking if
* the CLSLOOP thread is running on the controller.*/ * the CLSLOOP thread is running on the controller.*/
@@ -464,8 +549,13 @@ static int DMC2280Status(void *pData){
return HWBusy; return HWBusy;
} }
} }
#endif
if (self->noPowerSave == _SAVEPOWER) { if (self->noPowerSave == _SAVEPOWER) {
snprintf(cmd, CMDLEN, "MO%c", self->axisLabel); if (self->motOffDelay > 0 ) {
snprintf(cmd, CMDLEN, "AT %d; MO%c", self->motOffDelay, self->axisLabel);
} else {
snprintf(cmd, CMDLEN, "MO%c", self->axisLabel);
}
DMC2280Send(self, cmd); DMC2280Send(self, cmd);
} }
return HWIdle; return HWIdle;
@@ -594,11 +684,20 @@ static int DMC2280Halt(void *pData){
return 1; return 1;
} }
/** \brief Fetches the value of the named parameter, /** \brief Fetches the value of the named parameter,
* implements the GetDriverPar method in the MotorDriver interface. * implements the GetDriverPar method in the MotorDriver interface.
* *
* Note: The GetDriverPar method in the MotorDriver interface only * Note: The GetDriverPar method in the MotorDriver interface only
* allows float values to be returned. * allows float values to be returned.
*
* If the speed, acceleration or deceleration is requested then
* this compares the setting on the controller to the required setting,
* if they don't match then the controller is set to the required value.
*
* Note: Doesn't warn if the speed, acceleration, or deceleration set on
* the controller differ from the required settings.
*
* \param *pData (r) provides access to a motor's data * \param *pData (r) provides access to a motor's data
* \param *name (r) the name of the parameter to fetch. * \param *name (r) the name of the parameter to fetch.
* \param *fValue (w) the parameter's value. * \param *fValue (w) the parameter's value.
@@ -867,6 +966,12 @@ static void KillDMC2280(/*@only@*/void *pData){
* \param *motor (r) motor name * \param *motor (r) motor name
* \param *params (r) configuration parameter array. * \param *params (r) configuration parameter array.
* \return a reference to Motordriver structure * \return a reference to Motordriver structure
*
* NOTES:\n
* -Adding parameters
* - Add a field for the parameter to the DMC2280Driv struct
* - Get the parameter from the parameter array, see PARAMETERS: below
* - If the parameter requires an abs enc then add it after ABSENC:
*/ */
/*@only@*//*@null@*/ MotorDriver *CreateDMC2280(/*@observer@*/SConnection *pCon, /*@observer@*/char *motor, /*@observer@*/char *params){ /*@only@*//*@null@*/ MotorDriver *CreateDMC2280(/*@observer@*/SConnection *pCon, /*@observer@*/char *motor, /*@observer@*/char *params){
pDMC2280Driv pNew = NULL; pDMC2280Driv pNew = NULL;
@@ -940,6 +1045,8 @@ static void KillDMC2280(/*@only@*/void *pData){
pNew->SetDriverPar = DMC2280SetPar; pNew->SetDriverPar = DMC2280SetPar;
pNew->ListDriverPar = DMC2280List; pNew->ListDriverPar = DMC2280List;
pNew->KillPrivate = KillDMC2280; pNew->KillPrivate = KillDMC2280;
/* PARAMETERS: Fetch parameter values */
if ((pPtr=getParam(pCon, interp, params,UNITS,_REQUIRED)) == NULL) { if ((pPtr=getParam(pCon, interp, params,UNITS,_REQUIRED)) == NULL) {
KillDMC2280(pNew); KillDMC2280(pNew);
return NULL; return NULL;
@@ -981,6 +1088,12 @@ static void KillDMC2280(/*@only@*/void *pData){
pNew->noPowerSave=_SAVEPOWER; pNew->noPowerSave=_SAVEPOWER;
else else
sscanf(pPtr,"%d",&(pNew->noPowerSave)); sscanf(pPtr,"%d",&(pNew->noPowerSave));
if ((pPtr=getParam(pCon, interp, params,"motOffDelay",_OPTIONAL)) == NULL)
pNew->motOffDelay=0;
else
sscanf(pPtr,"%d",&(pNew->motOffDelay));
/* ABSENC: If the parameter requires an abs enc add it to the else block */
if ((pPtr=getParam(pCon, interp, params,"absEnc",_OPTIONAL)) == NULL) if ((pPtr=getParam(pCon, interp, params,"absEnc",_OPTIONAL)) == NULL)
pNew->abs_endcoder=0; pNew->abs_endcoder=0;
else { else {