Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

emcstepmot.c File Reference

#include "_timer.h"
#include "_shm.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <string.h>
#include "posemath.h"
#include "emcpos.h"
#include "emcmotcfg.h"
#include "emcmotglb.h"
#include "emcmot.h"
#include "pid.h"
#include "cubic.h"
#include "tc.h"
#include "tp.h"
#include "extintf.h"
#include "mmxavg.h"
#include "emcmotlog.h"
#include <signal.h>

Include dependency graph for emcstepmot.c:

Include dependency graph

Go to the source code of this file.

Defines

#define LIMIT_SWITCH_DEBOUNCE   10
#define AMP_FAULT_DEBOUNCE   100
#define diagnostics   printf
#define GET_MOTION_ERROR_FLAG()   (emcmotStatus->motionFlag & EMCMOT_MOTION_ERROR_BIT ? 1 : 0)
#define SET_MOTION_ERROR_FLAG(fl)   if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_ERROR_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_ERROR_BIT;
#define GET_MOTION_COORD_FLAG()   (emcmotStatus->motionFlag & EMCMOT_MOTION_COORD_BIT ? 1 : 0)
#define SET_MOTION_COORD_FLAG(fl)   if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_COORD_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_COORD_BIT;
#define GET_MOTION_INPOS_FLAG()   (emcmotStatus->motionFlag & EMCMOT_MOTION_INPOS_BIT ? 1 : 0)
#define SET_MOTION_INPOS_FLAG(fl)   if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_INPOS_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_INPOS_BIT;
#define GET_MOTION_ENABLE_FLAG()   (emcmotStatus->motionFlag & EMCMOT_MOTION_ENABLE_BIT ? 1 : 0)
#define SET_MOTION_ENABLE_FLAG(fl)   if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_ENABLE_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_ENABLE_BIT;
#define GET_AXIS_ENABLE_FLAG(ax)   (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_ENABLE_BIT ? 1 : 0)
#define SET_AXIS_ENABLE_FLAG(ax, fl)   if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_ENABLE_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_ENABLE_BIT;
#define GET_AXIS_ACTIVE_FLAG(ax)   (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_ACTIVE_BIT ? 1 : 0)
#define SET_AXIS_ACTIVE_FLAG(ax, fl)   if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_ACTIVE_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_ACTIVE_BIT;
#define GET_AXIS_INPOS_FLAG(ax)   (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_INPOS_BIT ? 1 : 0)
#define SET_AXIS_INPOS_FLAG(ax, fl)   if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_INPOS_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_INPOS_BIT;
#define GET_AXIS_ERROR_FLAG(ax)   (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_ERROR_BIT ? 1 : 0)
#define SET_AXIS_ERROR_FLAG(ax, fl)   if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_ERROR_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_ERROR_BIT;
#define GET_AXIS_PSL_FLAG(ax)   (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MAX_SOFT_LIMIT_BIT ? 1 : 0)
#define SET_AXIS_PSL_FLAG(ax, fl)   if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_MAX_SOFT_LIMIT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_MAX_SOFT_LIMIT_BIT;
#define GET_AXIS_NSL_FLAG(ax)   (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MIN_SOFT_LIMIT_BIT ? 1 : 0)
#define SET_AXIS_NSL_FLAG(ax, fl)   if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_MIN_SOFT_LIMIT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_MIN_SOFT_LIMIT_BIT;
#define GET_AXIS_PHL_FLAG(ax)   (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MAX_HARD_LIMIT_BIT ? 1 : 0)
#define SET_AXIS_PHL_FLAG(ax, fl)   if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_MAX_HARD_LIMIT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_MAX_HARD_LIMIT_BIT;
#define GET_AXIS_NHL_FLAG(ax)   (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MIN_HARD_LIMIT_BIT ? 1 : 0)
#define SET_AXIS_NHL_FLAG(ax, fl)   if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_MIN_HARD_LIMIT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_MIN_HARD_LIMIT_BIT;
#define GET_AXIS_HOME_SWITCH_FLAG(ax)   (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_HOME_SWITCH_BIT ? 1 : 0)
#define SET_AXIS_HOME_SWITCH_FLAG(ax, fl)   if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_HOME_SWITCH_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_HOME_SWITCH_BIT;
#define GET_AXIS_HOMING_FLAG(ax)   (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_HOMING_BIT ? 1 : 0)
#define SET_AXIS_HOMING_FLAG(ax, fl)   if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_HOMING_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_HOMING_BIT;
#define GET_AXIS_HOMED_FLAG(ax)   (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_HOMED_BIT ? 1 : 0)
#define SET_AXIS_HOMED_FLAG(ax, fl)   if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_HOMED_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_HOMED_BIT;
#define GET_AXIS_FERROR_FLAG(ax)   (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_FERROR_BIT ? 1 : 0)
#define SET_AXIS_FERROR_FLAG(ax, fl)   if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_FERROR_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_FERROR_BIT;
#define GET_AXIS_FAULT_FLAG(ax)   (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_FAULT_BIT ? 1 : 0)
#define SET_AXIS_FAULT_FLAG(ax, fl)   if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_FAULT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_FAULT_BIT;
#define GET_AXIS_ENABLE_POLARITY(ax)   (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_ENABLE_BIT ? 1 : 0)
#define SET_AXIS_ENABLE_POLARITY(ax, fl)   if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_ENABLE_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_ENABLE_BIT;
#define GET_AXIS_PHL_POLARITY(ax)   (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_MAX_HARD_LIMIT_BIT ? 1 : 0)
#define SET_AXIS_PHL_POLARITY(ax, fl)   if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_MAX_HARD_LIMIT_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_MAX_HARD_LIMIT_BIT;
#define GET_AXIS_NHL_POLARITY(ax)   (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_MIN_HARD_LIMIT_BIT ? 1 : 0)
#define SET_AXIS_NHL_POLARITY(ax, fl)   if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_MIN_HARD_LIMIT_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_MIN_HARD_LIMIT_BIT;
#define GET_AXIS_HOME_SWITCH_POLARITY(ax)   (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_HOME_SWITCH_BIT ? 1 : 0)
#define SET_AXIS_HOME_SWITCH_POLARITY(ax, fl)   if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_HOME_SWITCH_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_HOME_SWITCH_BIT;
#define GET_AXIS_HOMING_POLARITY(ax)   (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_HOMING_BIT ? 1 : 0)
#define SET_AXIS_HOMING_POLARITY(ax, fl)   if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_HOMING_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_HOMING_BIT;
#define GET_AXIS_FAULT_POLARITY(ax)   (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_FAULT_BIT ? 1 : 0)
#define SET_AXIS_FAULT_POLARITY(ax, fl)   if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_FAULT_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_FAULT_BIT;
#define FREE_AXIS_QUEUE_SIZE   4
#define AXRANGE(axis)   ((emcmotConfig->maxLimit[axis] - emcmotConfig->minLimit[axis]))

Functions

char __attribute__ ((unused)) ident[]="$Id
void MARK_EMCMOT_CONFIG_CHANGE (void)
void reportError (const char *fmt,...)
int isHoming (void)
int inRange (EmcPose pos)
int checkLimits (void)
int checkJog (int axis, double vel)
void setTrajCycleTime (double secs)
void setServoCycleTime (double secs)
int emcmotCommandHandler (void)
void emcmotController (int arg)
int init_module (void)
void cleanup_module (void)
void emcmot_quit (int sig)
int getArgs (int argc, char *argv[])
int main (int argc, char *argv[])

Variables

EMCMOT_STRUCTemcmotStruct
shm_t * shmem = NULL
EMCMOT_COMMANDemcmotCommand
EMCMOT_STATUSemcmotStatus
EMCMOT_CONFIGemcmotConfig
EMCMOT_DEBUGemcmotDebug
EMCMOT_ERRORemcmotError
EMCMOT_LOGemcmotLog
EMCMOT_COMPemcmotComp [EMCMOT_MAX_AXIS]
EMCMOT_LOG_STRUCT ls
int logSkip = 0
int loggingAxis = 0
int logIt = 0
int wdEnabling = 0
int wdEnabled = 0
int wdWait = 0
int wdCount = 0
unsigned char wdToggle = 0
unsigned char allHomed = 0
double jointHome [EMCMOT_MAX_AXIS]
EmcPose worldHome
KINEMATICS_FORWARD_FLAGS fflags = 0
KINEMATICS_INVERSE_FLAGS iflags = 0
int kinType = 0
int maxLimitSwitchCount [EMCMOT_MAX_AXIS]
int minLimitSwitchCount [EMCMOT_MAX_AXIS]
int ampFaultCount [EMCMOT_MAX_AXIS]
TP_STRUCT queue
TP_STRUCT freeAxis [EMCMOT_MAX_AXIS]
EmcPose freePose = {{0.0, 0.0, 0.0}, 0.0, 0.0, 0.0}
CUBIC_STRUCT cubic [EMCMOT_MAX_AXIS]
TC_STRUCT queueTcSpace [DEFAULT_TC_QUEUE_SIZE+10]
TC_STRUCT freeAxisTcSpace [EMCMOT_MAX_AXIS][FREE_AXIS_QUEUE_SIZE]
double rawInput [EMCMOT_MAX_AXIS]
double rawOutput [EMCMOT_MAX_AXIS]
double coarseJointPos [EMCMOT_MAX_AXIS]
double jointPos [EMCMOT_MAX_AXIS]
double jointVel [EMCMOT_MAX_AXIS]
double oldJointPos [EMCMOT_MAX_AXIS]
double oldInput [EMCMOT_MAX_AXIS]
double inverseInputScale [EMCMOT_MAX_AXIS]
double inverseOutputScale [EMCMOT_MAX_AXIS]
EmcPose oldPos
EmcPose oldVel
EmcPose newVel
EmcPose newAcc
double bigVel = 1.0
int waitingForLatch [EMCMOT_MAX_AXIS]
int latchFlag [EMCMOT_MAX_AXIS]
double saveLatch [EMCMOT_MAX_AXIS]
int enabling = 0
int coordinating = 0
int wasOnLimit = 0
int onLimit = 0
int overriding = 0
int stepping = 0
int idForStep = 0
int interpolationCounter = 0
int EMCMOT_NO_FORWARD_KINEMATICS = 0
int emcmot_done = 0


Define Documentation

#define AMP_FAULT_DEBOUNCE   100
 

Definition at line 487 of file emcstepmot.c.

#define AXRANGE axis       ((emcmotConfig->maxLimit[axis] - emcmotConfig->minLimit[axis]))
 

Definition at line 758 of file emcstepmot.c.

#define FREE_AXIS_QUEUE_SIZE   4
 

Definition at line 626 of file emcstepmot.c.

#define GET_AXIS_ACTIVE_FLAG ax       (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_ACTIVE_BIT ? 1 : 0)
 

Definition at line 537 of file emcstepmot.c.

#define GET_AXIS_ENABLE_FLAG ax       (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_ENABLE_BIT ? 1 : 0)
 

Definition at line 533 of file emcstepmot.c.

#define GET_AXIS_ENABLE_POLARITY ax       (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_ENABLE_BIT ? 1 : 0)
 

Definition at line 587 of file emcstepmot.c.

#define GET_AXIS_ERROR_FLAG ax       (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_ERROR_BIT ? 1 : 0)
 

Definition at line 545 of file emcstepmot.c.

#define GET_AXIS_FAULT_FLAG ax       (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_FAULT_BIT ? 1 : 0)
 

Definition at line 581 of file emcstepmot.c.

#define GET_AXIS_FAULT_POLARITY ax       (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_FAULT_BIT ? 1 : 0)
 

Definition at line 607 of file emcstepmot.c.

#define GET_AXIS_FERROR_FLAG ax       (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_FERROR_BIT ? 1 : 0)
 

Definition at line 577 of file emcstepmot.c.

#define GET_AXIS_HOMED_FLAG ax       (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_HOMED_BIT ? 1 : 0)
 

Definition at line 573 of file emcstepmot.c.

#define GET_AXIS_HOME_SWITCH_FLAG ax       (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_HOME_SWITCH_BIT ? 1 : 0)
 

Definition at line 565 of file emcstepmot.c.

#define GET_AXIS_HOME_SWITCH_POLARITY ax       (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_HOME_SWITCH_BIT ? 1 : 0)
 

Definition at line 599 of file emcstepmot.c.

#define GET_AXIS_HOMING_FLAG ax       (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_HOMING_BIT ? 1 : 0)
 

Definition at line 569 of file emcstepmot.c.

#define GET_AXIS_HOMING_POLARITY ax       (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_HOMING_BIT ? 1 : 0)
 

Definition at line 603 of file emcstepmot.c.

#define GET_AXIS_INPOS_FLAG ax       (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_INPOS_BIT ? 1 : 0)
 

Definition at line 541 of file emcstepmot.c.

#define GET_AXIS_NHL_FLAG ax       (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MIN_HARD_LIMIT_BIT ? 1 : 0)
 

Definition at line 561 of file emcstepmot.c.

#define GET_AXIS_NHL_POLARITY ax       (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_MIN_HARD_LIMIT_BIT ? 1 : 0)
 

Definition at line 595 of file emcstepmot.c.

#define GET_AXIS_NSL_FLAG ax       (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MIN_SOFT_LIMIT_BIT ? 1 : 0)
 

Definition at line 553 of file emcstepmot.c.

#define GET_AXIS_PHL_FLAG ax       (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MAX_HARD_LIMIT_BIT ? 1 : 0)
 

Definition at line 557 of file emcstepmot.c.

#define GET_AXIS_PHL_POLARITY ax       (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_MAX_HARD_LIMIT_BIT ? 1 : 0)
 

Definition at line 591 of file emcstepmot.c.

#define GET_AXIS_PSL_FLAG ax       (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MAX_SOFT_LIMIT_BIT ? 1 : 0)
 

Definition at line 549 of file emcstepmot.c.

 
#define GET_MOTION_COORD_FLAG      (emcmotStatus->motionFlag & EMCMOT_MOTION_COORD_BIT ? 1 : 0)
 

Definition at line 519 of file emcstepmot.c.

 
#define GET_MOTION_ENABLE_FLAG      (emcmotStatus->motionFlag & EMCMOT_MOTION_ENABLE_BIT ? 1 : 0)
 

Definition at line 527 of file emcstepmot.c.

 
#define GET_MOTION_ERROR_FLAG      (emcmotStatus->motionFlag & EMCMOT_MOTION_ERROR_BIT ? 1 : 0)
 

Definition at line 515 of file emcstepmot.c.

 
#define GET_MOTION_INPOS_FLAG      (emcmotStatus->motionFlag & EMCMOT_MOTION_INPOS_BIT ? 1 : 0)
 

Definition at line 523 of file emcstepmot.c.

#define LIMIT_SWITCH_DEBOUNCE   10
 

Definition at line 484 of file emcstepmot.c.

#define SET_AXIS_ACTIVE_FLAG ax,
fl       if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_ACTIVE_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_ACTIVE_BIT;
 

Definition at line 539 of file emcstepmot.c.

#define SET_AXIS_ENABLE_FLAG ax,
fl       if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_ENABLE_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_ENABLE_BIT;
 

Definition at line 535 of file emcstepmot.c.

#define SET_AXIS_ENABLE_POLARITY ax,
fl       if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_ENABLE_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_ENABLE_BIT;
 

Definition at line 589 of file emcstepmot.c.

#define SET_AXIS_ERROR_FLAG ax,
fl       if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_ERROR_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_ERROR_BIT;
 

Definition at line 547 of file emcstepmot.c.

#define SET_AXIS_FAULT_FLAG ax,
fl       if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_FAULT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_FAULT_BIT;
 

Definition at line 583 of file emcstepmot.c.

#define SET_AXIS_FAULT_POLARITY ax,
fl       if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_FAULT_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_FAULT_BIT;
 

Definition at line 609 of file emcstepmot.c.

#define SET_AXIS_FERROR_FLAG ax,
fl       if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_FERROR_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_FERROR_BIT;
 

Definition at line 579 of file emcstepmot.c.

#define SET_AXIS_HOMED_FLAG ax,
fl       if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_HOMED_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_HOMED_BIT;
 

Definition at line 575 of file emcstepmot.c.

#define SET_AXIS_HOME_SWITCH_FLAG ax,
fl       if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_HOME_SWITCH_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_HOME_SWITCH_BIT;
 

Definition at line 567 of file emcstepmot.c.

#define SET_AXIS_HOME_SWITCH_POLARITY ax,
fl       if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_HOME_SWITCH_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_HOME_SWITCH_BIT;
 

Definition at line 601 of file emcstepmot.c.

#define SET_AXIS_HOMING_FLAG ax,
fl       if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_HOMING_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_HOMING_BIT;
 

Definition at line 571 of file emcstepmot.c.

#define SET_AXIS_HOMING_POLARITY ax,
fl       if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_HOMING_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_HOMING_BIT;
 

Definition at line 605 of file emcstepmot.c.

#define SET_AXIS_INPOS_FLAG ax,
fl       if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_INPOS_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_INPOS_BIT;
 

Definition at line 543 of file emcstepmot.c.

#define SET_AXIS_NHL_FLAG ax,
fl       if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_MIN_HARD_LIMIT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_MIN_HARD_LIMIT_BIT;
 

Definition at line 563 of file emcstepmot.c.

#define SET_AXIS_NHL_POLARITY ax,
fl       if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_MIN_HARD_LIMIT_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_MIN_HARD_LIMIT_BIT;
 

Definition at line 597 of file emcstepmot.c.

#define SET_AXIS_NSL_FLAG ax,
fl       if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_MIN_SOFT_LIMIT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_MIN_SOFT_LIMIT_BIT;
 

Definition at line 555 of file emcstepmot.c.

#define SET_AXIS_PHL_FLAG ax,
fl       if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_MAX_HARD_LIMIT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_MAX_HARD_LIMIT_BIT;
 

Definition at line 559 of file emcstepmot.c.

#define SET_AXIS_PHL_POLARITY ax,
fl       if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_MAX_HARD_LIMIT_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_MAX_HARD_LIMIT_BIT;
 

Definition at line 593 of file emcstepmot.c.

#define SET_AXIS_PSL_FLAG ax,
fl       if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_MAX_SOFT_LIMIT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_MAX_SOFT_LIMIT_BIT;
 

Definition at line 551 of file emcstepmot.c.

#define SET_MOTION_COORD_FLAG fl       if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_COORD_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_COORD_BIT;
 

Definition at line 521 of file emcstepmot.c.

#define SET_MOTION_ENABLE_FLAG fl       if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_ENABLE_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_ENABLE_BIT;
 

Definition at line 529 of file emcstepmot.c.

#define SET_MOTION_ERROR_FLAG fl       if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_ERROR_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_ERROR_BIT;
 

Definition at line 517 of file emcstepmot.c.

#define SET_MOTION_INPOS_FLAG fl       if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_INPOS_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_INPOS_BIT;
 

Definition at line 525 of file emcstepmot.c.

#define diagnostics   printf
 

Definition at line 498 of file emcstepmot.c.


Function Documentation

void MARK_EMCMOT_CONFIG_CHANGE void    [inline, static]
 

Definition at line 502 of file emcstepmot.c.

00503 {
00504   if(emcmotConfig->head == emcmotConfig->tail) { 
00505     emcmotConfig->config_num++;
00506     emcmotStatus->config_num = emcmotConfig->config_num;
00507     emcmotConfig->head++;
00508   }
00509 }

int __attribute__ (unused)    [static]
 

Definition at line 355 of file emcstepmot.c.

00355                                                    : emcstepmot.c,v 1.18 2001/10/18 15:29:09 wshackle Exp $";
00356 
00357 void extMotDout(unsigned char byte)     // P.C. Added this to fix a broken call
00358     {                                   // when the functioning call has been
00359     return;                             // included for steppermotors, this
00360     }                                   // can be deleted.

int checkJog int    axis,
double    vel
[static]
 

Definition at line 818 of file emcstepmot.c.

Referenced by emcmotCommandHandler().

00819 {
00820   if (emcmotStatus->overrideLimits) {
00821     return 1;                   /* okay to jog when limits overridden */
00822   }
00823 
00824   if (axis < 0 ||
00825       axis >= EMCMOT_MAX_AXIS) {
00826     return 0;                   /* can't jog out-of-range axis */
00827   }
00828 
00829   if (vel > 0.0 &&
00830       (GET_AXIS_PSL_FLAG(axis) ||
00831        GET_AXIS_PHL_FLAG(axis))) {
00832     return 0;                   /* can't jog further past max limit */
00833   }
00834 
00835   if (vel < 0.0 &&
00836       (GET_AXIS_NSL_FLAG(axis) ||
00837        GET_AXIS_NHL_FLAG(axis))) {
00838     return 0;                   /* can't jog further past min limit */
00839   }
00840 
00841   /* okay to jog */
00842   return 1;
00843 }

int checkLimits void    [static]
 

Definition at line 793 of file emcstepmot.c.

00794 {
00795   int axis;
00796 
00797   for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
00798     if (! GET_AXIS_ACTIVE_FLAG(axis)) {
00799       /* if axis is not active, don't even look at its limits */
00800       continue;
00801     }
00802 
00803     if (GET_AXIS_PSL_FLAG(axis) ||
00804         GET_AXIS_NSL_FLAG(axis) ||
00805         GET_AXIS_PHL_FLAG(axis) ||
00806         GET_AXIS_NHL_FLAG(axis)) {
00807       return 0;
00808     }
00809   }
00810 
00811   return 1;
00812 }

void cleanup_module void   
 

Definition at line 3702 of file emcstepmot.c.

03703 {
03704   int axis;
03705 
03706   /* release traj planner space */
03707   tpDelete(&queue);
03708 
03709   /* disable amps */
03710   for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03711     extAmpEnable(axis,
03712                  ! GET_AXIS_ENABLE_POLARITY(axis));
03713   }
03714 
03715   /* quit board */
03716   extAioQuit();
03717   extDioQuit();
03718   extMotQuit();
03719 
03720 #ifdef rtlinux
03721 
03722 #ifdef RT_FIFO
03723   rtf_destroy(EMCMOT_COMMAND_RTF);
03724   rtf_destroy(EMCMOT_STATUS_RTF);
03725   rtf_destroy(EMCMOT_ERROR_RTF);
03726 #endif
03727 
03728   /* delete control task */
03729 #ifdef USE_RTL2
03730   pthread_delete_np(emcmotTask);
03731 #else
03732   rt_task_delete(&emcmotTask);
03733 #endif
03734 
03735 #ifdef STEPPER_MOTORS
03736 
03737   /* delete stepper motor task */
03738 #ifdef USE_RTL2
03739   pthread_delete_np(smTask);
03740 #else
03741   rt_task_delete(&smTask);
03742 #endif
03743 
03744 #endif
03745 
03746   /* free shared memory */
03747 #ifdef USE_RTL2
03748   mbuff_free("emcmotStruct",emcmotStruct);
03749 #else
03750 #ifdef rtlinux2
03751   iounmap(emcmotStruct);
03752 #else
03753   vfree(emcmotStruct);
03754 #endif
03755 #endif
03756 
03757 
03758   /* FIXME */
03759   diagnostics("exited emcmot\n");
03760 #ifdef STEPPER_MOTORS
03761   diagnostics("sm cycle time %d\n", (int) (smCycleTime * 1000000.0));
03762   diagnostics("sm cycles per axis %d\n", smCyclesPerAxis);
03763 #endif
03764 
03765 #else
03766 
03767   /* detach from shmem */
03768   if (NULL != shmem) {
03769     rcs_shm_close(shmem);
03770     shmem = NULL;
03771   }
03772 
03773 #endif
03774 }

int emcmotCommandHandler void    [static]
 

Definition at line 920 of file emcstepmot.c.

00921 {
00922   int axis;                     /* loop counter */
00923 #ifdef rtlinux
00924 #ifdef RT_FIFO
00925   int err;
00926 #endif
00927 #endif
00928   int valid;
00929 #ifdef STEPPER_MOTORS
00930   double mag;                   /* temporary value for magnitudes, to
00931                                    avoid calling fabs() all the time */
00932 #endif
00933 
00934   /* copy command from outside into local buffers */
00935 
00936 #if defined (rtlinux) && defined (RT_FIFO)
00937   while ((err =
00938           rtf_get(EMCMOT_COMMAND_RTF, &emcmotCommandBuffer,
00939                   sizeof(EMCMOT_COMMAND))) == sizeof(EMCMOT_COMMAND)) {
00940 
00941 #endif /* rtlinux and RT_FIFO */
00942 
00943     /* check for split read */
00944     if (emcmotCommand->head != emcmotCommand->tail) {
00945       emcmotDebug->split++;
00946       return 0;                 /* not really an error */
00947     }
00948 
00949     if (emcmotCommand->commandNum != emcmotStatus->commandNumEcho) {
00950       /* increment head count-- we'll be modifying emcmotStatus */
00951       emcmotStatus->head++;
00952       emcmotDebug->head++;
00953 
00954       /* got a new command-- echo command and number... */
00955       emcmotStatus->commandEcho = emcmotCommand->command;
00956       emcmotStatus->commandNumEcho = emcmotCommand->commandNum;
00957 
00958       /* clear status value by default */
00959       emcmotStatus->commandStatus = EMCMOT_COMMAND_OK;
00960 
00961       /* log it, if appropriate */
00962       if (emcmotStatus->logStarted &&
00963           emcmotStatus->logType == EMCMOT_LOG_TYPE_CMD) {
00964         ls.item.cmd.time = etime();
00965         ls.item.cmd.command = emcmotCommand->command;
00966         ls.item.cmd.commandNum = emcmotCommand->commandNum;
00967 #if defined (rtlinux) && defined (RT_FIFO)
00968         rtf_put(EMCMOT_LOG_RTF, &ls, sizeof(EMCMOT_LOG_STRUCT));
00969 #else  /* not rtlinux or not RT_FIFO */
00970         emcmotLogAdd(emcmotLog, ls);
00971         emcmotStatus->logPoints = emcmotLog->howmany;
00972 #endif /* else not rtlinux nor RT_FIFO */
00973       }
00974 
00975       /* ...and process command */
00976       switch (emcmotCommand->command) {
00977       case EMCMOT_FREE:
00978         /* change the mode to free axis motion */
00979         /* can be done at any time */
00980         /* reset the coordinating flag to defer transition to
00981            controller cycle */
00982         coordinating = 0;
00983         break;
00984 
00985       case EMCMOT_COORD:
00986         /* change the mode to coordinated axis motion */
00987         /* can be done at any time */
00988         /* set the coordinating flag to defer transition to
00989            controller cycle */
00990         coordinating = 1;
00991         break;
00992 
00993       case EMCMOT_SET_NUM_AXES:
00994         MARK_EMCMOT_CONFIG_CHANGE();
00995         /* set the global NUM_AXES, which must be between 1 and
00996            EMCMOT_MAX_AXIS, inclusive */
00997         axis = emcmotCommand->axis;
00998         /* note that this comparison differs from the check on the
00999            range of 'axis' in most other places, since those checks
01000            are for a value to be used as an index and here it's a value
01001            to be used as a counting number. The indenting is different
01002            here so as not to match macro editing on that other bunch. */
01003         if
01004           (
01005            axis <= 0 ||
01006            axis > EMCMOT_MAX_AXIS
01007            ) {
01008           break;
01009         }
01010         NUM_AXES = axis;
01011         break;
01012 
01013       case EMCMOT_SET_WORLD_HOME:
01014         worldHome = emcmotCommand->pos;
01015         break;
01016 
01017       case EMCMOT_SET_JOINT_HOME:
01018         axis = emcmotCommand->axis;
01019         if (axis < 0 ||
01020             axis >= EMCMOT_MAX_AXIS) {
01021           break;
01022         }
01023         jointHome[axis] = emcmotCommand->offset; /* FIXME-- use 'home' instead */
01024         break;
01025 
01026       case EMCMOT_SET_HOME_OFFSET:
01027         axis = emcmotCommand->axis;
01028         if (axis < 0 ||
01029             axis >= EMCMOT_MAX_AXIS) {
01030           break;
01031         }
01032         emcmotConfig->homeOffset[axis] = emcmotCommand->offset;
01033         break;
01034 
01035       case EMCMOT_OVERRIDE_LIMITS:
01036         if (emcmotCommand->axis < 0) {
01037           /* don't override limits */
01038           emcmotStatus->overrideLimits = 0;
01039         }
01040         else {
01041           emcmotStatus->overrideLimits = 1;
01042         }
01043         overriding = 0;
01044         for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01045           SET_AXIS_ERROR_FLAG(axis, 0);
01046         }
01047         break;
01048 
01049       case EMCMOT_SET_TRAJ_CYCLE_TIME:
01050         MARK_EMCMOT_CONFIG_CHANGE();
01051         /* set the cycle time for trajectory calculations */
01052         /* really should be done only at startup before
01053            controller is run, but at least it requires
01054            no active motions and the interpolators need
01055            to be cleared */
01056         setTrajCycleTime(emcmotCommand->cycleTime);
01057         break;
01058 
01059       case EMCMOT_SET_SERVO_CYCLE_TIME:
01060         MARK_EMCMOT_CONFIG_CHANGE();
01061         /* set the cycle time for servo calculations, which is the
01062            period for emcmotController execution */
01063         /* really should be done only at startup before
01064            controller is run, but at least it requires
01065            no active motions and the interpolators need
01066            to be cleared */
01067         setServoCycleTime(emcmotCommand->cycleTime);
01068 #ifdef rtlinux
01069 #ifdef USE_RTL2
01070         pthread_make_periodic_np(emcmotTask,
01071                                  gethrtime(),
01072                                  (hrtime_t)  (HRTICKS_PER_SEC *
01073                                              emcmotConfig->servoCycleTime));
01074 #else
01075         rt_task_make_periodic(&emcmotTask,
01076                               rt_get_time(),
01077                               (RTIME) (RT_TICKS_PER_SEC *
01078                                        emcmotConfig->servoCycleTime));
01079 #endif
01080 #endif /* rtlinux */
01081         break;
01082 
01083       case EMCMOT_SET_POSITION_LIMITS:
01084         MARK_EMCMOT_CONFIG_CHANGE();
01085         /* set the position limits for the axis */
01086         /* can be done at any time */
01087         axis = emcmotCommand->axis;
01088         if (axis < 0 ||
01089             axis >= EMCMOT_MAX_AXIS) {
01090           break;
01091         }
01092         emcmotConfig->minLimit[axis] = emcmotCommand->minLimit;
01093         emcmotConfig->maxLimit[axis] = emcmotCommand->maxLimit;
01094         break;
01095 
01096       case EMCMOT_SET_OUTPUT_LIMITS:
01097         MARK_EMCMOT_CONFIG_CHANGE();
01098         /* set the output limits for the axis */
01099         /* can be done at any time */
01100         axis = emcmotCommand->axis;
01101         if (axis < 0 ||
01102             axis >= EMCMOT_MAX_AXIS) {
01103           break;
01104         }
01105 
01106         emcmotConfig->minOutput[axis] = emcmotCommand->minLimit;
01107         emcmotConfig->maxOutput[axis] = emcmotCommand->maxLimit;
01108         break;
01109 
01110       case EMCMOT_SET_OUTPUT_SCALE:
01111         axis = emcmotCommand->axis;
01112         if (axis < 0 ||
01113             axis >= EMCMOT_MAX_AXIS ||
01114             emcmotCommand->scale == 0) {
01115           break;
01116         }
01117         emcmotStatus->outputScale[axis] = emcmotCommand->scale;
01118         emcmotStatus->outputOffset[axis] = emcmotCommand->offset;
01119         inverseOutputScale[axis] = 1.0 / emcmotStatus->outputScale[axis];
01120         break;
01121 
01122       case EMCMOT_SET_INPUT_SCALE:
01123         /*
01124           change the scale factor for the position input, e.g.,
01125           encoder counts per unit. Note that this is not a good idea
01126           once things have gotten underway, since the axis will
01127           jump servo to the "new" position, the gains will no longer
01128           be appropriate, etc.
01129         */
01130         axis = emcmotCommand->axis;
01131         if (axis < 0 ||
01132             axis >= EMCMOT_MAX_AXIS ||
01133             emcmotCommand->scale == 0.0) {
01134           break;
01135         }
01136 
01137         /* adjust last saved input value to match this one, so we
01138            don't get a spurious following error */
01139         oldInput[axis] = oldInput[axis] * emcmotStatus->inputScale[axis] +
01140           emcmotStatus->inputOffset[axis]; /* temp calc */
01141         oldInput[axis] = (oldInput[axis] - emcmotCommand->offset) /
01142           emcmotCommand->scale;
01143 
01144         /* now make them active */
01145         emcmotStatus->inputScale[axis] = emcmotCommand->scale;
01146         emcmotStatus->inputOffset[axis] = emcmotCommand->offset;
01147         inverseInputScale[axis] = 1.0 / emcmotStatus->inputScale[axis];
01148 
01149 #ifdef STEPPER_MOTORS
01150         /* change the units on the stepper counts; note that this
01151            is a signed value. De-sign it if you want to consider
01152            just its magnitude. */
01153         smStepsPerUnit[axis] = emcmotCommand->scale;
01154         mag = fabs(smStepsPerUnit[axis]);
01155         smMagUnitsPerStep[axis] = 1.0 / mag;
01156         /* update smVPmax so that stepper task runs at proper rate */
01157         if (mag > smMaxStepsPerUnit) {
01158           smVPmax = smVPmax * mag / smMaxStepsPerUnit;
01159           smMaxStepsPerUnit = mag;
01160         }
01161         /* set the period to twice the max pulse rate. It need only
01162            be the same as the pulse rate, but this makes it the same
01163            as before */
01164         smCycleTime = 0.5/smVPmax;
01165         smCyclesPerAxis = (int) (emcmotConfig->servoCycleTime / smCycleTime);
01166 #ifdef USE_RTL2
01167         pthread_make_periodic_np(smTask,
01168                               gethrtime(),
01169                               ((hrtime_t) (HRTICKS_PER_SEC * smCycleTime)));
01170 #else
01171         rt_task_make_periodic(&smTask,
01172                               rt_get_time(),
01173                               ((RTIME) (RT_TICKS_PER_SEC * smCycleTime)));
01174 #endif
01175 #endif
01176         break;
01177 
01178         /*
01179           Max and min ferror work like this:
01180           limiting ferror is determined by slope of ferror line,
01181           = maxFerror/limitVel
01182           -> limiting ferror = maxFerror/limitVel * vel.
01183           If ferror < minFerror then OK else
01184           if ferror < limiting ferror then OK else ERROR
01185          */
01186 
01187       case EMCMOT_SET_MAX_FERROR:
01188         MARK_EMCMOT_CONFIG_CHANGE();
01189         axis = emcmotCommand->axis;
01190         if (axis < 0 ||
01191             axis >= EMCMOT_MAX_AXIS ||
01192             emcmotCommand->maxFerror < 0.0) {
01193           break;
01194         }
01195         emcmotConfig->maxFerror[axis] = emcmotCommand->maxFerror;
01196         break;
01197 
01198       case EMCMOT_SET_MIN_FERROR:
01199         MARK_EMCMOT_CONFIG_CHANGE();
01200         axis = emcmotCommand->axis;
01201         if (axis < 0 ||
01202             axis >= EMCMOT_MAX_AXIS ||
01203             emcmotCommand->minFerror < 0.0) {
01204           break;
01205         }
01206         emcmotConfig->minFerror[axis] = emcmotCommand->minFerror;
01207         break;
01208 
01209       case EMCMOT_JOG_CONT:
01210         /* do a continuous jog, implemented as an incremental
01211            jog to the software limit, or the full range of travel
01212            if software limits don't yet apply because we're not homed */
01213 
01214         /* check axis range */
01215         axis = emcmotCommand->axis;
01216         if (axis < 0 ||
01217             axis >= EMCMOT_MAX_AXIS) {
01218           break;
01219         }
01220 
01221         /* requires no motion, in free mode, enable on */
01222         if (GET_MOTION_COORD_FLAG() ||
01223             ! GET_MOTION_INPOS_FLAG() ||
01224             ! GET_MOTION_ENABLE_FLAG()) {
01225           SET_AXIS_ERROR_FLAG(axis, 1);
01226           break;
01227         }
01228 
01229         /* don't jog further onto limits */
01230         if (! checkJog(axis, emcmotCommand->vel)) {
01231           SET_AXIS_ERROR_FLAG(axis, 1);
01232           break;
01233         }
01234 
01235         if (emcmotCommand->vel > 0.0) {
01236           if (GET_AXIS_HOMED_FLAG(axis)) {
01237             freePose.tran.x = emcmotConfig->maxLimit[axis];
01238           }
01239           else {
01240             freePose.tran.x = AXRANGE(axis);
01241           }
01242         }
01243         else {
01244           if (GET_AXIS_HOMED_FLAG(axis)) {
01245             freePose.tran.x = emcmotConfig->minLimit[axis];
01246           }
01247           else {
01248             freePose.tran.x = - AXRANGE(axis);
01249           }
01250         }
01251 
01252         tpSetVmax(&freeAxis[axis], fabs(emcmotCommand->vel));
01253         tpAddLine(&freeAxis[axis], freePose);
01254         SET_AXIS_ERROR_FLAG(axis, 0);
01255 
01256         break;
01257 
01258       case EMCMOT_JOG_INCR:
01259         /* do an incremental jog */
01260 
01261         /* check axis range */
01262         axis = emcmotCommand->axis;
01263         if (axis < 0 ||
01264             axis >= EMCMOT_MAX_AXIS) {
01265           break;
01266         }
01267 
01268         /* requires no motion, in free mode, enable on */
01269         if (GET_MOTION_COORD_FLAG() ||
01270             ! GET_MOTION_INPOS_FLAG() ||
01271             ! GET_MOTION_ENABLE_FLAG()) {
01272           SET_AXIS_ERROR_FLAG(axis, 1);
01273           break;
01274         }
01275 
01276         /* don't jog further onto limits */
01277         if (! checkJog(axis, emcmotCommand->vel)) {
01278           SET_AXIS_ERROR_FLAG(axis, 1);
01279           break;
01280         }
01281 
01282         if (emcmotCommand->vel > 0.0) {
01283           freePose.tran.x = jointPos[axis] + emcmotCommand->offset; /* FIXME-- use 'goal' instead */
01284           if (GET_AXIS_HOMED_FLAG(axis)) {
01285             if (freePose.tran.x > emcmotConfig->maxLimit[axis]) {
01286               freePose.tran.x = emcmotConfig->maxLimit[axis];
01287             }
01288           }
01289         }
01290         else {
01291           freePose.tran.x = jointPos[axis] - emcmotCommand->offset; /* FIXME-- use 'goal' instead */
01292           if (GET_AXIS_HOMED_FLAG(axis)) {
01293             if (freePose.tran.x < emcmotConfig->minLimit[axis]) {
01294               freePose.tran.x = emcmotConfig->minLimit[axis];
01295             }
01296           }
01297         }
01298 
01299         tpSetVmax(&freeAxis[axis], fabs(emcmotCommand->vel));
01300         tpAddLine(&freeAxis[axis], freePose);
01301         SET_AXIS_ERROR_FLAG(axis, 0);
01302 
01303         break;
01304 
01305       case EMCMOT_JOG_ABS:
01306         /* do an absolute jog */
01307 
01308         /* check axis range */
01309         axis = emcmotCommand->axis;
01310         if (axis < 0 ||
01311             axis >= EMCMOT_MAX_AXIS) {
01312           break;
01313         }
01314 
01315         /* requires no motion, in free mode, enable on */
01316         if (GET_MOTION_COORD_FLAG() ||
01317             ! GET_MOTION_INPOS_FLAG() ||
01318             ! GET_MOTION_ENABLE_FLAG()) {
01319           SET_AXIS_ERROR_FLAG(axis, 1);
01320           break;
01321         }
01322 
01323         /* don't jog further onto limits */
01324         if (! checkJog(axis, emcmotCommand->vel)) {
01325           SET_AXIS_ERROR_FLAG(axis, 1);
01326           break;
01327         }
01328 
01329         freePose.tran.x = emcmotCommand->offset; /* FIXME-- use 'goal' instead */
01330         if (GET_AXIS_HOMED_FLAG(axis)) {
01331           if (freePose.tran.x > emcmotConfig->maxLimit[axis]) {
01332             freePose.tran.x = emcmotConfig->maxLimit[axis];
01333           }
01334           else if (freePose.tran.x < emcmotConfig->minLimit[axis]) {
01335             freePose.tran.x = emcmotConfig->minLimit[axis];
01336           }
01337         }
01338 
01339         tpSetVmax(&freeAxis[axis], fabs(emcmotCommand->vel));
01340         tpAddLine(&freeAxis[axis], freePose);
01341         SET_AXIS_ERROR_FLAG(axis, 0);
01342 
01343         break;
01344 
01345       case EMCMOT_SET_TERM_COND:
01346         /* sets termination condition for motion queue */
01347         tpSetTermCond(&queue, emcmotCommand->termCond);
01348         break;
01349 
01350       case EMCMOT_SET_LINE:
01351         /* queue up a linear move */
01352         /* requires coordinated mode, enable off, not on limits */
01353         if (! GET_MOTION_COORD_FLAG() ||
01354             ! GET_MOTION_ENABLE_FLAG()) {
01355           reportError("Need to be enabled, in coord mode for linear move");
01356           emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
01357           SET_MOTION_ERROR_FLAG(1);
01358           break;
01359         }
01360         else if (! inRange(emcmotCommand->pos)) {
01361           reportError("Linear move %d out of range",
01362                       emcmotCommand->id);
01363           emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01364           tpAbort(&queue);
01365           SET_MOTION_ERROR_FLAG(1);
01366           break;
01367         }
01368         else if (! checkLimits()) {
01369           reportError("Can't do linear move with limits exceeded");
01370           emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01371           tpAbort(&queue);
01372           SET_MOTION_ERROR_FLAG(1);
01373           break;
01374         }
01375 
01376         /* append it to the queue */
01377         tpSetId(&queue, emcmotCommand->id);
01378         if (-1 == tpAddLine(&queue, emcmotCommand->pos)) {
01379           reportError("Can't add linear move");
01380           emcmotStatus->commandStatus = EMCMOT_COMMAND_BAD_EXEC;
01381           tpAbort(&queue);
01382           SET_MOTION_ERROR_FLAG(1);
01383           break;
01384         }
01385         else {
01386           SET_MOTION_ERROR_FLAG(0);
01387         }
01388         break;
01389 
01390       case EMCMOT_SET_CIRCLE:
01391         /* queue up a circular move */
01392         /* requires coordinated mode, enable on, not on limits */
01393         if (! GET_MOTION_COORD_FLAG() ||
01394             ! GET_MOTION_ENABLE_FLAG()) {
01395           reportError("Need to be enabled, in coord mode for circular move");
01396           emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
01397           SET_MOTION_ERROR_FLAG(1);
01398           break;
01399         }
01400         else if (! inRange(emcmotCommand->pos)) {
01401           reportError("Circular move %d out of range",
01402                       emcmotCommand->id);
01403           emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01404           tpAbort(&queue);
01405           SET_MOTION_ERROR_FLAG(1);
01406           break;
01407         }
01408         else if (! checkLimits()) {
01409           reportError("Can't do circular move with limits exceeded");
01410           emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01411           tpAbort(&queue);
01412           SET_MOTION_ERROR_FLAG(1);
01413           break;
01414         }
01415 
01416         /* append it to the queue */
01417         tpSetId(&queue, emcmotCommand->id);
01418         if (-1 ==
01419             tpAddCircle(&queue, emcmotCommand->pos,
01420                         emcmotCommand->center, emcmotCommand->normal,
01421                         emcmotCommand->turn)) {
01422           reportError("Can't add circular move");
01423           emcmotStatus->commandStatus = EMCMOT_COMMAND_BAD_EXEC;
01424           tpAbort(&queue);
01425           SET_MOTION_ERROR_FLAG(1);
01426           break;
01427         }
01428         else {
01429           SET_MOTION_ERROR_FLAG(0);
01430         }
01431         break;
01432 
01433       case EMCMOT_SET_VEL:
01434         /* set the velocity for subsequent moves */
01435         /* can do it at any time */
01436         emcmotStatus->vel = emcmotCommand->vel;
01437         for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01438           tpSetVmax(&freeAxis[axis], emcmotStatus->vel);
01439         }
01440         tpSetVmax(&queue, emcmotStatus->vel);
01441         break;
01442 
01443 
01444       case EMCMOT_SET_AXIS_VEL_LIMIT:
01445         /* check axis range */
01446         axis = emcmotCommand->axis;
01447         if (axis < 0 ||
01448             axis >= EMCMOT_MAX_AXIS) {
01449           break;
01450         }
01451         tpSetVlimit(&freeAxis[axis], emcmotCommand->vel);
01452         emcmotConfig->axisLimitVel[axis] = emcmotCommand->vel;
01453         // bigVel[axis = 10 * emcmotCommand->vel;
01454         break;
01455         
01456       case EMCMOT_SET_VEL_LIMIT:
01457         /* set the absolute max velocity for all subsequent moves */
01458         /* can do it at any time */
01459 #ifdef STEPPER_MOTORS
01460         /* update smVPmax so that stepper task runs at proper rate,
01461            before we lose emcmotStatus->vel from overwrite by new value */
01462         smVPmax = smVPmax * emcmotCommand->vel / emcmotConfig->limitVel;
01463         /* set the period to twice the max pulse rate. It need only
01464            be the same as the pulse rate, but this makes it the same
01465            as before */
01466         smCycleTime = 0.5/smVPmax;
01467         smCyclesPerAxis = (int) (emcmotConfig->servoCycleTime / smCycleTime);
01468 #ifdef USE_RTL2
01469         pthread_make_periodic_np(smTask,
01470                               gethrtime(),
01471                               ((hrtime_t) (HRTICKS_PER_SEC * smCycleTime)));
01472 #else
01473         rt_task_make_periodic(&smTask,
01474                               rt_get_time(),
01475                               ((RTIME) (RT_TICKS_PER_SEC * smCycleTime)));
01476 #endif
01477 #endif
01478         emcmotConfig->limitVel = emcmotCommand->vel;
01479         for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01480           tpSetVlimit(&freeAxis[axis], emcmotConfig->limitVel);
01481         }
01482         tpSetVlimit(&queue, emcmotConfig->limitVel);
01483         /* set the debounce vel */
01484         bigVel = 10.0 * emcmotConfig->limitVel;
01485         break;
01486 
01487       case EMCMOT_SET_HOMING_VEL:
01488         /* set the homing velocity */
01489         /* can do it at any time */
01490         /* sign of vel should set polarity, and mag-sign are recorded */
01491 
01492         /* check axis range */
01493         axis = emcmotCommand->axis;
01494         if (axis < 0 ||
01495             axis >= EMCMOT_MAX_AXIS) {
01496           break;
01497         }
01498 
01499         if (emcmotCommand->vel < 0.0) {
01500           emcmotConfig->homingVel[axis] = - emcmotCommand->vel;
01501           SET_AXIS_HOMING_POLARITY(axis, 0);
01502         }
01503         else {
01504           emcmotConfig->homingVel[axis] = emcmotCommand->vel;
01505           SET_AXIS_HOMING_POLARITY(axis, 1);
01506         }
01507         break;
01508 
01509       case EMCMOT_SET_ACC:
01510         /* set the max acceleration */
01511         /* can do it at any time */
01512         emcmotStatus->acc = emcmotCommand->acc;
01513         for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01514           tpSetAmax(&freeAxis[axis], emcmotStatus->acc);
01515         }
01516         tpSetAmax(&queue, emcmotStatus->acc);
01517         break;
01518 
01519       case EMCMOT_PAUSE:
01520         /* pause the motion */
01521         /* can happen at any time */
01522         for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01523           tpPause(&freeAxis[axis]);
01524         }
01525         tpPause(&queue);
01526         emcmotStatus->paused = 1;
01527         break;
01528 
01529       case EMCMOT_RESUME:
01530         /* resume paused motion */
01531         /* can happen at any time */
01532         stepping = 0;
01533         for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01534           tpResume(&freeAxis[axis]);
01535         }
01536         tpResume(&queue);
01537         emcmotStatus->paused = 0;
01538         break;
01539 
01540       case EMCMOT_STEP:
01541         /* resume paused motion until id changes */
01542         /* can happen at any time */
01543         idForStep = emcmotStatus->id;
01544         stepping = 1;
01545         for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01546           tpResume(&freeAxis[axis]);
01547         }
01548         tpResume(&queue);
01549         emcmotStatus->paused = 0;
01550         break;
01551 
01552       case EMCMOT_SCALE:
01553         /* override speed */
01554         /* can happen at any time */
01555         if (emcmotCommand->scale < 0.0) {
01556           emcmotCommand->scale = 0.0; /* clamp it */
01557         }
01558         for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01559           tpSetVscale(&freeAxis[axis], emcmotCommand->scale);
01560           emcmotStatus->axVscale[axis] = emcmotCommand->scale;
01561         }
01562         tpSetVscale(&queue, emcmotCommand->scale);
01563         emcmotStatus->qVscale = emcmotCommand->scale;
01564         break;
01565 
01566       case EMCMOT_ABORT:
01567         /* abort motion */
01568         /* can happen at any time */
01569         /* check for coord or free space motion active */
01570         if (GET_MOTION_COORD_FLAG()) {
01571           tpAbort(&queue);
01572           SET_MOTION_ERROR_FLAG(0);
01573         }
01574         else {
01575           /* check axis range */
01576           axis = emcmotCommand->axis;
01577           if (axis < 0 ||
01578               axis >= EMCMOT_MAX_AXIS) {
01579             break;
01580           }
01581           tpAbort(&freeAxis[axis]);
01582           SET_AXIS_HOMING_FLAG(axis, 0);
01583           SET_AXIS_ERROR_FLAG(axis, 0);
01584         }
01585         break;
01586 
01587       case EMCMOT_DISABLE:
01588         /* go into disable */
01589         /* can happen at any time */
01590         /* reset the enabling flag to defer disable until
01591            controller cycle (it *will* be honored) */
01592         enabling = 0;
01593         break;
01594 
01595       case EMCMOT_ENABLE:
01596         /* come out of disable */
01597         /* can happen at any time */
01598         /* set the enabling flag to defer enable
01599            until controller cycle */
01600         enabling = 1;
01601         break;
01602 
01603       case EMCMOT_SET_PID:
01604         /* configure the PID gains */
01605         axis = emcmotCommand->axis;
01606         if (axis < 0 ||
01607             axis >= EMCMOT_MAX_AXIS) {
01608           break;
01609         }
01610         /* force it, instead of callind pidSetGains(), which would require
01611            that we link in pid.o, which we don't really need to do */
01612         emcmotConfig->pid[axis].p = emcmotCommand->pid.p;
01613         emcmotConfig->pid[axis].i = emcmotCommand->pid.i;
01614         emcmotConfig->pid[axis].d = emcmotCommand->pid.d;
01615         emcmotConfig->pid[axis].ff0 = emcmotCommand->pid.ff0;
01616         emcmotConfig->pid[axis].ff1 = emcmotCommand->pid.ff1;
01617         emcmotConfig->pid[axis].ff2 = emcmotCommand->pid.ff2;
01618         emcmotConfig->pid[axis].backlash = emcmotCommand->pid.backlash;
01619         emcmotConfig->pid[axis].bias = emcmotCommand->pid.bias;
01620         emcmotConfig->pid[axis].maxError = emcmotCommand->pid.maxError;
01621         emcmotConfig->pid[axis].deadband = emcmotCommand->pid.deadband;
01622         break;
01623 
01624       case EMCMOT_ACTIVATE_AXIS:
01625         /* make axis active, so that amps will be enabled when
01626            system is enabled or disabled */
01627         /* can be done at any time */
01628         axis = emcmotCommand->axis;
01629         if (axis < 0 ||
01630             axis >= EMCMOT_MAX_AXIS) {
01631           break;
01632         }
01633         SET_AXIS_ACTIVE_FLAG(axis, 1);
01634         break;
01635 
01636       case EMCMOT_DEACTIVATE_AXIS:
01637         /* make axis inactive, so that amps won't be affected when
01638            system is enabled or disabled */
01639         /* can be done at any time */
01640         axis = emcmotCommand->axis;
01641         if (axis < 0 ||
01642             axis >= EMCMOT_MAX_AXIS) {
01643           break;
01644         }
01645         SET_AXIS_ACTIVE_FLAG(axis, 0);
01646         break;
01647 
01648       case EMCMOT_ENABLE_AMPLIFIER:
01649         /* enable the amplifier directly, but don't enable calculations */
01650         /* can be done at any time */
01651         axis = emcmotCommand->axis;
01652         if (axis < 0 ||
01653             axis >= EMCMOT_MAX_AXIS) {
01654           break;
01655         }
01656         extAmpEnable(axis, GET_AXIS_ENABLE_POLARITY(axis));
01657         break;
01658 
01659       case EMCMOT_DISABLE_AMPLIFIER:
01660         /* disable the axis calculations and amplifier, but don't
01661            disable calculations */
01662         /* can be done at any time */
01663         axis = emcmotCommand->axis;
01664         if (axis < 0 ||
01665             axis >= EMCMOT_MAX_AXIS) {
01666           break;
01667         }
01668         extAmpEnable(axis, ! GET_AXIS_ENABLE_POLARITY(axis));
01669         break;
01670 
01671       case EMCMOT_OPEN_LOG:
01672         /* open a data log */
01673         axis = emcmotCommand->axis;
01674         valid = 0;
01675         if (emcmotCommand->logSize > 0 &&
01676             emcmotCommand->logSize <= EMCMOT_LOG_MAX) {
01677           /* handle log-specific data */
01678           switch (emcmotCommand->logType) {
01679           case EMCMOT_LOG_TYPE_AXIS_POS:
01680           case EMCMOT_LOG_TYPE_AXIS_VEL:
01681           case EMCMOT_LOG_TYPE_POS_VOLTAGE:
01682             if (axis >= 0 &&
01683                 axis < EMCMOT_MAX_AXIS) {
01684               loggingAxis = axis;
01685               valid = 1;
01686             }
01687             break;
01688 
01689           default:
01690             valid = 1;
01691             break;
01692           }
01693         }
01694 
01695         if (valid) {
01696           /* success */
01697 #if defined (rtlinux) && defined (RT_FIFO)
01698           if (-1 ==
01699               rtf_create(EMCMOT_LOG_RTF,
01700                          emcmotCommand->logSize *
01701                          sizeof(EMCMOT_LOG_STRUCT))) {
01702             /* error-- can't open log */
01703             break;
01704           }
01705 #else  /* not rtlinux or not RT_FIFO */
01706           emcmotLogInit(emcmotLog,
01707                         emcmotCommand->logType,
01708                         emcmotCommand->logSize);
01709 #endif /* else not rtlinux or not RT_FIFO */
01710           emcmotStatus->logOpen = 1;
01711           emcmotStatus->logStarted = 0;
01712           emcmotStatus->logSize = emcmotCommand->logSize;
01713           emcmotStatus->logSkip = emcmotCommand->logSkip;
01714           emcmotStatus->logType = emcmotCommand->logType;
01715         }
01716         break;
01717 
01718       case EMCMOT_START_LOG:
01719         /* start logging */
01720         /* first ignore triggered log types */
01721         if (emcmotStatus->logType == EMCMOT_LOG_TYPE_POS_VOLTAGE) {
01722           break;
01723         }
01724         if (emcmotStatus->logOpen) {
01725           emcmotStatus->logStarted = 1;
01726           logSkip = 0;
01727         }
01728         break;
01729 
01730       case EMCMOT_STOP_LOG:
01731         /* stop logging */
01732         emcmotStatus->logStarted = 0;
01733         break;
01734 
01735       case EMCMOT_CLOSE_LOG:
01736 #if defined (rtlinux) && defined (RT_FIFO)
01737         rtf_destroy(EMCMOT_LOG_RTF);
01738 #endif /* rtlinux and RT_FIFO */
01739         emcmotStatus->logOpen = 0;
01740         emcmotStatus->logStarted = 0;
01741         emcmotStatus->logSize = 0;
01742         emcmotStatus->logSkip = 0;
01743         emcmotStatus->logType = 0;
01744         break;
01745 
01746       case EMCMOT_DAC_OUT:
01747         /* write output to dacs directly */
01748         /* will only persist if amplifiers are disabled */
01749         axis = emcmotCommand->axis;
01750         if (axis < 0 ||
01751             axis >= EMCMOT_MAX_AXIS) {
01752           break;
01753         }
01754         /* trigger log, if active */
01755         if (emcmotStatus->logType == EMCMOT_LOG_TYPE_POS_VOLTAGE &&
01756             loggingAxis == axis &&
01757             emcmotStatus->logOpen != 0) {
01758           emcmotStatus->logStarted = 1;
01759           logSkip = 0;
01760         }
01761         emcmotStatus->output[axis] = emcmotCommand->dacOut;
01762         break;
01763 
01764       case EMCMOT_HOME:
01765         /* home the specified axis */
01766         /* need to be in free mode, enable on */
01767         /* homing is basically a slow incremental jog to full range */
01768         axis = emcmotCommand->axis;
01769         if (axis < 0 ||
01770             axis >= EMCMOT_MAX_AXIS) {
01771           break;
01772         }
01773         if (GET_MOTION_COORD_FLAG() ||
01774             ! GET_MOTION_ENABLE_FLAG()) {
01775           break;
01776         }
01777 
01778         if (GET_AXIS_HOMING_POLARITY(axis)) {
01779           freePose.tran.x = + 2.0 * AXRANGE(axis);
01780         }
01781         else {
01782           freePose.tran.x = - 2.0 * AXRANGE(axis);
01783         }
01784 
01785         tpSetVmax(&freeAxis[axis], emcmotConfig->homingVel[axis]);
01786         tpAddLine(&freeAxis[axis], freePose);
01787         waitingForLatch[axis] = 1;
01788         SET_AXIS_HOMING_FLAG(axis, 1);
01789         SET_AXIS_HOMED_FLAG(axis, 0);
01790         break;
01791 
01792       case EMCMOT_ENABLE_WATCHDOG:
01793         wdEnabling = 1;
01794         wdWait = emcmotCommand->wdWait;
01795         if (wdWait < 0) {
01796           wdWait = 0;
01797         }
01798         break;
01799 
01800       case EMCMOT_DISABLE_WATCHDOG:
01801         wdEnabling = 0;
01802         break;
01803 
01804       case EMCMOT_SET_POLARITY:
01805         axis = emcmotCommand->axis;
01806         if (axis < 0 ||
01807             axis >= EMCMOT_MAX_AXIS) {
01808           break;
01809         }
01810         if (emcmotCommand->level) {
01811           /* normal */
01812           emcmotConfig->axisPolarity[axis] |= emcmotCommand->axisFlag;
01813         }
01814         else {
01815           /* inverted */
01816           emcmotConfig->axisPolarity[axis] &= ~emcmotCommand->axisFlag;
01817         }
01818         break;
01819 
01820 #ifdef ENABLE_PROBING
01821       case EMCMOT_SET_PROBE_INDEX:
01822         emcmotConfig->probeIndex = emcmotCommand->probeIndex;
01823         break;
01824 
01825       case EMCMOT_SET_PROBE_POLARITY:
01826         emcmotConfig->probePolarity = emcmotCommand->level;
01827         break;
01828 
01829       case EMCMOT_CLEAR_PROBE_FLAGS:
01830         emcmotStatus->probeTripped = 0;
01831         emcmotStatus->probing = 1;
01832         break;
01833 
01834       case EMCMOT_PROBE:
01835         /* most of this is taken from EMCMOT_SET_LINE */
01836         /* queue up a linear move */
01837         /* requires coordinated mode, enable off, not on limits */
01838         if (! GET_MOTION_COORD_FLAG() ||
01839             ! GET_MOTION_ENABLE_FLAG()) {
01840           reportError("Need to be enabled, in coord mode for linear move");
01841           emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
01842           SET_MOTION_ERROR_FLAG(1);
01843           break;
01844         }
01845         else if (! inRange(emcmotCommand->pos)) {
01846           reportError("Linear move %d out of range",
01847                       emcmotCommand->id);
01848           emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01849           tpAbort(&queue);
01850           SET_MOTION_ERROR_FLAG(1);
01851           break;
01852         }
01853         else if (! checkLimits()) {
01854           reportError("Can't do linear move with limits exceeded");
01855           emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01856           tpAbort(&queue);
01857           SET_MOTION_ERROR_FLAG(1);
01858           break;
01859         }
01860 
01861         /* append it to the queue */
01862         tpSetId(&queue, emcmotCommand->id);
01863         if (-1 == tpAddLine(&queue, emcmotCommand->pos)) {
01864           reportError("Can't add linear move");
01865           emcmotStatus->commandStatus = EMCMOT_COMMAND_BAD_EXEC;
01866           tpAbort(&queue);
01867           SET_MOTION_ERROR_FLAG(1);
01868           break;
01869         }
01870         else {
01871           emcmotStatus->probeTripped = 0;
01872           emcmotStatus->probing = 1;
01873           SET_MOTION_ERROR_FLAG(0);
01874         }
01875         break;
01876 #endif /* ENABLE_PROBING */
01877 
01878       default:
01879         reportError("Unrecognized command %d", emcmotCommand->command);
01880         emcmotStatus->commandStatus = EMCMOT_COMMAND_UNKNOWN_COMMAND;
01881         break;
01882       } /* end of: command switch */
01883 
01884       /* synch tail count */
01885       emcmotStatus->tail = emcmotStatus->head;
01886       emcmotConfig->tail = emcmotConfig->head;
01887       emcmotDebug->tail = emcmotDebug->head;
01888 
01889     } /* end of: if-new-command */
01890 
01891 #if defined (rtlinux) && defined (RT_FIFO)
01892   } /* end of: while-msg loop for RT FIFO */
01893 
01894   if (err != 0) {
01895     return -1;
01896   }
01897 
01898 #endif /* rtlinux and RT_FIFO */
01899 
01900   return 0;
01901 }

void emcmotController int    arg [static]
 

Definition at line 1916 of file emcstepmot.c.

Referenced by main().

01918 {
01919   double start, end, delta;     /* time stamping */
01920   int homeFlag;                 /* result of ext read to home switch */
01921   int axis;                     /* axis loop counter */
01922   int t;                        /* loop counter if we're in axis loop */
01923   int isLimit;                  /* result of ext read to limit sw */
01924   int whichCycle;               /* 0=none, 1=servo, 2=traj */
01925   int fault;
01926   double numres;
01927   double thisFerror[EMCMOT_MAX_AXIS];
01928   double limitFerror;           /* current scaled ferror */
01929   double magFerror;
01930 #ifdef STEPPER_MOTORS
01931   double bcomp[EMCMOT_MAX_AXIS]; /* backlash comp value */
01932   char bcompdir[EMCMOT_MAX_AXIS]; /* 0=none, 1=pos, -1=neg */
01933   double bcompincr[EMCMOT_MAX_AXIS]; /* incremental backlash comp value */
01934   double dsteps;                /* steps value (double) for stepper task */
01935   double oldbcomp;
01936   /* various parameters for acc/dec backlash comp */
01937   char bac_done[EMCMOT_MAX_AXIS];
01938   double bac_d[EMCMOT_MAX_AXIS];
01939   double bac_di[EMCMOT_MAX_AXIS];
01940   double bac_D[EMCMOT_MAX_AXIS];
01941   double bac_halfD[EMCMOT_MAX_AXIS];
01942   double bac_incrincr[EMCMOT_MAX_AXIS];
01943   double bac_incr[EMCMOT_MAX_AXIS];
01944 #endif
01945   char finalHome[EMCMOT_MAX_AXIS];
01946 
01947   for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01948 #ifdef STEPPER_MOTORS
01949     bcomp[axis] = 0.0;
01950     bcompdir[axis] = 0;
01951     bcompincr[axis] = 0.0;
01952     bac_done[axis] = 1;
01953     bac_d[axis] = 0.0;
01954     bac_di[axis] = 0.0;
01955     bac_D[axis] = 0.0;
01956     bac_halfD[axis] = 0.0;
01957     bac_incrincr[axis] = 0.0;
01958     bac_incr[axis] = 0.0;
01959 #endif
01960     finalHome[axis] = 0;
01961   }
01962 
01963 #ifdef rtlinux
01964   for (;;) {
01965 #endif /* rtlinux */
01966 
01967 #ifdef rtlinux
01968     /* toggle sound port watchdog */
01969 
01970     if (wdEnabling && ! wdEnabled) {
01971       /* just turned WD on */
01972       wdCount = wdWait;
01973       wdToggle = 0;
01974       wdEnabled = 1;
01975     }
01976     if (! wdEnabling && wdEnabled) {
01977       /* just turned WD off */
01978       /* clear the bit */
01979       soundByte = inb(SOUND_PORT);
01980       soundByte &= ~SOUND_MASK;
01981       outb(soundByte, SOUND_PORT);
01982       wdEnabled = 0;
01983     }
01984 
01985     if (wdEnabled && wdCount-- <= 0) {
01986       soundByte = inb(SOUND_PORT);
01987       wdToggle = ! wdToggle;
01988       if (wdToggle) {
01989         soundByte |= SOUND_MASK;
01990       }
01991       else {
01992         soundByte &= ~SOUND_MASK;
01993       }
01994       outb(soundByte, SOUND_PORT);
01995       wdCount = wdWait;
01996     }
01997 #endif /* rtlinux */
01998 
01999     /* record start time */
02000     start = etime();
02001 
02002     /* READ COMMAND: */
02003 
02004 #ifndef RT_FIFO
02005     emcmotCommandHandler();
02006 
02007 #endif /* not RT_FIFO */
02008 
02009     /* increment head count */
02010     emcmotStatus->head++;
02011     emcmotDebug->head++;
02012 
02013     /* READ INPUTS: */
02014 
02015 #ifndef STEPPER_MOTORS
02016     /* latch all encoder feedback into raw input array, done outside
02017        of for-loop on joints below, since it's a single call for all
02018        joints */
02019     extEncoderReadAll(EMCMOT_MAX_AXIS, rawInput);
02020 #endif
02021 
02022     /* process input and read limit switches */
02023     for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02024 #ifdef STEPPER_MOTORS
02025       /* READ INPUTS, deferred from above */
02026       rawInput[axis] = (double) emcmotDebug->stepperCount[axis] -
02027         bcompincr[axis] * smStepsPerUnit[axis];
02028 #endif
02029 
02030       /* save old cycle's values */
02031       oldInput[axis] = emcmotStatus->input[axis];
02032       /* set input, scaled according to input = (raw - offset) / scale */
02033       emcmotStatus->input[axis] =
02034         (rawInput[axis] - emcmotStatus->inputOffset[axis]) *
02035         inverseInputScale[axis];
02036 
02037 #ifndef STEPPER_MOTORS
02038       /* debounce bad feedback */
02039       if (fabs(emcmotStatus->input[axis] - oldInput[axis]) /
02040           emcmotConfig->servoCycleTime > bigVel) {
02041         /* bad input value-- debounce with the last value */
02042         emcmotStatus->input[axis] = oldInput[axis];
02043       }
02044 #endif
02045 
02046       /* read limit switches and amp fault from external
02047          interface, and set 'enabling' to zero if tripped
02048          to cause immediate stop */
02049 
02050       /* handle limits */
02051       if (GET_AXIS_ACTIVE_FLAG(axis)) {
02052         extMaxLimitSwitchRead(axis, &isLimit);
02053         if (isLimit == GET_AXIS_PHL_POLARITY(axis)) {
02054           if (++maxLimitSwitchCount[axis] > LIMIT_SWITCH_DEBOUNCE) {
02055             SET_AXIS_PHL_FLAG(axis, 1);
02056             maxLimitSwitchCount[axis] = LIMIT_SWITCH_DEBOUNCE;
02057             if (emcmotStatus->overrideLimits ||
02058                 isHoming()) {
02059             }
02060             else {
02061               SET_AXIS_ERROR_FLAG(axis, 1);
02062               enabling = 0;
02063             }
02064           }
02065         }
02066         else {
02067           SET_AXIS_PHL_FLAG(axis, 0);
02068           maxLimitSwitchCount[axis] = 0;
02069         }
02070       }
02071       if (GET_AXIS_ACTIVE_FLAG(axis)) {
02072         extMinLimitSwitchRead(axis, &isLimit);
02073         if (isLimit == GET_AXIS_NHL_POLARITY(axis)) {
02074           if (++minLimitSwitchCount[axis] > LIMIT_SWITCH_DEBOUNCE) {
02075             SET_AXIS_NHL_FLAG(axis, 1);
02076             minLimitSwitchCount[axis] = LIMIT_SWITCH_DEBOUNCE;
02077             if (emcmotStatus->overrideLimits ||
02078                 isHoming()) {
02079             }
02080             else {
02081               SET_AXIS_ERROR_FLAG(axis, 1);
02082               enabling = 0;
02083             }
02084           }
02085         }
02086         else {
02087           SET_AXIS_NHL_FLAG(axis, 0);
02088           minLimitSwitchCount[axis] = 0;
02089         }
02090       }
02091 
02092       if (GET_AXIS_ACTIVE_FLAG(axis) &&
02093           GET_AXIS_ENABLE_FLAG(axis)) {
02094         extAmpFault(axis, &fault);
02095         if (fault == GET_AXIS_FAULT_POLARITY(axis)) {
02096           if (++ampFaultCount[axis] > AMP_FAULT_DEBOUNCE) {
02097             SET_AXIS_ERROR_FLAG(axis, 1);
02098             SET_AXIS_FAULT_FLAG(axis, 1);
02099             ampFaultCount[axis] = AMP_FAULT_DEBOUNCE;
02100             enabling = 0;
02101           }
02102         }
02103         else {
02104           SET_AXIS_FAULT_FLAG(axis, 0);
02105           ampFaultCount[axis] = 0;
02106         }
02107       }
02108 
02109       /* read home switch and set flag if tripped. Handling of home
02110          sequence is done later. */
02111       if (GET_AXIS_ACTIVE_FLAG(axis)) {
02112         extHomeSwitchRead(axis, &homeFlag);
02113         if (homeFlag == GET_AXIS_HOME_SWITCH_POLARITY(axis)) {
02114           SET_AXIS_HOME_SWITCH_FLAG(axis, 1);
02115         }
02116         else {
02117           SET_AXIS_HOME_SWITCH_FLAG(axis, 0);
02118         }
02119       }
02120 
02121     } /* end of: loop on axes, for reading inputs, setting limit and
02122            home switch flags */
02123 
02124     /* now we're outside the axis loop, having just read input, scaled it,
02125          read the limit and home switches and amp faults. We need to abort
02126          all motion if we're on limits, handle homing sequence, and handle
02127          mode and state transitions. */
02128 
02129     /* RUN STATE LOGIC: */
02130 
02131     /* check for disabling */
02132     if (! enabling && GET_MOTION_ENABLE_FLAG()) {
02133       /* clear out the motion queue and interpolators */
02134       tpClear(&queue);
02135       for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02136         tpClear(&freeAxis[axis]);
02137         cubicDrain(&cubic[axis]);
02138         if (GET_AXIS_ACTIVE_FLAG(axis)) {
02139           extAmpEnable(axis, ! GET_AXIS_ENABLE_POLARITY(axis));
02140           SET_AXIS_ENABLE_FLAG(axis, 0);
02141           SET_AXIS_HOMING_FLAG(axis, 0);
02142           emcmotStatus->output[axis] = 0.0;
02143         }
02144         /* don't clear the axis error flag, since that may signify why
02145            we just went into disabled state */
02146       }
02147       /* reset the trajectory interpolation counter, so that the kinematics
02148          functions called during the disabled state run at the nominal
02149          trajectory rate rather than the servo rate. It's loaded with
02150          emcmotConfig->interpolationRate when it goes to zero. */
02151       interpolationCounter = 0;
02152 #ifdef STEPPER_MOTORS
02153       smInhibit = 1;
02154 #endif
02155       SET_MOTION_ENABLE_FLAG(0);
02156       /* don't clear the motion error flag, since that may signify why
02157          we just went into disabled state */
02158     }
02159 
02160     /* check for enabling */
02161     if (enabling && ! GET_MOTION_ENABLE_FLAG()) {
02162       tpSetPos(&queue, emcmotStatus->pos);
02163       for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02164         freePose.tran.x = jointPos[axis];
02165         tpSetPos(&freeAxis[axis], freePose);
02166 #ifndef STEPPER_MOTORS
02167         pidReset(&emcmotConfig->pid[axis]);
02168 #endif
02169         if (GET_AXIS_ACTIVE_FLAG(axis)) {
02170           extAmpEnable(axis, GET_AXIS_ENABLE_POLARITY(axis));
02171           SET_AXIS_ENABLE_FLAG(axis, 1);
02172           SET_AXIS_HOMING_FLAG(axis, 0);
02173         }
02174         /* clear any outstanding axis errors when going into enabled state */
02175         SET_AXIS_ERROR_FLAG(axis, 0);
02176       }
02177 #ifdef STEPPER_MOTORS
02178       smInhibit = 0;
02179 #endif
02180       SET_MOTION_ENABLE_FLAG(1);
02181       /* clear any outstanding motion errors when going into enabled state */
02182       SET_MOTION_ERROR_FLAG(0);
02183     }
02184 
02185     /* check for entering coordinated mode */
02186     if (coordinating && ! GET_MOTION_COORD_FLAG()) {
02187       if (GET_MOTION_INPOS_FLAG()) {
02188         /* update coordinated queue position */
02189         tpSetPos(&queue, emcmotStatus->pos);
02190         /* drain the cubics so they'll synch up */
02191         for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02192           cubicDrain(&cubic[axis]);
02193         }
02194         /* clear the override limits flags */
02195         overriding = 0;
02196         emcmotStatus->overrideLimits = 0;
02197         SET_MOTION_COORD_FLAG(1);
02198         SET_MOTION_ERROR_FLAG(0);
02199       }
02200       else {
02201         /* not in position-- don't honor mode change */
02202         coordinating = 0;
02203       }
02204     }
02205 
02206     /* check entering free space mode */
02207     if (! coordinating && GET_MOTION_COORD_FLAG()) {
02208       if (GET_MOTION_INPOS_FLAG()) {
02209         for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02210           /* update free planner positions */
02211           freePose.tran.x = jointPos[axis];
02212           tpSetPos(&freeAxis[axis], freePose);
02213           /* drain the cubics so they'll synch up */
02214           cubicDrain(&cubic[axis]);
02215         }
02216         SET_MOTION_COORD_FLAG(0);
02217         SET_MOTION_ERROR_FLAG(0);
02218       }
02219       else {
02220         /* not in position-- don't honor mode change */
02221         coordinating = 1;
02222       }
02223     }
02224 
02225     /* check for homing sequences */
02226     for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02227       if (GET_AXIS_HOMING_FLAG(axis)) {
02228         if (tpIsDone(&freeAxis[axis])) {
02229           /* check for decel or final move */
02230           if (finalHome[axis]) {
02231             /* reset flag-- we're back at home */
02232             finalHome[axis] = 0;
02233 
02234             /* rework the home kinematics values-- this could be done
02235                after each message to set world or joint kinematics, but
02236                we'll defer it to here so it happens just prior to when
02237                it's needed. Note that the nominal value of these may be
02238                changed, if the kinematics need to. */
02239             kinematicsHome(&worldHome, jointHome, &fflags, &iflags);
02240 
02241             /* set input offset to value such that resulting input
02242                is the jointHome[] value, with:
02243                input = (raw - offset) / scale ->
02244                offset = raw - input * scale ->
02245                offset = raw - jointHome * scale */
02246 
02247             emcmotStatus->inputOffset[axis] = rawInput[axis] -
02248               jointHome[axis] * emcmotStatus->inputScale[axis];
02249 
02250             /* recompute inputs to match so we don't have a
02251                momentary jump */
02252             emcmotStatus->input[axis] = jointHome[axis];
02253             oldInput[axis] = emcmotStatus->input[axis];
02254 
02255             /* reset interpolator so that it doesn't jump */
02256             cubicOffset(&cubic[axis], jointHome[axis] - coarseJointPos[axis]);
02257 
02258             /* set axis position to jointHome upon homing */
02259             jointPos[axis] = jointHome[axis];
02260             freePose.tran.x = jointHome[axis];
02261             tpSetPos(&freeAxis[axis], freePose);
02262 
02263             SET_AXIS_HOMING_FLAG(axis, 0);
02264             SET_AXIS_HOMED_FLAG(axis, 1);
02265 
02266             /* set allHomed flag if all active axes are homed; this
02267                  will signify that kinematics functions can be called */
02268             allHomed = 1;
02269             for (t = 0; t < EMCMOT_MAX_AXIS; t++) {
02270               if (GET_AXIS_ACTIVE_FLAG(t) &&
02271                   ! GET_AXIS_HOMED_FLAG(t)) {
02272                 /* one active axis is not homed */
02273                 allHomed = 0;
02274                 break;
02275               }
02276             }
02277             /* FIXME-- this only works with no forward kins */
02278             if (allHomed) {
02279               emcmotStatus->pos = worldHome;
02280               emcmotStatus->actualPos = worldHome;
02281             }
02282           }
02283           else {
02284             /* just finished decel, now we'll do final home */
02285             finalHome[axis] = 1;
02286             /* add move back to latched position + backoff */
02287             freePose.tran.x =
02288               (saveLatch[axis] - emcmotStatus->inputOffset[axis]) *
02289               inverseInputScale[axis] +
02290               emcmotConfig->homeOffset[axis];
02291             tpAddLine(&freeAxis[axis], freePose);
02292           }
02293         } /* end of: if axis is done either decel or final home */
02294       } /* end of: if axis is homing */
02295     } /* end of: axis loop that checks for homing */
02296 
02297     /* RUN MOTION CALCULATIONS: */
02298 
02299     /* run axis interpolations and outputs, but only if we're
02300        enabled. This section is "suppressed" if we're not
02301        enabled, although the read/write of encoders/dacs is still
02302        done. */
02303     whichCycle = 0;
02304     if (GET_MOTION_ENABLE_FLAG()) {
02305       /* set whichCycle to be at least a servo cycle, for calc time logging */
02306       whichCycle = 1;
02307 
02308       /* check to see if the interpolators are empty */
02309       while (cubicNeedNextPoint(&cubic[0])) {
02310         /* they're empty, so pull next point(s) off Cartesian or
02311            joint planner, depending upon coord or free mode. */
02312 
02313         /* check to see whether we're in coordinated or free mode, to
02314            decide which motion planner to call */
02315         if (GET_MOTION_COORD_FLAG()) {
02316           /* we're in coordinated mode-- pull a pose off the Cartesian
02317              trajectory planner, run it through the inverse kinematics,
02318              and spline up the joint points for interpolation in
02319              servo cycles. */
02320 
02321           /* set whichCycle to be a Cartesian trajectory cycle,
02322              for calc time logging */
02323           whichCycle = 2;
02324 
02325           /* run coordinated trajectory planning cycle */
02326           tpRunCycle(&queue);
02327 
02328           /* set new commanded traj pos */
02329           emcmotStatus->pos = tpGetPos(&queue);
02330 
02331           /* convert to joints */
02332           kinematicsInverse(&emcmotStatus->pos, coarseJointPos, &iflags, &fflags);
02333 
02334           /* spline joints up-- note that we may be adding points that
02335              fail soft limits, but we'll abort at the end of this cycle
02336              so it doesn't really matter */
02337           for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02338             cubicAddPoint(&cubic[axis], coarseJointPos[axis]);
02339           }
02340 
02341           /* call forward kinematics on input points for actual pos,
02342              at trajectory rate to save bandwidth */
02343           /* FIXME */
02344           if (EMCMOT_NO_FORWARD_KINEMATICS) {
02345             /* fake it by setting actual pos to commanded pos */
02346             emcmotStatus->actualPos = emcmotStatus->pos;
02347           }
02348           else {
02349             kinematicsForward(emcmotStatus->input, &emcmotStatus->actualPos, &fflags, &iflags);
02350           }
02351 
02352           /* now emcmotStatus->actualPos, emcmotStatus->pos, and
02353              coarseJointPos[] are set */
02354 
02355         } /* end of: coord mode */
02356         else {
02357           /* we're in free mode-- run joint planning cycles */
02358           for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02359             /* set whichCycle to be a joint trajectory cycle,
02360                for calc time logging */
02361             /* note that this may include one or more joint trajectory
02362                cycles, so calc time may be inherently variable */
02363             whichCycle = 2;
02364 
02365             /* run joint trajectory planning cycle */
02366             tpRunCycle(&freeAxis[axis]);
02367 
02368             /* set new coarse joint position. FIXME-- this uses only
02369                the tran.x field of the TP_STRUCT, which is overkill.
02370                We need a TP_STRUCT with a single scalar element. */
02371             coarseJointPos[axis] = tpGetPos(&freeAxis[axis]).tran.x;
02372 
02373             /* spline joint up-- note that we may be adding a point that
02374                fails soft limit, but we'll abort at the end of this cycle
02375                so it doesn't really matter */
02376             cubicAddPoint(&cubic[axis], coarseJointPos[axis]);
02377 
02378           } /* end of: axis for loop for joint planning cycle */
02379 
02380           if (EMCMOT_NO_FORWARD_KINEMATICS) {
02381             /* can't do anything */
02382           }
02383           else {
02384             /* call forward kinematics on input points for actual pos,
02385                at trajectory rate to save bandwidth */
02386             kinematicsForward(emcmotStatus->input, &emcmotStatus->actualPos, &fflags, &iflags);
02387 
02388             /* push coarseJointPos[] through the forward kins to
02389              set emcmotStatus->pos, which are not computed in free
02390              mode as they are in coord mode */
02391           /* Note: in systems where the forward kins are costly to compute,
02392              emcmotStatus->pos can be set to emcmotStatus->actualPos to
02393              save one call to the forward kins */
02394             kinematicsForward(coarseJointPos, &emcmotStatus->pos, &fflags, &iflags);
02395           }
02396 
02397           /* now emcmotStatus->actualPos, emcmotStatus->pos, and
02398              coarseJointPos[] are set */
02399 
02400         } /* end of: free mode trajectory planning */
02401       } /* end of: while (cubicNeedNextPoint(0)) */
02402 
02403       /* we're still in motion enabled section. For coordinated mode,
02404          the Cartesian trajectory cycle has been computed, if necessary,
02405          run through the inverse kinematics, and the joints have been
02406          splined up for interpolation. For free mode, the joint trajectory
02407          cycles have been computed, if necessary, and the joints have
02408          been splined up for interpolation. We still need to push the
02409          actual input through the forward kinematics, for actual pos.
02410 
02411          Effects:
02412 
02413          For coord mode, emcmotStatus->pos contains the commanded
02414          Cartesian pose, coarseJointPos[] contains the results of the
02415          inverse kinematics at the coarse (trajectory) rate, and the
02416          interpolators are not empty.
02417 
02418          For free mode, emcmotStatus->pos is unchanged, and needs to
02419          be updated via the forward kinematics. FIXME-- make sure this
02420          happens, and note where in this comment. coarseJointPos[]
02421          contains the results of the joint trajectory calculations
02422          at the coarse (trajectory) rate, and the interpolators are
02423          not empty.
02424       */
02425 
02426       /* check for soft joint limits. If so, abort all motion. The
02427          interpolators will pick this up further down and begin
02428          planning abort and stop. */
02429       onLimit = 0;
02430       for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02431         SET_AXIS_PSL_FLAG(axis, 0);
02432         SET_AXIS_NSL_FLAG(axis, 0);
02433         if (GET_AXIS_HOMED_FLAG(axis)) {
02434           if (coarseJointPos[axis] > emcmotConfig->maxLimit[axis]) {
02435             SET_AXIS_ERROR_FLAG(axis, 1);
02436             SET_AXIS_PSL_FLAG(axis, 1);
02437             onLimit = 1;
02438           }
02439           else if (coarseJointPos[axis] < emcmotConfig->minLimit[axis]) {
02440             SET_AXIS_ERROR_FLAG(axis, 1);
02441             SET_AXIS_NSL_FLAG(axis, 1);
02442           }
02443         }
02444       }
02445 
02446       /* reset wasOnLimit flag iff all joints are free of
02447        soft limits, as seen in the flag bits set last cycle.
02448        No need to do this for hard limits, since wasOnLimit
02449        only prevents flurry of aborts while on a soft limit
02450        and hard limits don't abort, they disable. */
02451       if (onLimit) {
02452         if (! wasOnLimit) {
02453           /* abort everything, regardless of coord or free mode */
02454           tpAbort(&queue);
02455           for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02456             tpAbort(&freeAxis[axis]);
02457             wasOnLimit = 1;
02458           }
02459         }
02460         /* else we were on a limit, so inhibit firing of aborts */
02461       }
02462       else {
02463         /* not on a limit, so clear wasOnLimit so aborts fire next
02464            time we are on a limit */
02465         wasOnLimit = 0;
02466       }
02467 
02468       if (whichCycle == 2) {
02469         /* we're on a trajectory cycle, either Cartesian or joint planning, so
02470            log per-traj-cycle data if logging active */
02471         logIt = 0;
02472 
02473         if (emcmotStatus->logStarted &&
02474             emcmotStatus->logSkip >= 0) {
02475 
02476           /* calculate current vel, accel, for logging */
02477           newVel.tran.x = (emcmotStatus->pos.tran.x - oldPos.tran.x) /
02478             emcmotConfig->trajCycleTime;
02479           newVel.tran.y = (emcmotStatus->pos.tran.y - oldPos.tran.y) /
02480             emcmotConfig->trajCycleTime;
02481           newVel.tran.z = (emcmotStatus->pos.tran.z - oldPos.tran.z) /
02482             emcmotConfig->trajCycleTime;
02483           oldPos = emcmotStatus->pos;
02484           newAcc.tran.x = (newVel.tran.x - oldVel.tran.x) /
02485             emcmotConfig->trajCycleTime;
02486           newAcc.tran.y = (newVel.tran.y - oldVel.tran.y) /
02487             emcmotConfig->trajCycleTime;
02488           newAcc.tran.z = (newVel.tran.z - oldVel.tran.z) /
02489             emcmotConfig->trajCycleTime;
02490           oldVel = newVel;
02491 
02492           /* save the type with the log item */
02493           ls.type = emcmotStatus->logType;
02494 
02495           /* now log type-specific data */
02496           switch (emcmotStatus->logType) {
02497 
02498           case EMCMOT_LOG_TYPE_TRAJ_POS:
02499             if (logSkip-- <= 0) {
02500               ls.item.trajPos.time = start;
02501               ls.item.trajPos.pos = emcmotStatus->pos.tran;
02502               logSkip = emcmotStatus->logSkip;
02503               logIt = 1;
02504             }
02505             break;
02506 
02507           case EMCMOT_LOG_TYPE_TRAJ_VEL:
02508             if (logSkip-- <= 0) {
02509               ls.item.trajVel.time = start;
02510               ls.item.trajVel.vel = newVel.tran;
02511               pmCartMag(newVel.tran, &ls.item.trajVel.mag);
02512               logSkip = emcmotStatus->logSkip;
02513               logIt = 1;
02514             }
02515             break;
02516 
02517           case EMCMOT_LOG_TYPE_TRAJ_ACC:
02518             if (logSkip-- <= 0) {
02519               ls.item.trajAcc.time = start;
02520               ls.item.trajAcc.acc = newAcc.tran;
02521               pmCartMag(newAcc.tran, &ls.item.trajAcc.mag);
02522               logSkip = emcmotStatus->logSkip;
02523               logIt = 1;
02524             }
02525             break;
02526 
02527           default:
02528             break;
02529           } /* end of: switch on log type */
02530 
02531           /* now log it */
02532 #if defined (rtlinux) && defined (RT_FIFO)
02533           if (logIt) {
02534             rtf_put(EMCMOT_LOG_RTF, &ls, sizeof(EMCMOT_LOG_STRUCT));
02535             /* FIXME-- update emcmotStatus->logPoints */
02536             logIt = 0;
02537           }
02538 #else
02539           if (logIt) {
02540             emcmotLogAdd(emcmotLog, ls);
02541             emcmotStatus->logPoints = emcmotLog->howmany;
02542             logIt = 0;
02543           }
02544 #endif
02545         } /* end of: if (emcmotStatus->logStarted &&
02546                          emcmotStatus->logSkip >= 0) */
02547       } /* end of: if (whichCycle == 2), for trajectory cycle logging */
02548 
02549       /* run interpolation and compensation */
02550       for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02551         /* interpolate */
02552         oldJointPos[axis] = jointPos[axis];
02553         jointPos[axis] = cubicInterpolate(&cubic[axis], 0, 0, 0, 0);
02554         /* round position to input resolution */
02555         numres = jointPos[axis] * emcmotStatus->inputScale[axis];
02556         if (numres < 0.0) {
02557           jointPos[axis] = inverseInputScale[axis] * ((int) (numres - 0.5));
02558         }
02559         else {
02560           jointPos[axis] = inverseInputScale[axis] * ((int) (numres + 0.5));
02561         }
02562         jointVel[axis] = (jointPos[axis] - oldJointPos[axis]) /
02563           emcmotConfig->servoCycleTime;
02564 
02565         /* run output calculations */
02566         if (GET_AXIS_ACTIVE_FLAG(axis)) {
02567 #ifdef STEPPER_MOTORS
02568           /* backlash compensation for steppers*/
02569           /* This is pretty screwed up, since backlash was originally
02570              part of the PID structure. We need to duplicate the
02571              correction method here, and use the backlash value from
02572              the PID structure since that's where it ends up.
02573              FIXME-- make backlash part of the EMC status proper, not
02574              the PID structure */
02575           if (jointPos[axis] - oldJointPos[axis] > 0.0) {
02576             oldbcomp = bcomp[axis];
02577             bcomp[axis] = + emcmotConfig->pid[axis].backlash / 2.0;
02578             if (bcompdir[axis] != + 1) {
02579               bac_done[axis] = 0;
02580               bac_di[axis] = bcompincr[axis];
02581               bac_d[axis] = 0;
02582               bac_D[axis] = bcomp[axis] - oldbcomp;
02583               bac_halfD[axis] = 0.5 * bac_D[axis];
02584               bac_incrincr[axis] = emcmotStatus->acc *
02585                 emcmotConfig->servoCycleTime * emcmotConfig->servoCycleTime;
02586               bac_incr[axis] = - 0.5 * bac_incrincr[axis];
02587               bcompdir[axis] = + 1;
02588             }
02589           }
02590           else if (jointPos[axis] - oldJointPos[axis] < 0.0) {
02591             oldbcomp = bcomp[axis];
02592             bcomp[axis] = - emcmotConfig->pid[axis].backlash / 2.0;
02593             if (bcompdir[axis] != - 1) {
02594               bac_done[axis] = 0;
02595               bac_di[axis] = bcompincr[axis];
02596               bac_d[axis] = 0;
02597               bac_D[axis] = bcomp[axis] - oldbcomp;
02598               bac_halfD[axis] = 0.5 * bac_D[axis];
02599               bac_incrincr[axis] = emcmotStatus->acc *
02600                 emcmotConfig->servoCycleTime * emcmotConfig->servoCycleTime;
02601               bac_incr[axis] = - 0.5 * bac_incrincr[axis];
02602               bcompdir[axis] = - 1;
02603             }
02604           }
02605           /* else no motion, so leave bcomp what it was */
02606 
02607           /* mete out the backlash according to an acc/dec profile */
02608           if (! bac_done[axis]) {
02609             if (bac_D[axis] > 0.0) {
02610               bcompincr[axis] = bac_di[axis] + bac_d[axis];
02611               if (bac_d[axis] < bac_halfD[axis]) {
02612                 bac_incr[axis] += bac_incrincr[axis];
02613                 bac_d[axis] += bac_incr[axis];
02614               }
02615               else if (bac_d[axis] < bac_D[axis]) {
02616                 bac_incr[axis] -= bac_incrincr[axis];
02617                 bac_d[axis] += bac_incr[axis];
02618               }
02619               if (bac_d[axis] >= bac_D[axis] || bac_incr[axis] <= 0.0) {
02620                 bac_done[axis] = 1;
02621               }
02622             }
02623             else {
02624               bcompincr[axis] = bac_di[axis] + bac_d[axis];
02625               if (bac_d[axis] > bac_halfD[axis]) {
02626                 bac_incr[axis] += bac_incrincr[axis];
02627                 bac_d[axis] -= bac_incr[axis];
02628               }
02629               else if (bac_d[axis] > bac_D[axis]) {
02630                 bac_incr[axis] -= bac_incrincr[axis];
02631                 bac_d[axis] -= bac_incr[axis];
02632               }
02633               if (bac_d[axis] <= bac_D[axis] || bac_incr[axis] <= 0.0) {
02634                 bac_done[axis] = 1;
02635               }
02636             }
02637           } /* end of: if not bac_done[axis] */
02638 
02639           /* fill in global smSteps[] for stepper task */
02640           /* first get steps, as a floating point */
02641           dsteps = (jointPos[axis] + bcompincr[axis]) *
02642             smStepsPerUnit[axis] + emcmotStatus->inputOffset[axis];
02643           /* round to nearest integer */
02644           if (dsteps < 0.0) {
02645             smSteps[axis] = (int) (dsteps - 0.5);
02646           }
02647           else {
02648             smSteps[axis] = (int) (dsteps + 0.5);
02649           }
02650 
02651           /* flag this as the start of a new chunk for the stepper task */
02652           smNewCycle[axis] = 1;
02653 #else
02654           /* COMPENSATE: */
02655 
02656           /*
02657             compensation means compute output
02658             'emcmotStatus->output[]' based on desired position
02659             'jointPos[]' and input 'emcmotStatus->input[]'.
02660 
02661             Currently the source calls for PID compensation.
02662             FIXME-- add wrapper for compensator, with ptr to
02663             emcmotStatus struct, with semantics that ->output[]
02664             needs to be filled.
02665           */
02666 
02667           /* here is PID compensation */
02668           emcmotStatus->output[axis] =
02669             pidRunCycle(&emcmotConfig->pid[axis],
02670                         emcmotStatus->input[axis],
02671                         jointPos[axis]);
02672 #endif
02673 
02674           /* COMPUTE FOLLOWING ERROR: */
02675 
02676           /* compute signed following error and magnitude */
02677           thisFerror[axis] = jointPos[axis] - emcmotStatus->input[axis];
02678           emcmotDebug->ferrorCurrent[axis] = thisFerror[axis];
02679           magFerror = fabs(thisFerror[axis]);
02680 
02681           /* record the max ferror for this axis */
02682           if (emcmotDebug->ferrorHighMark[axis] < magFerror) {
02683             emcmotDebug->ferrorHighMark[axis] = magFerror;
02684           }
02685 
02686           /* compute the scaled ferror for a move of this speed */
02687           limitFerror = emcmotConfig->maxFerror[axis] /
02688             emcmotConfig->limitVel *
02689             jointVel[axis];
02690           if (limitFerror < emcmotConfig->minFerror[axis]) {
02691             limitFerror = emcmotConfig->minFerror[axis];
02692           }
02693 
02694           /* abort if this ferror is greater than the scaled ferror */
02695           if (magFerror > limitFerror) {
02696             /* abort! abort! following error exceeded */
02697             SET_AXIS_ERROR_FLAG(axis, 1);
02698             SET_AXIS_FERROR_FLAG(axis, 1);
02699             if (enabling) {
02700               // report the following error just this once
02701               reportError("Axis %d following error", axis);
02702             }
02703             enabling = 0;
02704           }
02705           else {
02706             SET_AXIS_FERROR_FLAG(axis, 0);
02707           }
02708         } /* end of: if (GET_AXIS_ACTIVE_FLAG(axis)) */
02709         else {
02710           /* axis is not active-- leave the pid output where it is--
02711              if axis is not active one can still write to the dac */
02712         }
02713 
02714 #ifndef STEPPER_MOTORS
02715         /* CLAMP OUTPUT: */
02716 
02717         /*
02718           clamp output means take 'emcmotStatus->output[]' and
02719           limit to range
02720           'emcmotConfig->minOutput[] .. emcmotConfig->maxOutput[]'
02721         */
02722         if (emcmotStatus->output[axis] < emcmotConfig->minOutput[axis]) {
02723           emcmotStatus->output[axis] = emcmotConfig->minOutput[axis];
02724         }
02725         else if (emcmotStatus->output[axis] > emcmotConfig->maxOutput[axis]) {
02726           emcmotStatus->output[axis] = emcmotConfig->maxOutput[axis];
02727         }
02728 #endif
02729 
02730         /* CHECK FOR LATCH CONDITION: */
02731 
02732         /*
02733           check for latch condition means if we're waiting for a
02734           latched index pulse, and we see the pulse and the home
02735           switch, we read the raw input and abort. The offset is set
02736           above in the homing section by noting that if we're homing,
02737           and waitingForLatch[] is cleared, we latched.
02738 
02739           This presumes an encoder index pulse.
02740           FIXME-- remove explicit calls to encoder index pulse, to
02741           allow for open-loop control latching via switches only.
02742         */
02743         if (waitingForLatch[axis]) {
02744           if (GET_AXIS_HOME_SWITCH_FLAG(axis) ||
02745               GET_AXIS_PHL_FLAG(axis) ||
02746               GET_AXIS_NHL_FLAG(axis)) {
02747             /* read encoder index */
02748 #ifdef STEPPER_MOTORS
02749             /* force an "encoder latch" */
02750             latchFlag[axis] = 1;
02751 #else
02752             extEncoderResetIndex(axis);
02753             extEncoderReadLatch(axis, &latchFlag[axis]);
02754 #endif
02755             if (latchFlag[axis]) {
02756               /* get latched position in RAW UNITS */
02757               saveLatch[axis] = rawInput[axis];
02758               waitingForLatch[axis] = 0;
02759               /* call for an abort-- when it's finished, code
02760                  above sets inputOffset[] to saveLatch[] */
02761               finalHome[axis] = 0;
02762               tpAbort(&freeAxis[axis]);
02763             }
02764           } /* end of: if (GET_AXIS_HOME_SWITCH_FLAG(axis)) */
02765         }/* end of: if (waitingForLatch[axis]) */
02766       } /* end of: for (axis = 0; ...) */
02767     } /* end of: if (GET_MOTION_ENABLE_FLAG()) */
02768     else {
02769       /* we're not enabled, so no motion planning or interpolation has
02770          been done. jointPos[] is set to emcmotStatus->input[], and
02771          likewise with coarseJointPos[], which is normally updated at
02772          the traj rate but it's convenient to do them here at the same
02773          time at the servo rate. emcmotStatus->pos, ->actualPos need to
02774          be run through forward kinematics.
02775          Note that we are running at the servo rate, so we may need
02776          to slow down by the interpolation factor to avoid soaking
02777          the CPU. If we were enabled, ->pos was set by calcs (coord mode)
02778          or forward kins (free mode), and ->actualPos was set by forward
02779          kins on ->input[], all at the trajectory rate. */
02780       for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02781         coarseJointPos[axis] = emcmotStatus->input[axis];
02782         jointPos[axis] = coarseJointPos[axis];
02783       }
02784       /* synthesize the trajectory interpolation, via a counter that
02785          decrements from the interpolation rate. This causes the statements
02786          to execute at the trajectory rate instead of the servo rate at which
02787          this enclosing code is called. */
02788       if (--interpolationCounter <= 0) {
02789         if (! EMCMOT_NO_FORWARD_KINEMATICS) {
02790           /* call the forward kinematics, at the effective trajectory rate */
02791           if (allHomed ||
02792               kinType == KINEMATICS_IDENTITY) {
02793             kinematicsForward(emcmotStatus->input, &emcmotStatus->actualPos, &fflags, &iflags);
02794           }
02795           emcmotStatus->pos = emcmotStatus->actualPos;
02796         }
02797         /* reload the interpolation counter that simulates the interpolation
02798            done when enabled */
02799         interpolationCounter = emcmotConfig->interpolationRate;
02800       }
02801     }
02802 
02803 #ifdef ENABLE_PROBING
02804     extDioRead(emcmotConfig->probeIndex, &emcmotStatus->probeval);
02805     if (emcmotStatus->probing && emcmotStatus->probeTripped) {
02806       tpClear(&queue);
02807       emcmotStatus->probing = 0;
02808     }
02809     else if (emcmotStatus->probing && GET_MOTION_INPOS_FLAG() &&
02810              tpQueueDepth(&queue) == 0) {
02811       emcmotStatus->probing = 0;
02812     }
02813     else if (emcmotStatus->probing) {
02814       if (emcmotStatus->probeval == emcmotConfig->probePolarity) {
02815         emcmotStatus->probeTripped = 1;
02816         emcmotStatus->probedPos = emcmotStatus->actualPos;
02817         if (GET_MOTION_COORD_FLAG()) {
02818           tpAbort(&queue);
02819           SET_MOTION_ERROR_FLAG(0);
02820         }
02821         else {
02822           /* check axis range */
02823           for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02824             tpAbort(&freeAxis[axis]);
02825             SET_AXIS_HOMING_FLAG(axis, 0);
02826             SET_AXIS_ERROR_FLAG(axis, 0);
02827           }
02828         }
02829       }
02830     }
02831 #endif /* ENABLE_PROBING */
02832 
02833 #ifndef STEPPER_MOTORS
02834 
02835     /* SCALE OUTPUTS: */
02836 
02837     for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02838       rawOutput[axis] =
02839         (emcmotStatus->output[axis] - emcmotStatus->outputOffset[axis]) *
02840         inverseOutputScale[axis];
02841     }
02842 
02843     /* WRITE OUTPUTS: */
02844 
02845     /* write DACs-- note that this is done even when not
02846        enabled, although in this case the pidOutputs are
02847        all zero unless manually overridden. They will not
02848        be set by any calculations if we're not enabled. */
02849     extDacWriteAll(EMCMOT_MAX_AXIS, rawOutput);
02850 #endif
02851 
02852     /* UPDATE THE REST OF THE DYNAMIC STATUS: */
02853 
02854     /* copy computed axis positions to status. Note that if motion is
02855        disabled, this is the same as ->input[]. */
02856     for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02857       emcmotStatus->axisPos[axis] = jointPos[axis];
02858     }
02859 
02860     /* health heartbeat */
02861     emcmotStatus->heartbeat++;
02862 
02863     /* motion queue status */
02864     emcmotStatus->depth = tpQueueDepth(&queue);
02865     emcmotStatus->activeDepth = tpActiveDepth(&queue);
02866     emcmotStatus->id = tpGetExecId(&queue);
02867     emcmotStatus->queueFull = tcqFull(&queue.queue);
02868     SET_MOTION_INPOS_FLAG(0);
02869     if (tpIsDone(&queue)) {
02870       SET_MOTION_INPOS_FLAG(1);
02871     }
02872 
02873     /* axis status */
02874     for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02875       SET_AXIS_INPOS_FLAG(axis, 0);
02876       if (tpIsDone(&freeAxis[axis])) {
02877         SET_AXIS_INPOS_FLAG(axis, 1);
02878       }
02879       else {
02880         /* this axis, at least, is moving, so set overriding flag */
02881         if (emcmotStatus->overrideLimits) {
02882           overriding = 1;
02883         }
02884       }
02885     }
02886 
02887     /* reset overrideLimits flag if we have started a move and now
02888        are in position */
02889     for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02890       if (! GET_AXIS_INPOS_FLAG(axis)) {
02891         break;
02892       }
02893     }
02894     if (axis == EMCMOT_MAX_AXIS) {
02895       /* ran through all axes, and all are in position */
02896       if (overriding) {
02897         overriding = 0;
02898         emcmotStatus->overrideLimits = 0;
02899       }
02900     }
02901 
02902     /* check to see if we should pause in order to implement
02903        single stepping */
02904     if (stepping && idForStep != emcmotStatus->id) {
02905       for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02906         tpPause(&freeAxis[axis]);
02907       }
02908       tpPause(&queue);
02909       stepping = 0;
02910       emcmotStatus->paused = 1;
02911     }
02912 
02913     /* calculate elapsed time and min/max/avg */
02914     end = etime();
02915     delta = end - start;
02916     emcmotStatus->computeTime = delta;
02917     if (2 == whichCycle) {
02918       /* traj calcs done this cycle-- use tMin,Max,Avg */
02919       mmxavgAdd(&emcmotDebug->tMmxavg, delta);
02920       emcmotDebug->tMin = mmxavgMin(&emcmotDebug->tMmxavg);
02921       emcmotDebug->tMax = mmxavgMax(&emcmotDebug->tMmxavg);
02922       emcmotDebug->tAvg = mmxavgAvg(&emcmotDebug->tMmxavg);
02923     }
02924     else if (1 == whichCycle) {
02925       /* servo calcs only this cycle-- use sMin,Max,Avg */
02926       mmxavgAdd(&emcmotDebug->sMmxavg, delta);
02927       emcmotDebug->sMin = mmxavgMin(&emcmotDebug->sMmxavg);
02928       emcmotDebug->sMax = mmxavgMax(&emcmotDebug->sMmxavg);
02929       emcmotDebug->sAvg = mmxavgAvg(&emcmotDebug->sMmxavg);
02930     }
02931     else {
02932       /* calcs disabled this cycle-- use nMin,Max,Avg */
02933       mmxavgAdd(&emcmotDebug->nMmxavg, delta);
02934       emcmotDebug->nMin = mmxavgMin(&emcmotDebug->nMmxavg);
02935       emcmotDebug->nMax = mmxavgMax(&emcmotDebug->nMmxavg);
02936       emcmotDebug->nAvg = mmxavgAvg(&emcmotDebug->nMmxavg);
02937     }
02938 
02939     /* log per-servo-cycle data if logging active */
02940     logIt = 0;
02941     if (emcmotStatus->logStarted &&
02942         emcmotStatus->logSkip >= 0) {
02943 
02944       /* record type here, since all will set this */
02945       ls.type = emcmotStatus->logType;
02946 
02947       /* now log type-specific data */
02948       switch (ls.type) {
02949 
02950       case EMCMOT_LOG_TYPE_AXIS_POS:
02951         if (logSkip-- <= 0) {
02952           ls.item.axisPos.time = end;
02953           ls.item.axisPos.input = emcmotStatus->input[loggingAxis];
02954           ls.item.axisPos.output = jointPos[loggingAxis];
02955           logSkip = emcmotStatus->logSkip;
02956           logIt = 1;
02957         }
02958         break;
02959 
02960       case EMCMOT_LOG_TYPE_ALL_INPOS:
02961         if (logSkip-- <= 0) {
02962           ls.item.allInpos.time = end;
02963           for (axis = 0;
02964                axis < EMCMOT_LOG_NUM_AXES &&
02965                  axis < EMCMOT_MAX_AXIS;
02966                axis++) {
02967             ls.item.allInpos.input[axis] = emcmotStatus->input[axis];
02968           }
02969           logSkip = emcmotStatus->logSkip;
02970           logIt = 1;
02971         }
02972         break;
02973 
02974       case EMCMOT_LOG_TYPE_ALL_OUTPOS:
02975         if (logSkip-- <= 0) {
02976           ls.item.allOutpos.time = end;
02977           for (axis = 0;
02978                axis < EMCMOT_LOG_NUM_AXES &&
02979                  axis < EMCMOT_MAX_AXIS;
02980                axis++) {
02981             ls.item.allOutpos.output[axis] = jointPos[axis];
02982           }
02983           logSkip = emcmotStatus->logSkip;
02984           logIt = 1;
02985         }
02986         break;
02987 
02988       case EMCMOT_LOG_TYPE_AXIS_VEL:
02989         if (logSkip-- <= 0) {
02990           ls.item.axisVel.time = end;
02991           ls.item.axisVel.cmdVel = jointPos[loggingAxis] -
02992             oldJointPos[loggingAxis];
02993           ls.item.axisVel.actVel = emcmotStatus->input[loggingAxis] -
02994             oldInput[loggingAxis];
02995           logSkip = emcmotStatus->logSkip;
02996           logIt = 1;
02997         }
02998         break;
02999 
03000       case EMCMOT_LOG_TYPE_ALL_FERROR:
03001         if (logSkip-- <= 0) {
03002           ls.item.allFerror.time = end;
03003           for (axis = 0;
03004                axis < EMCMOT_LOG_NUM_AXES &&
03005                  axis < EMCMOT_MAX_AXIS;
03006                axis++) {
03007             ls.item.allFerror.ferror[axis] = thisFerror[axis];
03008           }
03009           logSkip = emcmotStatus->logSkip;
03010           logIt = 1;
03011         }
03012         break;
03013 
03014       case EMCMOT_LOG_TYPE_POS_VOLTAGE:
03015         /* don't do a circular log-- suppress if full */
03016         if (emcmotLog->howmany >= emcmotStatus->logSize) {
03017           emcmotStatus->output[loggingAxis] = 0.0; /* drop the DAC to zero */
03018           emcmotStatus->logStarted = 0; /* stop logging */
03019           logIt = 0;            /* should still be zero, reset anyway */
03020           break;
03021         }
03022         if (logSkip-- <= 0) {
03023           ls.item.posVoltage.time = end;
03024           for (axis = 0;
03025                axis < EMCMOT_LOG_NUM_AXES &&
03026                  axis < EMCMOT_MAX_AXIS;
03027                axis++) {
03028             ls.item.posVoltage.pos = emcmotStatus->input[loggingAxis];
03029             ls.item.posVoltage.voltage = rawOutput[loggingAxis];
03030           }
03031           logSkip = emcmotStatus->logSkip;
03032           logIt = 1;
03033         }
03034         break;
03035 
03036       default:
03037         break;
03038       } /* end of: switch on log type */
03039 
03040       /* now log it */
03041 #if defined (rtlinux) && defined (RT_FIFO)
03042       if (logIt) {
03043         rtf_put(EMCMOT_LOG_RTF, &ls, sizeof(EMCMOT_LOG_STRUCT));
03044         /* FIXME-- update emcmotStatus->logPoints */
03045         logIt = 0;
03046       }
03047 #else
03048       if (logIt) {
03049         emcmotLogAdd(emcmotLog, ls);
03050         emcmotStatus->logPoints = emcmotLog->howmany;
03051         logIt = 0;
03052       }
03053 #endif
03054     } /* end of: if logging */
03055 
03056     /* set tail to head, which has already been incremented */
03057     emcmotStatus->tail = emcmotStatus->head;
03058     emcmotDebug->tail = emcmotDebug->head;
03059     emcmotConfig->tail = emcmotConfig->head;
03060 
03061     /* WRITE STATUS DATA */
03062 
03063 #if defined (rtlinux) && defined (RT_FIFO)
03064     /* write to rtlinux FIFO */
03065     rtf_put(EMCMOT_STATUS_RTF, &emcmotStatusBuffer, sizeof(EMCMOT_STATUS));
03066 
03067 #endif /* rtlinux and RT_FIFO */
03068 
03069 #ifdef rtlinux
03070     /* wait for next cycle */
03071 #ifdef USE_RTL2
03072     pthread_wait_np();
03073 #else
03074     rt_task_wait();
03075 #endif
03076   } /* end of: forever loop for RT task */
03077 #endif /* rtlinux */
03078 #ifdef USE_RTL2
03079   return(NULL);
03080 #endif
03081 } /* end of: emcmotController() function */

void emcmot_quit int    sig [static]
 

Definition at line 3780 of file emcstepmot.c.

03781 {
03782   emcmot_done = 1;
03783 }

int getArgs int    argc,
char *    argv[]
[static]
 

Definition at line 3790 of file emcstepmot.c.

Referenced by main().

03791 {
03792   int t;
03793   int len;
03794 
03795   for (t = 1; t < argc; t++) {
03796     /* try -ini */
03797     /* NOTE: motion controller cannot normally read an INI file.
03798        This is provided for main() simulation, which can read
03799        an INI file and needs it for the plant simulation parameters */
03800     if (!strcmp(argv[t], "-ini")) {
03801       if (t == argc - 1) {
03802         diagnostics("missing -ini parameter\n");
03803         return -1;
03804       }
03805       else {
03806         strcpy(EMCMOT_INIFILE, argv[t+1]);
03807         t++;            /* step over following arg */
03808         continue;
03809       }
03810     }
03811 
03812     /* try SHMEM_BASE_ADDRESS */
03813     len = strlen("SHMEM_BASE_ADDRESS");
03814     if (! strncmp(argv[t], "SHMEM_BASE_ADDRESS", len)) {
03815       if (argv[t][len] != '=' ||
03816           1 != sscanf(&argv[t][len + 1], "%i", &SHMEM_BASE_ADDRESS)) {
03817         diagnostics("syntax: %s SHMEM_BASE_ADDRESS=integer\n", argv[0]);
03818         return -1;
03819       }
03820       else {
03821         continue;
03822       }
03823     }
03824 
03825     /* try SHMEM_KEY */
03826     len = strlen("SHMEM_KEY");
03827     if (! strncmp(argv[t], "SHMEM_KEY", len)) {
03828       if (argv[t][len] != '=' ||
03829           1 != sscanf(&argv[t][len + 1], "%i", &SHMEM_KEY)) {
03830         diagnostics("syntax: %s SHMEM_KEY=integer\n", argv[0]);
03831         return -1;
03832       }
03833       else {
03834         continue;
03835       }
03836     }
03837 
03838     /* FIXME */
03839     /* try -noforward */
03840     if (!strcmp(argv[t], "-noforward")) {
03841       EMCMOT_NO_FORWARD_KINEMATICS = 1;
03842       continue;
03843     }
03844 
03845     /* no match-- bad arg */
03846     diagnostics("bad argument to %s: %s\n", argv[0], argv[t]);
03847     return -1;
03848   }
03849 
03850   return 0;
03851 }

int inRange EmcPose    pos [static]
 

Definition at line 762 of file emcstepmot.c.

Referenced by emcmotCommandHandler().

00763 {
00764   double joint[EMCMOT_MAX_AXIS];
00765   int axis;
00766 
00767   /* fill in all joints with 0 */
00768   for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
00769     joint[axis] = 0.0;
00770   }
00771 
00772   /* now fill in with real values, for joints that are used */
00773   kinematicsInverse(&pos, joint, &iflags, &fflags);
00774 
00775   for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
00776     if (! GET_AXIS_ACTIVE_FLAG(axis)) {
00777       /* if axis is not active, don't even look at its limits */
00778       continue;
00779     }
00780 
00781     if (joint[axis] > emcmotConfig->maxLimit[axis] ||
00782         joint[axis] < emcmotConfig->minLimit[axis]) {
00783       return 0;         /* can't move further past limit */
00784     }
00785   }
00786 
00787   /* okay to move */
00788   return 1;
00789 }

int init_module void   
 

Definition at line 3260 of file emcstepmot.c.

03261 {
03262   int axis;
03263   int t;
03264 #ifdef rtlinux
03265 #ifdef USE_RTL2
03266   hrtime_t now;
03267   pthread_attr_t attr;
03268   struct sched_param sched_param;
03269   clockid_t local_clock;
03270 #else
03271   RTIME now;
03272 #endif
03273 #endif
03274   PID_STRUCT pid;
03275 
03276 #ifdef rtlinux
03277 
03278 #ifdef RT_FIFO
03279   rtf_create(EMCMOT_COMMAND_RTF, sizeof(EMCMOT_COMMAND) + 1);
03280   rtf_create(EMCMOT_STATUS_RTF, sizeof(EMCMOT_STATUS) + 1);
03281   rtf_create(EMCMOT_ERROR_RTF, EMCMOT_ERROR_NUM * EMCMOT_ERROR_LEN + 1);
03282   /* log is created, deleted dynamically */
03283 
03284   /* fifo puts and gets work on buffer structs, so point to these */
03285   emcmotCommand = &emcmotCommandBuffer;
03286   emcmotStatus = &emcmotStatusBuffer;
03287   emcmotConfig = &emcmotConfigBuffer;
03288   emcmotDebug = &emcmotDebugBuffer;
03289 
03290 #else  /* not RT_FIFO */
03291 
03292 
03293 #ifdef USE_RTL2
03294   /* set shared memory pointer using mbuff which does not require that memory be resevered in lilo.conf */
03295   printk(KERN_INFO "calling mbuff_alloc(%s,%d)\n",
03296          "emcmotStruct",
03297          (int) sizeof(EMCMOT_STRUCT));
03298   emcmotStruct = (EMCMOT_STRUCT *) mbuff_alloc("emcmotStruct",sizeof(EMCMOT_STRUCT));
03299   printk(KERN_INFO "mbuff_alloc returned %d\n",((int) emcmotStruct));
03300 
03301 #else
03302 #ifdef rtlinux2
03303   /* set shared memory pointer using ioremap for 2.1+ kernels */
03304   emcmotStruct = (EMCMOT_STRUCT *) ioremap(SHMEM_BASE_ADDRESS, sizeof(EMCMOT_STRUCT));
03305 
03306 #else
03307   /* set shared memory pointer */
03308   emcmotStruct = (EMCMOT_STRUCT *) vremap(SHMEM_BASE_ADDRESS, sizeof(EMCMOT_STRUCT));
03309 #endif
03310 #endif
03311 
03312 #endif /* else not RT_FIFO */
03313 
03314 #else  /* not rtlinux */
03315   /* get command shmem */
03316   shmem = rcs_shm_open(SHMEM_KEY, sizeof(EMCMOT_STRUCT), 1, 0666);
03317   if (NULL == shmem ||
03318       NULL == shmem->addr)
03319     {
03320       diagnostics("can't get shared memory\n");
03321       return -1;
03322     }
03323 
03324   memset(shmem->addr, 0, sizeof(EMCMOT_STRUCT));
03325   /* map shmem area into local address space */
03326   emcmotStruct = (EMCMOT_STRUCT *) shmem->addr;
03327 
03328 #endif /* else not rtlinux */
03329 
03330 #ifndef RT_FIFO
03331   /* we'll reference emcmotStruct directly */
03332   emcmotCommand = (EMCMOT_COMMAND *) &emcmotStruct->command;
03333   emcmotStatus = (EMCMOT_STATUS *) &emcmotStruct->status;
03334   emcmotConfig = (EMCMOT_CONFIG *) &emcmotStruct->config;
03335   emcmotDebug = (EMCMOT_DEBUG *) &emcmotStruct->debug;
03336   emcmotError = (EMCMOT_ERROR *) &emcmotStruct->error;
03337   emcmotLog = (EMCMOT_LOG *) &emcmotStruct->log;
03338   for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03339     emcmotComp[axis] = (EMCMOT_COMP *) &emcmotStruct->comp[axis];
03340   }
03341 
03342   /* zero shared memory */
03343   for (t = 0; t < sizeof(EMCMOT_STRUCT); t++) {
03344     ((char *) emcmotStruct)[t] = 0;
03345   }
03346 #endif /* not RT_FIFO */
03347 
03348   /* init locals */
03349   for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03350     maxLimitSwitchCount[axis] = 0;
03351     minLimitSwitchCount[axis] = 0;
03352     ampFaultCount[axis] = 0;
03353 #ifdef STEPPER_MOTORS
03354     smStepsPerUnit[axis] = INPUT_SCALE;
03355     smMagUnitsPerStep[axis] = fabs(1.0 / INPUT_SCALE);
03356     emcmotDebug->stepperCount[axis] = 0;
03357     smNewCycle[axis] = 1;
03358 #endif
03359   }
03360 
03361 #ifndef RT_FIFO
03362   /* init compensation struct */
03363   for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03364     emcmotComp[axis]->total = 0;
03365     emcmotComp[axis]->alter = 0.0;
03366     /* leave out the avgint, nominal, forward, and reverse, since
03367        these can't be zero and the total flag prevents their use anyway */
03368   }
03369 
03370   /* init error struct */
03371   emcmotErrorInit(emcmotError);
03372 #endif /* not RT_FIFO */
03373 
03374   /* init command struct */
03375   emcmotCommand->head = 0;
03376   emcmotCommand->command = 0;
03377   emcmotCommand->commandNum = 0;
03378   emcmotCommand->tail = 0;
03379 
03380   /* init status struct */
03381 
03382   emcmotStatus->head = 0;
03383   emcmotConfig->head = 0;
03384   emcmotDebug->head = 0;
03385 
03386   emcmotStatus->motionFlag = 0;
03387   SET_MOTION_ERROR_FLAG(0);
03388   SET_MOTION_COORD_FLAG(0);
03389   emcmotDebug->split = 0;
03390   emcmotStatus->commandEcho = 0;
03391   emcmotStatus->commandNumEcho = 0;
03392   emcmotStatus->commandStatus = 0;
03393   emcmotStatus->heartbeat = 0;
03394   emcmotStatus->computeTime = 0.0;
03395   emcmotConfig->numAxes = EMCMOT_MAX_AXIS;
03396   emcmotConfig->trajCycleTime = TRAJ_CYCLE_TIME;
03397   emcmotConfig->servoCycleTime = SERVO_CYCLE_TIME;
03398   emcmotStatus->pos.tran.x = 0.0;
03399   emcmotStatus->pos.tran.y = 0.0;
03400   emcmotStatus->pos.tran.z = 0.0;
03401   emcmotStatus->actualPos.tran.x = 0.0;
03402   emcmotStatus->actualPos.tran.y = 0.0;
03403   emcmotStatus->actualPos.tran.z = 0.0;
03404   emcmotStatus->vel = VELOCITY;
03405   emcmotConfig->limitVel = VELOCITY;
03406   emcmotStatus->acc = ACCELERATION;
03407   emcmotStatus->qVscale = 1.0;
03408   emcmotStatus->id = 0;
03409   emcmotStatus->depth = 0;
03410   emcmotStatus->activeDepth = 0;
03411   emcmotStatus->paused = 0;
03412   emcmotStatus->overrideLimits = 0;
03413   SET_MOTION_INPOS_FLAG(1);
03414   emcmotStatus->logOpen = 0;
03415   emcmotStatus->logStarted = 0;
03416   emcmotStatus->logSize = 0;
03417   emcmotStatus->logSkip = 0;
03418   emcmotStatus->logPoints = 0;
03419   SET_MOTION_ENABLE_FLAG(0);
03420 
03421   oldPos = emcmotStatus->pos;
03422   oldVel.tran.x = 0.0;
03423   oldVel.tran.y = 0.0;
03424   oldVel.tran.z = 0.0;
03425 
03426   for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03427     emcmotConfig->homingVel[axis] = VELOCITY;
03428     emcmotConfig->homeOffset[axis] = 0.0;
03429     emcmotStatus->axisFlag[axis] = 0;
03430     emcmotConfig->maxLimit[axis] = MAX_LIMIT;
03431     emcmotConfig->minLimit[axis] = MIN_LIMIT;
03432     emcmotConfig->maxOutput[axis] = MAX_OUTPUT;
03433     emcmotConfig->minOutput[axis] = MIN_OUTPUT;
03434     emcmotConfig->minFerror[axis] = 0.0; /* gives a true linear ferror */
03435     emcmotConfig->maxFerror[axis] = MAX_FERROR;
03436     emcmotDebug->ferrorCurrent[axis] = 0.0;
03437     emcmotDebug->ferrorHighMark[axis] = 0.0;
03438     emcmotStatus->outputScale[axis] = OUTPUT_SCALE;
03439     emcmotStatus->outputOffset[axis] = OUTPUT_OFFSET;
03440     emcmotStatus->inputScale[axis] = INPUT_SCALE;
03441     inverseInputScale[axis] = 1.0 / INPUT_SCALE;
03442     emcmotStatus->inputOffset[axis] = INPUT_OFFSET;
03443     inverseOutputScale[axis] = 1.0 / OUTPUT_SCALE;
03444     emcmotStatus->axVscale[axis] = 1.0;
03445     SET_AXIS_ENABLE_FLAG(axis, 0);
03446     SET_AXIS_ACTIVE_FLAG(axis, 0); /* default is not to use it; need an
03447                                       explicit activate */
03448     SET_AXIS_NSL_FLAG(axis, 0);
03449     SET_AXIS_PSL_FLAG(axis, 0);
03450     SET_AXIS_NHL_FLAG(axis, 0);
03451     SET_AXIS_PHL_FLAG(axis, 0);
03452     SET_AXIS_INPOS_FLAG(axis, 1);
03453     SET_AXIS_HOMING_FLAG(axis, 0);
03454     SET_AXIS_HOMED_FLAG(axis, 0);
03455     SET_AXIS_FERROR_FLAG(axis, 0);
03456     SET_AXIS_FAULT_FLAG(axis, 0);
03457     SET_AXIS_ERROR_FLAG(axis, 0);
03458     emcmotConfig->axisPolarity[axis] = (EMCMOT_AXIS_FLAG) 0xFFFFFFFF;
03459     /* will read encoders directly, so don't set them here */
03460   }
03461 
03462   /* FIXME-- add emcmotError */
03463 
03464   /* init min-max-avg stats */
03465   mmxavgInit(&emcmotDebug->tMmxavg, emcmotDebug->tMmxavgSpace, MMXAVG_SIZE);
03466   mmxavgInit(&emcmotDebug->sMmxavg, emcmotDebug->sMmxavgSpace, MMXAVG_SIZE);
03467   mmxavgInit(&emcmotDebug->nMmxavg, emcmotDebug->nMmxavgSpace, MMXAVG_SIZE);
03468   emcmotDebug->tMin = 0.0;
03469   emcmotDebug->tMax = 0.0;
03470   emcmotDebug->tAvg = 0.0;
03471   emcmotDebug->sMin = 0.0;
03472   emcmotDebug->sMax = 0.0;
03473   emcmotDebug->sAvg = 0.0;
03474   emcmotDebug->nMin = 0.0;
03475   emcmotDebug->nMax = 0.0;
03476   emcmotDebug->nAvg = 0.0;
03477 
03478   /* init motion queue */
03479   if (-1 == tpCreate(&queue, DEFAULT_TC_QUEUE_SIZE, queueTcSpace)) {
03480     diagnostics("can't create motion queue\n");
03481     return -1;
03482   }
03483   tpInit(&queue);
03484   tpSetCycleTime(&queue, emcmotConfig->trajCycleTime);
03485   tpSetPos(&queue, emcmotStatus->pos);
03486   tpSetVmax(&queue, emcmotStatus->vel);
03487   tpSetAmax(&queue, emcmotStatus->acc);
03488 
03489   /* init the axis components */
03490   pid.p = P_GAIN;
03491   pid.i = I_GAIN;
03492   pid.d = D_GAIN;
03493   pid.ff0 = FF0_GAIN;
03494   pid.ff1 = FF1_GAIN;
03495   pid.ff2 = FF2_GAIN;
03496   pid.backlash = BACKLASH;
03497   pid.bias = BIAS;
03498   pid.maxError = MAX_ERROR;
03499 
03500   for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03501     if (-1 == tpCreate(&freeAxis[axis], FREE_AXIS_QUEUE_SIZE, freeAxisTcSpace[axis])) {
03502       diagnostics("can't create axis queue %d\n", axis);
03503       return -1;
03504     }
03505     tpInit(&freeAxis[axis]);
03506     tpSetCycleTime(&freeAxis[axis], emcmotConfig->trajCycleTime);
03507     /* freePose is inited to 0's in decl */
03508     tpSetPos(&freeAxis[axis], freePose);
03509     tpSetVmax(&freeAxis[axis], emcmotStatus->vel);
03510     tpSetAmax(&freeAxis[axis], emcmotStatus->acc);
03511 #ifndef STEPPER_MOTORS
03512     pidInit(&emcmotConfig->pid[axis]);
03513     pidSetGains(&emcmotConfig->pid[axis], pid);
03514 #endif
03515     cubicInit(&cubic[axis]);
03516   }
03517 
03518   /* init the time and rate using functions to affect traj, the
03519      pids, and the cubics properly, since they're coupled */
03520   setTrajCycleTime(TRAJ_CYCLE_TIME);
03521   setServoCycleTime(SERVO_CYCLE_TIME);
03522 
03523   /* init board */
03524   if (-1 == extMotInit((const char *) 0)) {
03525     diagnostics("can't initialize motion hardware\n");
03526     return -1;
03527   }
03528   if (-1 == extDioInit((const char *) 0)) {
03529     diagnostics("can't initialize DIO hardware\n");
03530     return -1;
03531   }
03532   if (-1 == extAioInit((const char *) 0)) {
03533     diagnostics("can't initialize AIO hardware\n");
03534     return -1;
03535   }
03536 
03537   /* record the kinematics type of the machine */
03538   kinType = kinematicsType();
03539 
03540   extEncoderSetIndexModel(EXT_ENCODER_INDEX_MODEL_MANUAL);
03541   for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03542     rawInput[axis] = 0.0;
03543     rawOutput[axis] = 0.0;
03544     coarseJointPos[axis] = 0.0;
03545     jointPos[axis] = 0.0;
03546     jointVel[axis] = 0.0;
03547     emcmotStatus->axisPos[axis] = 0.0;
03548     oldJointPos[axis] = 0.0;
03549 
03550     waitingForLatch[axis] = 0;
03551     latchFlag[axis] = 0;
03552     saveLatch[axis] = 0.0;
03553 
03554     emcmotStatus->input[axis] = 0.0;
03555     oldInput[axis] = 0.0;
03556     emcmotStatus->output[axis] = 0.0;
03557 
03558     jointHome[axis] = 0.0;
03559 
03560     extAmpEnable(axis,
03561                  ! GET_AXIS_ENABLE_POLARITY(axis));
03562   }
03563 
03564   emcmotStatus->tail = 0;
03565 
03566 #ifdef rtlinux
03567 
03568 
03569 #ifdef USE_RTL2
03570   local_clock = rtl_getschedclock();
03571 
03572 #if 0
03573   if(!rtl_setclockmode(local_clock, RTL_CLOCK_MODE_PERIODIC, 20000))
03574     {
03575     diagnostics("can't set periodic mode\n");
03576   }
03577 #else
03578   rtl_setclockmode(local_clock, RTL_CLOCK_MODE_ONESHOT,0);
03579 #endif
03580 
03581 #else // RTL before version 2
03582 #if 0
03583   if (RT_TIME_END == rtl_set_periodic_mode(20)) {
03584     diagnostics("can't set periodic mode\n");
03585   }
03586 #else
03587   rtl_set_oneshot_mode();
03588 #endif
03589 
03590 #endif
03591 
03592 #ifdef USE_RTL2
03593   pthread_attr_init (&attr);
03594   sched_param.sched_priority = RT_TASK_PRIORITY;
03595   pthread_attr_setschedparam (&attr, &sched_param);
03596   attr.use_fp = 1;
03597   attr.stack_size = RT_TASK_STACK_SIZE;
03598   pthread_create( &emcmotTask, &attr, emcmotController, (void *) 1);
03599 
03600   /* get current time as base for starting tasks */
03601   now =gethrtime();
03602 
03603   pthread_setfp_np(emcmotTask,1);
03604   pthread_make_periodic_np(emcmotTask,
03605                            now + 0.010*HRTICKS_PER_SEC,
03606                            (hrtime_t) (HRTICKS_PER_SEC *
03607                                        emcmotConfig->servoCycleTime));
03608 #else
03609 
03610   /* init control task */
03611   rt_task_init(&emcmotTask,     /* RT_TASK * */
03612                emcmotController, /* task code */
03613                0,               /* startup arg to task code */
03614                RT_TASK_STACK_SIZE, /* task stack size */
03615                RT_TASK_PRIORITY); /* priority */
03616 
03617   /* make sure we save FP context */
03618   rt_task_use_fp(&emcmotTask, 1);
03619 
03620   /* get current time as base for starting tasks */
03621   now = rt_get_time();
03622 
03623   /* schedule control task to run */
03624   rt_task_make_periodic(&emcmotTask,
03625                         now + SECS_TO_RTIME(0.010),
03626                         (RTIME) (RT_TICKS_PER_SEC *
03627                                  emcmotConfig->servoCycleTime));
03628 
03629 
03630 #endif
03631 
03632 
03633 
03634 #ifdef STEPPER_MOTORS
03635 
03636 
03637   /* schedule stepper task to run at 1/(V*P), where V is max velocity
03638      and P is the max stepper pulses per unit among all axes, i.e.,
03639      inputScale. Note that this is also done whenever limit vel or input
03640      scales are changed */
03641   smVPmax = VELOCITY * INPUT_SCALE; /* use defaults at first */
03642   smMaxStepsPerUnit = INPUT_SCALE;
03643   /* set the period to twice the max pulse rate. It need only
03644      be the same as the pulse rate, but this makes it the same
03645      as before */
03646   smCycleTime = 0.5/smVPmax;
03647   smCyclesPerAxis = (int) (emcmotConfig->servoCycleTime / smCycleTime);
03648 
03649 
03650 #ifdef USE_RTL2
03651   pthread_attr_init (&attr);
03652   sched_param.sched_priority = SM_TASK_PRIORITY;
03653   pthread_attr_setschedparam (&attr, &sched_param);
03654   attr.use_fp = 1;
03655   attr.stack_size = SM_TASK_STACK_SIZE;
03656   pthread_create( &smTask, &attr, smController, NULL);
03657 
03658   /* get current time as base for starting tasks */
03659   now =gethrtime();
03660 
03661   pthread_setfp_np(emcmotTask,1);
03662   pthread_make_periodic_np(emcmotTask,
03663                            now + 0.010*HRTICKS_PER_SEC,
03664                            (hrtime_t) (HRTICKS_PER_SEC *
03665                                        smCycleTime));
03666 
03667 #else
03668 
03669   /* init stepper motor task */
03670   rt_task_init(&smTask, /* RT_TASK * */
03671                smController, /* task code */
03672                0,               /* startup arg to task code */
03673                SM_TASK_STACK_SIZE, /* task stack size */
03674                SM_TASK_PRIORITY); /* priority */
03675 
03676   /* make sure we save FP context */
03677   rt_task_use_fp(&smTask, 1);
03678 
03679   rt_task_make_periodic(&smTask,
03680                         now + SECS_TO_RTIME(0.010),
03681                         ((RTIME) (RT_TICKS_PER_SEC * smCycleTime)));
03682 
03683 #endif
03684 #endif
03685 
03686   /* FIXME */
03687   diagnostics("inited emcmot\n");
03688 
03689 #endif /* rtlinux */
03690 
03691 #if defined (rtlinux) && defined (RT_FIFO)
03692   /* create user process handler on control channel */
03693   rtf_create_handler(EMCMOT_COMMAND_RTF, /* fifo number */
03694                      emcmotCommandHandler /* control message handler */
03695                      );
03696 
03697 #endif /* rtlinux and RT_FIFO */
03698 
03699   return 0;
03700 }

int isHoming void    [static]
 

Definition at line 743 of file emcstepmot.c.

00744 {
00745   int axis;
00746 
00747   for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
00748     if (GET_AXIS_HOMING_FLAG(axis)) {
00749       return 1;
00750     }
00751   }
00752 
00753   /* got here, so none are homing */
00754   return 0;
00755 }

int main int    argc,
char *    argv[]
 

Definition at line 3861 of file emcstepmot.c.

03865 {
03866   double delta;                 /* elapsed time */
03867 
03868 #ifndef UNDER_CE
03869   /* trap ^C */
03870   signal(SIGINT, emcmot_quit);
03871 
03872   /* process command line args */
03873   if (0 != getArgs(argc, argv)) {
03874     diagnostics("can't init module-- bad arguments\n");
03875     exit(1);
03876   }
03877 #endif
03878 
03879   /* set up data structs */
03880   if (-1 == init_module()) {
03881     diagnostics("can't init module-- execution permission problems?\n");
03882 #ifndef UNDER_CE
03883     exit(1);
03884 #else
03885     return 1;
03886 #endif
03887   }
03888 
03889   while (! emcmot_done) {
03890     delta = etime();
03891     emcmotController(0);
03892     delta = etime() - delta;
03893     delta = emcmotConfig->servoCycleTime - delta;
03894 
03895     if (delta > 0.0) {
03896       esleep(delta);
03897     }
03898   }
03899 
03900   cleanup_module();
03901 #ifndef UNDER_CE
03902   exit(0);
03903 #else
03904   return 0;
03905 #endif
03906 }

void reportError const char *    fmt,
...   
[static]
 

Definition at line 720 of file emcstepmot.c.

Referenced by checkJog(), emcmotCommandHandler(), and emcmotController().

00721 {
00722   va_list args;
00723   char error[EMCMOT_ERROR_LEN];
00724 
00725   va_start(args, fmt);
00726 #ifndef UNDER_CE
00727   vsprintf(error, fmt, args);
00728 #else
00729   RCS_CE_VSPRINTF(error,fmt,args);
00730 #endif
00731   va_end(args);
00732 
00733 #if defined (rtlinux) && defined (RT_FIFO)
00734   rtf_put(EMCMOT_ERROR_RTF, error, EMCMOT_ERROR_LEN);
00735 
00736 #else
00737   emcmotErrorPut(emcmotError, error);
00738 
00739 #endif
00740 }

void setServoCycleTime double    secs [static]
 

Definition at line 884 of file emcstepmot.c.

Referenced by emcmotCommandHandler(), and init_module().

00885 {
00886   static int t;
00887 
00888   /* make sure it's not zero */
00889   if (secs <= 0.0) {
00890     return;
00891   }
00892 
00893   MARK_EMCMOT_CONFIG_CHANGE();
00894 
00895   /* compute the interpolation rate as nearest integer to traj/servo*/
00896   emcmotConfig->interpolationRate =
00897     (int) (emcmotConfig->trajCycleTime / secs + 0.5);
00898 
00899   /* set the cubic interpolation rate and PID cycle time */
00900   for (t = 0; t < EMCMOT_MAX_AXIS; t++) {
00901     cubicSetInterpolationRate(&cubic[t], emcmotConfig->interpolationRate);
00902     cubicSetSegmentTime(&cubic[t], secs);
00903 #ifndef STEPPER_MOTORS
00904     pidSetCycleTime(&emcmotConfig->pid[t], secs);
00905 #endif
00906   }
00907 
00908   /* copy into status out */
00909   emcmotConfig->servoCycleTime = secs;
00910 
00911 #ifdef STEPPER_MOTORS
00912   smCyclesPerAxis = (int) (emcmotConfig->servoCycleTime / smCycleTime);
00913 #endif
00914 }

void setTrajCycleTime double    secs [static]
 

Definition at line 855 of file emcstepmot.c.

Referenced by emcmotCommandHandler(), and init_module().

00856 {
00857   static int t;
00858 
00859   /* make sure it's not zero */
00860   if (secs <= 0.0) {
00861     return;
00862   }
00863   MARK_EMCMOT_CONFIG_CHANGE();
00864 
00865 
00866   /* compute the interpolation rate as nearest integer to traj/servo*/
00867   emcmotConfig->interpolationRate =
00868     (int) (secs / emcmotConfig->servoCycleTime + 0.5);
00869 
00870   /* set traj planner */
00871   tpSetCycleTime(&queue, secs);
00872 
00873   /* set the free planners, cubic interpolation rate and segment time */
00874   for (t = 0; t < EMCMOT_MAX_AXIS; t++) {
00875     tpSetCycleTime(&freeAxis[t], secs);
00876     cubicSetInterpolationRate(&cubic[t], emcmotConfig->interpolationRate);
00877   }
00878 
00879   /* copy into status out */
00880   emcmotConfig->trajCycleTime = secs;
00881 }


Variable Documentation

int EMCMOT_NO_FORWARD_KINEMATICS = 0
 

Definition at line 1904 of file emcstepmot.c.

unsigned char allHomed = 0 [static]
 

Definition at line 467 of file emcstepmot.c.

int ampFaultCount[EMCMOT_MAX_AXIS] [static]
 

Definition at line 488 of file emcstepmot.c.

double bigVel = 1.0 [static]
 

Definition at line 646 of file emcstepmot.c.

double coarseJointPos[EMCMOT_MAX_AXIS] [static]
 

Definition at line 632 of file emcstepmot.c.

int coordinating = 0 [static]
 

Definition at line 653 of file emcstepmot.c.

CUBIC_STRUCT cubic[EMCMOT_MAX_AXIS] [static]
 

Definition at line 621 of file emcstepmot.c.

EMCMOT_COMMAND* emcmotCommand [static]
 

Definition at line 442 of file emcstepmot.c.

EMCMOT_COMP* emcmotComp[EMCMOT_MAX_AXIS] [static]
 

Definition at line 451 of file emcstepmot.c.

EMCMOT_CONFIG* emcmotConfig [static]
 

Definition at line 444 of file emcstepmot.c.

EMCMOT_DEBUG* emcmotDebug [static]
 

Definition at line 445 of file emcstepmot.c.

EMCMOT_ERROR* emcmotError [static]
 

Definition at line 449 of file emcstepmot.c.

EMCMOT_LOG* emcmotLog [static]
 

Definition at line 450 of file emcstepmot.c.

EMCMOT_STATUS* emcmotStatus [static]
 

Definition at line 443 of file emcstepmot.c.

EMCMOT_STRUCT* emcmotStruct
 

Definition at line 431 of file emcstepmot.c.

int emcmot_done = 0
 

Definition at line 3779 of file emcstepmot.c.

int enabling = 0 [static]
 

Definition at line 652 of file emcstepmot.c.

KINEMATICS_FORWARD_FLAGS fflags = 0 [static]
 

Definition at line 477 of file emcstepmot.c.

TP_STRUCT freeAxis[EMCMOT_MAX_AXIS] [static]
 

Definition at line 616 of file emcstepmot.c.

TC_STRUCT freeAxisTcSpace[EMCMOT_MAX_AXIS][FREE_AXIS_QUEUE_SIZE] [static]
 

Definition at line 627 of file emcstepmot.c.

EmcPose freePose = {{0.0, 0.0, 0.0}, 0.0, 0.0, 0.0} [static]
 

Definition at line 620 of file emcstepmot.c.

int idForStep = 0 [static]
 

Definition at line 667 of file emcstepmot.c.

KINEMATICS_INVERSE_FLAGS iflags = 0 [static]
 

Definition at line 478 of file emcstepmot.c.

int interpolationCounter = 0 [static]
 

Definition at line 852 of file emcstepmot.c.

double inverseInputScale[EMCMOT_MAX_AXIS] [static]
 

Definition at line 639 of file emcstepmot.c.

double inverseOutputScale[EMCMOT_MAX_AXIS] [static]
 

Definition at line 640 of file emcstepmot.c.

double jointHome[EMCMOT_MAX_AXIS] [static]
 

Definition at line 470 of file emcstepmot.c.

double jointPos[EMCMOT_MAX_AXIS] [static]
 

Definition at line 633 of file emcstepmot.c.

double jointVel[EMCMOT_MAX_AXIS] [static]
 

Definition at line 634 of file emcstepmot.c.

int kinType = 0 [static]
 

Definition at line 481 of file emcstepmot.c.

int latchFlag[EMCMOT_MAX_AXIS] [static]
 

Definition at line 649 of file emcstepmot.c.

int logIt = 0 [static]
 

Definition at line 457 of file emcstepmot.c.

int logSkip = 0 [static]
 

Definition at line 455 of file emcstepmot.c.

int loggingAxis = 0 [static]
 

Definition at line 456 of file emcstepmot.c.

EMCMOT_LOG_STRUCT ls [static]
 

Definition at line 454 of file emcstepmot.c.

int maxLimitSwitchCount[EMCMOT_MAX_AXIS] [static]
 

Definition at line 485 of file emcstepmot.c.

int minLimitSwitchCount[EMCMOT_MAX_AXIS] [static]
 

Definition at line 486 of file emcstepmot.c.

EmcPose newAcc [static]
 

Definition at line 643 of file emcstepmot.c.

EmcPose newVel [static]
 

Definition at line 642 of file emcstepmot.c.

double oldInput[EMCMOT_MAX_AXIS] [static]
 

Definition at line 636 of file emcstepmot.c.

double oldJointPos[EMCMOT_MAX_AXIS] [static]
 

Definition at line 635 of file emcstepmot.c.

EmcPose oldPos [static]
 

Definition at line 641 of file emcstepmot.c.

EmcPose oldVel [static]
 

Definition at line 642 of file emcstepmot.c.

int onLimit = 0 [static]
 

Definition at line 660 of file emcstepmot.c.

int overriding = 0 [static]
 

Definition at line 663 of file emcstepmot.c.

TP_STRUCT queue [static]
 

Definition at line 611 of file emcstepmot.c.

TC_STRUCT queueTcSpace[DEFAULT_TC_QUEUE_SIZE + 10] [static]
 

Definition at line 625 of file emcstepmot.c.

double rawInput[EMCMOT_MAX_AXIS] [static]
 

Definition at line 629 of file emcstepmot.c.

double rawOutput[EMCMOT_MAX_AXIS] [static]
 

Definition at line 630 of file emcstepmot.c.

double saveLatch[EMCMOT_MAX_AXIS] [static]
 

Definition at line 650 of file emcstepmot.c.

shm_t* shmem = NULL [static]
 

Definition at line 435 of file emcstepmot.c.

int stepping = 0 [static]
 

Definition at line 666 of file emcstepmot.c.

int waitingForLatch[EMCMOT_MAX_AXIS] [static]
 

Definition at line 648 of file emcstepmot.c.

int wasOnLimit = 0 [static]
 

Definition at line 655 of file emcstepmot.c.

int wdCount = 0 [static]
 

Definition at line 463 of file emcstepmot.c.

int wdEnabled = 0 [static]
 

Definition at line 461 of file emcstepmot.c.

int wdEnabling = 0 [static]
 

Definition at line 460 of file emcstepmot.c.

unsigned char wdToggle = 0 [static]
 

Definition at line 464 of file emcstepmot.c.

int wdWait = 0 [static]
 

Definition at line 462 of file emcstepmot.c.

EmcPose worldHome [static]
 

Initial value:

 {{0.0, 0.0, 0.0},
                           0.0, 0.0, 0.0}

Definition at line 473 of file emcstepmot.c.


Generated on Sun Dec 2 15:28:01 2001 for EMC by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001