00001 #ifndef EMCMOT_H 00002 #define EMCMOT_H 00003 00004 /* 00005 emcmot.h 00006 00007 Decls of data structures for motion controller 00008 00009 Modification history: 00010 00011 17-Aug-2001 FMP added EMCMOT_SET_AOUT,DOUT 00012 15-Aug-2001 FMP added EMCMOT_SET_AXIS_VEL_LIMIT, to distinguish between 00013 trajectory limit and axis limits 00014 10-Aug-2001 FMP added jacobianForward() 00015 9-Aug-2001 FMP added kinematicsSetParameters() 00016 1-Jun-2001 FMP added EMCMOT_SET_DEBUG as command, put 'debug' in config 00017 status 00018 31-May-2001 FMP took decls of init_module(), cleanup_module() out 00019 altogether, since they're only called from within the file in which 00020 they're defined. 00021 cleanup_module that Terry Ridder added 00022 21-May-2001 FMP took out FIFO stuff, since it's no longer used 00023 18-May-2001 WPS moved alot of stuff into the emcmotDebug structure 00024 which is copied into shared memory. The Task level doesn't use this 00025 but it will hopefully make debugging some problems easier. 00026 25-Oct-2000 terrylr added if defined conditional using EMCMOT_C & 00027 EMCSTEPMOT_C to allow for the correct declaration of init_module & 00028 cleanup_module. 00029 15-Aug-2000 FMP added alter[] to EMCMOT_COMP struct, for dynamic altering 00030 of compensation points by external processes, e.g., thermal comp 00031 10-Aug-2000 FMP changed comp table structure a bit, removing fwd,revavgint 00032 in favor of a single avgint, to do input comp rather than output comp. 00033 8-Aug-2000 FMP added EMCMOT_COMP compensation table 00034 27-Jul-2000 WPS added probing commands and status variables. 00035 30-Mar-2000 WPS added ferrorCurrent and changed the name of ferror to 00036 ferrorHighMark in EMCMOT_STATUS struct. 00037 30-Sep-1999 FMP added EMCMOT_OVERRIDE_LIMITS cmd 00038 29-Sep-1999 FMP added homeOffset[] to status, EMCMOT_SET_HOME_OFFSET to cmd 00039 29-Sep-1999 WPS added decl of emcmot_done for Windows CE 00040 9-Aug-1999 FMP added EMCMOT_SET_WORLD_HOME, EMCMOT_SET_JOINT_HOME, and 00041 decls for revised syntax for kinematics 00042 14-Jul-1999 FMP rearranged EMCMOT_STATUS into dynamic and static sections, 00043 in prep for dual head-tail flags 00044 16-Jun-1999 FMP added axisPos[] to status, for calculated axis positions 00045 resulting from inverse kinematics 00046 8-Jun-1999 FMP took out SET_SM_CYCLE_TIME since we set the stepper 00047 motor cycle time to twice the servo cycle time; added EMCMOT_SET_MAX_VEL 00048 to set the maximum speed that all effective velocities, including their 00049 feed override if >1, will be limited to; added limitVel to status 00050 8-May-1999 FMP changed #ifdef rtlinux_O9J to rtlinux_09J, that is, 00051 "oh" to "zero". 00052 25-Feb-1999 FMP added commandEcho to status 00053 7-Feb-1999 FMP changed comment for status ferror to be mag of max ferror 00054 4-Feb-1999 RSB changed FIFO numbering from 0-3 to 1-4 for rtlinux-9J 00055 7-Oct-1998 FMP added homing vel stuff 00056 5-Aug-1998 FMP took out decl of emcmotController(), since it need only 00057 be static in emcmot.c 00058 8-Jul-1998 FMP added logPoints to status 00059 6-Jul-1998 FMP added emcmotGetArgs decl 00060 3-Apr-1998 FMP added active axis concept, with EMCMOT_AXIS_ACTIVE_BIT 00061 2-Apr-1998 FMP added EMCMOT_ENABLE,DISABLE_AXIS for calcs 00062 25-Mar-1998 FMP reversed wrong error ring buffer indices 00063 25-Feb-1998 FMP added AXIS_ERROR_FLAG 00064 10-Feb-1998 FMP added RTF decls back in 00065 6-Feb-1998 FMP added log types 00066 15-Nov-1997 FMP added home switch bit to axis status 00067 16-Oct-1997 FMP added kinematics prototype decls 00068 10-Oct-1997 FMP added min-max-avg status 00069 29-Aug-1997 WPS added EMCMOT_STEP, and paused to EMCMOT_STATUS 00070 27-Aug-1997 WPS added queueFull to EMCMOT_STATUS 00071 01-Aug-1997 FMP added min,maxOutput 00072 28-Jul-1997 FMP added bitflag status words motionFlag, axisFlag; 00073 moved all bit status into them; added EMCMOT_LOG_FILE_NAME; 00074 17-Jul-1997 FMP added EMCMOT_ERROR_SHMKEY 00075 25-Jun-1997 FMP added EMCMOT_COORD,FREE mode 00076 11-Jun-1997 FMP added index pulse homing 00077 10-Jun-1997 FMP added Servo To Go encoder/amp testing 00078 2-May-1997 FMP added EMCMOT_*_LOG stuff 00079 17-Apr-1997 FMP added computeTime to status 00080 16-Apr-1997 FMP created 00081 */ 00082 00083 #define ENABLE_PROBING 00084 00085 #include "posemath.h" /* PmCartesian */ 00086 #include "emcpos.h" 00087 #include "cubic.h" /* CUBIC_STRUCT */ 00088 #include "pid.h" /* PID_STRUCT */ 00089 #include "emcmotcfg.h" /* EMCMOT_MAX_AXIS */ 00090 #include "emcmotlog.h" 00091 #include "emcpos.h" /* EmcPose */ 00092 #include "tp.h" /* TP_STRUCT */ 00093 #include "tc.h" /* TC_STRUCT */ 00094 #include "mmxavg.h" /* MMXAVG_STRUCT */ 00095 00096 #ifdef __cplusplus 00097 extern "C" { 00098 #endif 00099 00100 /* motion flag type */ 00101 typedef unsigned short EMCMOT_MOTION_FLAG; 00102 00103 /* axis flag type */ 00104 typedef unsigned short EMCMOT_AXIS_FLAG; 00105 00106 /* commands */ 00107 enum { 00108 EMCMOT_SET_TRAJ_CYCLE_TIME = 1, /* set the cycle time */ 00109 EMCMOT_SET_SERVO_CYCLE_TIME, /* set the interpolation rate */ 00110 EMCMOT_SET_POSITION_LIMITS, /* set the axis position +/- limits */ 00111 EMCMOT_SET_OUTPUT_LIMITS, /* set the axis output +/- limits */ 00112 EMCMOT_SET_OUTPUT_SCALE, /* scale factor for outputs */ 00113 EMCMOT_SET_INPUT_SCALE, /* scale factor for inputs */ 00114 EMCMOT_SET_MIN_FERROR, /* minimum following error, input units */ 00115 EMCMOT_SET_MAX_FERROR, /* maximum following error, input units */ 00116 EMCMOT_JOG_CONT, /* continuous jog */ 00117 EMCMOT_JOG_INCR, /* incremental jog */ 00118 EMCMOT_JOG_ABS, /* absolute jog */ 00119 EMCMOT_SET_LINE, /* queue up a linear move */ 00120 EMCMOT_SET_CIRCLE, /* queue up a circular move */ 00121 EMCMOT_SET_VEL, /* set the velocity for subsequent moves */ 00122 EMCMOT_SET_VEL_LIMIT, /* set the absolute max vel for all moves */ 00123 EMCMOT_SET_AXIS_VEL_LIMIT, /* set the absolute max vel for each axis */ 00124 EMCMOT_SET_ACC, /* set the acceleration for moves */ 00125 EMCMOT_PAUSE, /* pause motion */ 00126 EMCMOT_RESUME, /* resume motion */ 00127 EMCMOT_STEP, /* resume motion until id encountered */ 00128 EMCMOT_ABORT, /* abort motion */ 00129 EMCMOT_SCALE, /* scale the speed */ 00130 EMCMOT_ENABLE, /* enable servos for active axes */ 00131 EMCMOT_DISABLE, /* disable servos for active axes */ 00132 EMCMOT_SET_PID, /* set PID gains */ 00133 EMCMOT_ENABLE_AMPLIFIER, /* enable amp outputs and dac writes */ 00134 EMCMOT_DISABLE_AMPLIFIER, /* disable amp outputs and dac writes */ 00135 EMCMOT_OPEN_LOG, /* open a log */ 00136 EMCMOT_START_LOG, /* start logging */ 00137 EMCMOT_STOP_LOG, /* stop logging */ 00138 EMCMOT_CLOSE_LOG, /* close log */ 00139 EMCMOT_DAC_OUT, /* write directly to the dacs */ 00140 EMCMOT_HOME, /* home an axis */ 00141 EMCMOT_FREE, /* set mode to free (joint) motion */ 00142 EMCMOT_COORD, /* set mode to coordinated motion */ 00143 EMCMOT_TELEOP, /* set mode to teleop*/ 00144 EMCMOT_ENABLE_WATCHDOG, /* enable watchdog sound, parport */ 00145 EMCMOT_DISABLE_WATCHDOG, /* enable watchdog sound, parport */ 00146 EMCMOT_SET_POLARITY, /* set polarity for axis flags */ 00147 EMCMOT_ACTIVATE_AXIS, /* make axis active */ 00148 EMCMOT_DEACTIVATE_AXIS, /* make axis inactive */ 00149 EMCMOT_SET_TERM_COND, /* set termination condition (stop, blend) */ 00150 EMCMOT_SET_HOMING_VEL, /* set the axis homing speed */ 00151 EMCMOT_SET_NUM_AXES, /* set the number of axes */ 00152 EMCMOT_SET_WORLD_HOME, /* set pose for world home */ 00153 EMCMOT_SET_JOINT_HOME, /* set value for joint homes */ 00154 EMCMOT_SET_HOME_OFFSET, /* where to go after a home */ 00155 EMCMOT_OVERRIDE_LIMITS, /* temporarily ignore limits until jog done */ 00156 EMCMOT_SET_TELEOP_VECTOR, /* Move at a given velocity but in 00157 world cartesian coordinates, not in joint 00158 space like EMCMOT_JOG_* */ 00159 #ifdef ENABLE_PROBING 00160 EMCMOT_SET_PROBE_INDEX, /* set which wire the probe signal is on. */ 00161 EMCMOT_SET_PROBE_POLARITY, /* probe tripped on 0 to 1 transition or on 00162 1 to 0 transition. */ 00163 EMCMOT_CLEAR_PROBE_FLAGS, /* clears probeTripped flag */ 00164 EMCMOT_PROBE, /* go towards a position, stop if the probe 00165 is tripped, and record the position where 00166 the probe tripped */ 00167 EMCMOT_SET_DEBUG, /* sets the debug level */ 00168 EMCMOT_SET_AOUT, /* sets an analog motion point for next move */ 00169 EMCMOT_SET_DOUT /* sets a digital motion point for next move */ 00170 #endif 00171 00172 }; 00173 00174 /* termination conditions for queued motions */ 00175 #define EMCMOT_TERM_COND_STOP 1 00176 #define EMCMOT_TERM_COND_BLEND 2 00177 00178 typedef struct _EMC_TELEOP_DATA { 00179 EmcPose currentVel; 00180 EmcPose currentAccell; 00181 EmcPose desiredVel; 00182 EmcPose desiredAccell; 00183 } EMC_TELEOP_DATA; 00184 00185 /* command struct */ 00186 typedef struct 00187 { 00188 unsigned char head; /* flag count for mutex detect */ 00189 int command; /* one of enum above */ 00190 int commandNum; /* increment this for new command */ 00191 double cycleTime; /* planning time (not servo time) */ 00192 double maxLimit; /* pos value for position limit, output */ 00193 double minLimit; /* neg value for position limit, output */ 00194 EmcPose pos; /* end for line, circle */ 00195 PmCartesian center; /* center for circle */ 00196 PmCartesian normal; /* normal vec for circle */ 00197 int turn; /* turns for circle */ 00198 double vel; /* max velocity */ 00199 double acc; /* max acceleration */ 00200 int id; /* id for motion */ 00201 int termCond; /* termination condition */ 00202 int axis; /* which index to use for below */ 00203 PID_STRUCT pid; /* gains */ 00204 int logSize; /* size for log fifo */ 00205 int logSkip; /* how many to skip, 0 means log all, 00206 -1 means don't log on cycles */ 00207 int logType; /* type for logging */ 00208 int logTriggerType; /* see enum LOG_TRIGGER_TYPES */ 00209 int logTriggerVariable; /* the variable(s) that can cause the log to 00210 trigger. se enum LOG_TRIGGER_VARS */ 00211 double logTriggerThreshold; /* the value for non manual triggers */ 00212 double dacOut; /* output to DAC */ 00213 double scale; /* input or output scale arg */ 00214 double offset; /* input or output offset arg */ 00215 double minFerror; /* min following error */ 00216 double maxFerror; /* max following error */ 00217 int wdWait; /* cycle to wait before toggling wd */ 00218 EMCMOT_AXIS_FLAG axisFlag; /* flag to set polarities */ 00219 int level; /* flag for polarity level */ 00220 #ifdef ENABLE_PROBING 00221 int probeIndex; /* which wire the probe signal is on */ 00222 #endif 00223 int debug; /* debug level, from DEBUG in .ini file */ 00224 unsigned char out, start, end; /* motion index, start, and end bits */ 00225 unsigned char tail; /* flag count for mutex detect */ 00226 } EMCMOT_COMMAND; 00227 00228 /* 00229 motion status flag structure-- looks like: 00230 00231 MSB LSB 00232 v---------------v------------------v 00233 | | | | T | CE | C | IP | EN | 00234 ^---------------^------------------^ 00235 00236 where: 00237 00238 EN is 1 if calculations are enabled, 0 if not 00239 IP is 1 if all axes in position, 0 if not 00240 C is 1 if coordinated mode, 0 if in free mode 00241 CE is 1 if coordinated mode error, 0 if not 00242 T is 1 if we are in teleop mode. 00243 */ 00244 00245 /* bit masks */ 00246 #define EMCMOT_MOTION_ENABLE_BIT 0x0001 00247 #define EMCMOT_MOTION_INPOS_BIT 0x0002 00248 #define EMCMOT_MOTION_COORD_BIT 0x0004 00249 #define EMCMOT_MOTION_ERROR_BIT 0x0008 00250 #define EMCMOT_MOTION_TELEOP_BIT 0x0010 00251 00252 /* 00253 axis status flag structure-- looks like: 00254 00255 MSB LSB 00256 ----------v-----------------v-----------------------v-------------------v 00257 | AF | FE | | HD | H | HS | NHL | PHL | NSL | PSL | ER | IP | AC | EN | 00258 ----------^-----------------^-----------------------^-------------------^ 00259 * x * * * * * 00260 00261 x = unused 00262 * = has a polarity associated with it 00263 00264 where: 00265 00266 EN is 1 if axis amplifier is enabled, 0 if not 00267 AC is 1 if axis is active for calculations, 0 if not 00268 IP is 1 if axis is in position, 0 if not 00269 ER is 1 if axis has an error, 0 if not 00270 00271 PSL is 1 if axis is on maximum software limit, 0 if not 00272 NSL is 1 if axis is on minimum software limit, 0 if not 00273 PHL is 1 if axis is on maximum hardware limit, 0 if not 00274 NHL is 1 if axis is on minimum hardware limit, 0 if not 00275 00276 HS is 1 if axis home switch is tripped, 0 if not 00277 H is 1 if axis is homing, 0 if not 00278 HD is 1 if axis has been homed, 0 if not 00279 00280 FE is 1 if axis exceeded following error, 0 if not 00281 AF is 1 if amplifier is faulted, 0 if not 00282 00283 */ 00284 00285 /* bit masks */ 00286 #define EMCMOT_AXIS_ENABLE_BIT 0x0001 00287 #define EMCMOT_AXIS_ACTIVE_BIT 0x0002 00288 #define EMCMOT_AXIS_INPOS_BIT 0x0004 00289 #define EMCMOT_AXIS_ERROR_BIT 0x0008 00290 00291 #define EMCMOT_AXIS_MAX_SOFT_LIMIT_BIT 0x0010 00292 #define EMCMOT_AXIS_MIN_SOFT_LIMIT_BIT 0x0020 00293 #define EMCMOT_AXIS_MAX_HARD_LIMIT_BIT 0x0040 00294 #define EMCMOT_AXIS_MIN_HARD_LIMIT_BIT 0x0080 00295 00296 #define EMCMOT_AXIS_HOME_SWITCH_BIT 0x0100 00297 #define EMCMOT_AXIS_HOMING_BIT 0x0200 00298 #define EMCMOT_AXIS_HOMED_BIT 0x0400 00299 00300 #define EMCMOT_AXIS_FERROR_BIT 0x1000 00301 #define EMCMOT_AXIS_FAULT_BIT 0x2000 00302 00303 /* axis flag polarities-- for those axis flag bits that are subject 00304 to polarity (e.g., EN is, IP, H are not)-- are referenced to these 00305 bit masks above. 00306 00307 Note that 1 is normal, 0 is inverted, for sensing. They are reported 00308 in the axis status flag as documented, regardless of polarity. That 00309 is, AF will be 1 in the axis status flag for an amp fault, if the 00310 amp is faulted, regardless of the polarity. 00311 00312 They default to 1, normal polarity. 00313 00314 To set them, send EMCMOT_SET_POLARITY, with axis set to 00315 0..EMCMOT_MAX_AXIS - 1, axisFlag set to polarity bits for axis. */ 00316 00317 /* values for commandStatus */ 00318 #define EMCMOT_COMMAND_OK 0 /* cmd honored */ 00319 #define EMCMOT_COMMAND_UNKNOWN_COMMAND 1 /* cmd not understood */ 00320 #define EMCMOT_COMMAND_INVALID_COMMAND 2 /* cmd can't be handled now */ 00321 #define EMCMOT_COMMAND_INVALID_PARAMS 3 /* bad cmd params */ 00322 #define EMCMOT_COMMAND_BAD_EXEC 4 /* error trying to initiate */ 00323 00324 /* 00325 The type of kinematics used. 00326 00327 KINEMATICS_IDENTITY means that the joints and world coordinates are the 00328 same, as for slideway machines (XYZ milling machines). The EMC will allow 00329 changing from joint to world mode and vice versa. Also, the EMC will set 00330 the actual world position to be the actual joint positions (not commanded) 00331 by calling the forward kinematics each trajectory cycle. 00332 00333 KINEMATICS_FORWARD_ONLY means that only the forward kinematics exist. 00334 Since the EMC requires at least the inverse kinematics, this should simply 00335 terminate the EMC. 00336 00337 KINEMATICS_INVERSE_ONLY means that only the inverse kinematics exist. 00338 The forwards won't be called, and the EMC will only allow changing from 00339 joint to world mode at the home position. 00340 00341 KINEMATICS_BOTH means that both the forward and inverse kins are defined. 00342 Like KINEMATICS_IDENTITY, the EMC will allow changing between world and 00343 joint modes. However, the kins are assumed to be somewhat expensive 00344 computationally, and the forwards won't be called at the trajectory rate 00345 to compute actual world coordinates from actual joint values. 00346 */ 00347 00348 typedef enum { 00349 KINEMATICS_IDENTITY = 1, /* forward=inverse, both well-behaved */ 00350 KINEMATICS_FORWARD_ONLY, /* forward but no inverse */ 00351 KINEMATICS_INVERSE_ONLY, /* inverse but no forward */ 00352 KINEMATICS_BOTH /* forward and inverse both */ 00353 } KINEMATICS_TYPE; 00354 00355 /* deprecated symbols */ 00356 #define KINEMATICS_SERIAL KINEMATICS_FORWARD_ONLY 00357 #define KINEMATICS_PARALLEL KINEMATICS_INVERSE_ONLY 00358 #define KINEMATICS_CUSTOM KINEMATICS_BOTH 00359 00360 /* status struct */ 00361 typedef struct 00362 { 00363 unsigned char head; /* flag count for mutex detect */ 00364 00365 /* dynamic status-- changes every cycle */ 00366 unsigned int heartbeat; 00367 int config_num; /* incremented whenever configuration changed. */ 00368 double computeTime; 00369 EmcPose pos; /* calculated Cartesian position */ 00370 double axisPos[EMCMOT_MAX_AXIS]; /* calculated axis positions */ 00371 double output[EMCMOT_MAX_AXIS]; 00372 double input[EMCMOT_MAX_AXIS]; /* actual input */ 00373 EmcPose actualPos; /* actual Cartesian position */ 00374 int id; /* id for executing motion */ 00375 int depth; /* motion queue depth */ 00376 int activeDepth; /* depth of active blend elements */ 00377 int queueFull; 00378 EMCMOT_MOTION_FLAG motionFlag; 00379 EMCMOT_AXIS_FLAG axisFlag[EMCMOT_MAX_AXIS]; 00380 int paused; 00381 int overrideLimits; /* non-zero means limits are ignored */ 00382 int logPoints; /* how many points currently in log */ 00383 00384 /* static status-- only changes upon input commands, e.g., config */ 00385 int commandEcho; /* echo of input command */ 00386 int commandNumEcho; /* echo of input command number */ 00387 unsigned char commandStatus; /* one of EMCMOT_COMMAND_ defined above */ 00388 double outputScale[EMCMOT_MAX_AXIS]; 00389 double outputOffset[EMCMOT_MAX_AXIS]; 00390 double inputScale[EMCMOT_MAX_AXIS]; 00391 double inputOffset[EMCMOT_MAX_AXIS]; /* encoder offsets */ 00392 double qVscale; /* traj velocity scale factor */ 00393 double axVscale[EMCMOT_MAX_AXIS]; /* axis velocity scale factor */ 00394 double vel; /* scalar max vel */ 00395 double acc; /* scalar max accel */ 00396 int logOpen; 00397 int logStarted; 00398 int logSize; /* size in entries, not bytes */ 00399 int logSkip; 00400 int logType; /* type being logged */ 00401 int logTriggerType; /* 0=manual, 1 =abs(change) > threshold, 00402 2=var < threshold, 3 var>threshold */ 00403 int logTriggerVariable; /* The variable(s) that can cause the log to 00404 trigger. */ 00405 double logTriggerThreshold; /* The value for non manual triggers. */ 00406 double logStartVal; /* value use for delta trigger */ 00407 int probeTripped; /* Has the probe signal changed since 00408 start of probe command? */ 00409 int probeval; /* current value of probe wire */ 00410 int probing; /* Currently looking for a probe signal? */ 00411 EmcPose probedPos; /* Axis positions stored as soon as possible 00412 after last probeTripped */ 00413 unsigned char tail; /* flag count for mutex detect */ 00414 } EMCMOT_STATUS; 00415 00416 00417 typedef struct 00418 { 00419 unsigned char head; /* flag count for mutex detect */ 00420 00421 int config_num; /* Incremented everytime configuration changed, should match status.config_num */ 00422 00423 EMCMOT_AXIS_FLAG axisPolarity[EMCMOT_MAX_AXIS]; 00424 int numAxes; 00425 double trajCycleTime; 00426 double servoCycleTime; 00427 int interpolationRate; 00428 double maxLimit[EMCMOT_MAX_AXIS]; /* maximum axis limits, counts */ 00429 double minLimit[EMCMOT_MAX_AXIS]; /* minimum axis limits, counts */ 00430 double minOutput[EMCMOT_MAX_AXIS]; /* minimum output value allowed, volts */ 00431 double maxOutput[EMCMOT_MAX_AXIS]; /* maximum output value allowed, volts */ 00432 double minFerror[EMCMOT_MAX_AXIS]; /* minimum allowable following error */ 00433 double maxFerror[EMCMOT_MAX_AXIS]; /* maximum allowable following error */ 00434 double limitVel; /* scalar upper limit on vel */ 00435 double axisLimitVel[EMCMOT_MAX_AXIS]; /* scalar upper limit on axis vels */ 00436 double homingVel[EMCMOT_MAX_AXIS]; /* scalar max homing vels */ 00437 double homeOffset[EMCMOT_MAX_AXIS]; /* where to go after home, user units */ 00438 int probeIndex; /* Which wire has the probe signal? */ 00439 int probePolarity; /* Look for 0 or 1. */ 00440 KINEMATICS_TYPE kinematics_type; 00441 PID_STRUCT pid[EMCMOT_MAX_AXIS]; 00442 int STEPPING_TYPE; /* 0 = step/direction, 1 = phasing */ 00443 00444 int PERIOD; /* fundamental period for timer interrupts */ 00445 unsigned short STG_BASE_ADDRESS; 00446 unsigned long int PARPORT_IO_ADDRESS; 00447 int debug; /* copy of DEBUG, from .ini file */ 00448 00449 unsigned char tail; /* flag count for mutex detect */ 00450 } EMCMOT_CONFIG; 00451 00452 typedef struct 00453 { 00454 unsigned char head; /* flag count for mutex detect */ 00455 double tMin, tMax, tAvg; /* trajectory min, max, avg times */ 00456 double sMin, sMax, sAvg; /* servo min, max, avg times */ 00457 double nMin, nMax, nAvg; /* min, max, avg times in DISABLED mode */ 00458 double yMin, yMax, yAvg; /* min, max, avg times cycle times rather than compute */ 00459 double fMin, fMax, fAvg; /* min, max, avg times frequency */ 00460 double fyMin, fyMax, fyAvg; /* min, max, avg times frequency cycle times rather than compute */ 00461 00462 EMC_TELEOP_DATA teleop_data; 00463 double ferrorCurrent[EMCMOT_MAX_AXIS]; /* current following error */ 00464 double ferrorHighMark[EMCMOT_MAX_AXIS]; /* magnitude of max following error */ 00465 int split; /* number of split command reads */ 00466 /* 00467 stepperCount[] contains the accumulated pulses that have been output, which 00468 are used as the "encoder feedback" for open-loop stepping. 00469 */ 00470 int stepperCount[EMCMOT_MAX_AXIS]; /* and rest are 0 */ 00471 00472 /* 00473 * 'pdmult' is a global that sets value to be loaded into decrement 00474 * counters, for freqfunc() task function. Set this to 0 or 1 for full-out 00475 * frequency, 2 for half, 3 for a third, etc. 00476 * lpg - 00477 * for rtl2x 00478 * 1,193,180 / ( +-10 1.0 48000ns) 00479 * pdmult = HRTICKS_PER_SEC / (rawoutput * output_scale * PERIOD); 00480 * 00481 */ 00482 int pdmult[EMCMOT_MAX_AXIS]; 00483 int enable[EMCMOT_MAX_AXIS]; 00484 00485 /* flag for enabling, disabling watchdog; multiple for down-stepping */ 00486 int wdEnabling ; 00487 int wdEnabled ; 00488 int wdWait ; 00489 int wdCount ; 00490 unsigned char wdToggle ; 00491 00492 /* flag that all active axes are homed */ 00493 unsigned char allHomed ; 00494 00495 /* values for joint home positions */ 00496 double jointHome[EMCMOT_MAX_AXIS]; 00497 00498 int maxLimitSwitchCount[EMCMOT_MAX_AXIS]; 00499 int minLimitSwitchCount[EMCMOT_MAX_AXIS]; 00500 int ampFaultCount[EMCMOT_MAX_AXIS]; 00501 00502 TP_STRUCT queue; /* coordinated mode planner */ 00503 /* the freeAxis TP_STRUCTs are used to store the single joint value, 00504 in tran.x, that enables us to use the TP_STRUCT functions for axis 00505 planning. This is overkill, and we need to create a simpler TP_STRUCT 00506 for single-joint motion planning. */ 00507 TP_STRUCT freeAxis[EMCMOT_MAX_AXIS]; 00508 /* freePose is a EmcPose struct that is used to hold a joint value, in 00509 tran.x, so that the TP_STRUCT functions can be called for scalar joint 00510 planning */ 00511 EmcPose freePose; 00512 CUBIC_STRUCT cubic[EMCMOT_MAX_AXIS]; 00513 00514 /* space for trajectory planner queues, plus 10 more for safety */ 00515 /* FIXME-- default is used; dynamic is not honored */ 00516 TC_STRUCT queueTcSpace[DEFAULT_TC_QUEUE_SIZE + 10]; 00517 #define FREE_AXIS_QUEUE_SIZE 4 /* don't really queue free axis motion */ 00518 TC_STRUCT freeAxisTcSpace[EMCMOT_MAX_AXIS][FREE_AXIS_QUEUE_SIZE]; 00519 00520 double rawInput[EMCMOT_MAX_AXIS]; /* raw feedback from sensors */ 00521 double rawOutput[EMCMOT_MAX_AXIS]; /* raw output to actuators */ 00522 00523 double coarseJointPos[EMCMOT_MAX_AXIS]; /* trajectory point, in joints */ 00524 double jointPos[EMCMOT_MAX_AXIS]; /* interpolated point, in joints */ 00525 double jointVel[EMCMOT_MAX_AXIS]; /* joint velocity */ 00526 double oldJointPos[EMCMOT_MAX_AXIS]; /* ones from last cycle, for vel */ 00527 double outJointPos[EMCMOT_MAX_AXIS]; /* rounded and backlash-comped */ 00528 double oldInput[EMCMOT_MAX_AXIS]; /* ones for actual pos, last cycle */ 00529 char oldInputValid[EMCMOT_MAX_AXIS]; 00530 /* inverseInputScale[] is 1/inputScale[], and lets us use a multiplication 00531 instead of a division each servo cycle */ 00532 double inverseInputScale[EMCMOT_MAX_AXIS]; 00533 double inverseOutputScale[EMCMOT_MAX_AXIS]; 00534 EmcPose oldPos; /* last position, used for vel differencing */ 00535 EmcPose oldVel, newVel; /* velocities, used for acc differencing */ 00536 EmcPose newAcc; /* differenced acc */ 00537 00538 /* value of speed past which we debounce the feedback */ 00539 double bigVel[EMCMOT_MAX_AXIS]; 00540 00541 int homingPhase[EMCMOT_MAX_AXIS]; /*flags for homing */ 00542 int latchFlag[EMCMOT_MAX_AXIS]; /* flags for axis latched */ 00543 double saveLatch[EMCMOT_MAX_AXIS]; /* saved axis latch values */ 00544 00545 int enabling; /* starts up disabled */ 00546 int coordinating; /* starts up in free mode */ 00547 int teleoperating ; /* starts up in free mode */ 00548 00549 int wasOnLimit; /* non-zero means we already aborted 00550 everything due to a soft 00551 limit, and need not re-abort. It's 00552 cleared only when all limits are 00553 cleared. */ 00554 int onLimit; /* non-zero means at least one axis is 00555 on a soft limit */ 00556 00557 int overriding; /* non-zero means we've initiated an axis 00558 move while overriding limits */ 00559 00560 int stepping; 00561 int idForStep; 00562 00563 /* min-max-avg structs for traj and servo cycles */ 00564 MMXAVG_STRUCT tMmxavg; 00565 MMXAVG_STRUCT sMmxavg; 00566 MMXAVG_STRUCT nMmxavg; 00567 MMXAVG_STRUCT yMmxavg; 00568 MMXAVG_STRUCT fMmxavg; 00569 MMXAVG_STRUCT fyMmxavg; 00570 00571 double tMmxavgSpace[DEFAULT_MMXAVG_SIZE]; 00572 double sMmxavgSpace[DEFAULT_MMXAVG_SIZE]; 00573 double nMmxavgSpace[DEFAULT_MMXAVG_SIZE]; 00574 double yMmxavgSpace[DEFAULT_MMXAVG_SIZE]; 00575 double fMmxavgSpace[DEFAULT_MMXAVG_SIZE]; 00576 double fyMmxavgSpace[DEFAULT_MMXAVG_SIZE]; 00577 00578 double start_time; 00579 double running_time; 00580 double cur_time; 00581 double last_time; 00582 00583 /* backlash stuff */ 00584 double bcomp[EMCMOT_MAX_AXIS]; /* backlash comp value */ 00585 char bcompdir[EMCMOT_MAX_AXIS]; /* 0=none, 1=pos, -1=neg */ 00586 double bcompincr[EMCMOT_MAX_AXIS]; /* incremental backlash comp */ 00587 char bac_done[EMCMOT_MAX_AXIS]; 00588 double bac_d[EMCMOT_MAX_AXIS]; 00589 double bac_di[EMCMOT_MAX_AXIS]; 00590 double bac_D[EMCMOT_MAX_AXIS]; 00591 double bac_halfD[EMCMOT_MAX_AXIS]; 00592 double bac_incrincr[EMCMOT_MAX_AXIS]; 00593 double bac_incr[EMCMOT_MAX_AXIS]; 00594 00595 unsigned char tail; /* flag count for mutex detect */ 00596 } EMCMOT_DEBUG; 00597 00598 /* error structure */ 00599 typedef struct 00600 { 00601 unsigned char head; /* flag count for mutex detect */ 00602 char error[EMCMOT_ERROR_NUM][EMCMOT_ERROR_LEN]; 00603 int start; /* index of oldest error */ 00604 int end; /* index of newest error */ 00605 int num; /* number of items */ 00606 unsigned char tail; /* flag count for mutex detect */ 00607 } EMCMOT_ERROR; 00608 00609 /* compensation structure */ 00610 #define EMCMOT_COMP_SIZE 256 00611 typedef struct 00612 { 00613 int total; /* how many comp points */ 00614 double avgint; /* average interval between points */ 00615 double nominal[EMCMOT_COMP_SIZE]; /* nominal points */ 00616 double forward[EMCMOT_COMP_SIZE]; /* forward comp points */ 00617 double reverse[EMCMOT_COMP_SIZE]; /* reverse comp points */ 00618 double alter; /* additive dynamic compensation */ 00619 } EMCMOT_COMP; 00620 00621 /* big comm structure, for upper memory */ 00622 typedef struct 00623 { 00624 EMCMOT_COMMAND command; 00625 EMCMOT_STATUS status; 00626 EMCMOT_CONFIG config; 00627 EMCMOT_DEBUG debug; 00628 EMCMOT_ERROR error; 00629 EMCMOT_LOG log; 00630 EMCMOT_COMP comp[EMCMOT_MAX_AXIS]; 00631 } EMCMOT_STRUCT; 00632 00633 /* 00634 function prototypes for emcmot code 00635 00636 built-in main() calls these functions; if main() is not used 00637 they must be called by user processes directly. Control flow is: 00638 00639 init_module(); 00640 for (;;) 00641 { 00642 emcmotController(0); 00643 if (userDoneFunction()) 00644 break; 00645 else 00646 userWaitCycle(); 00647 } 00648 cleanup_module(); 00649 00650 where userDoneFunction() tells when to stop, and userWaitCycle() should 00651 sleep the process for the servo cycle time. 00652 */ 00653 00654 extern int init_module(void); 00655 extern void cleanup_module(void); 00656 00657 /* FIXME-- better kinematics functions */ 00658 00659 /* the forward flags are passed to the forward kinematics so that they 00660 can resolve ambiguities in the world coordinates for a given joint set, 00661 e.g., for hexpods, this would be platform-below-base, platform-above-base. 00662 00663 The flags are also passed to the inverse kinematics and are set by them, 00664 which is how they are changed from their initial value. For example, for 00665 hexapods you could do a coordinated move that brings the platform up from 00666 below the base to above the base. The forward flags would be set to 00667 indicate this. */ 00668 typedef unsigned long int KINEMATICS_FORWARD_FLAGS; 00669 00670 /* the inverse flags are passed to the inverse kinematics so thay they 00671 can resolve ambiguities in the joint angles for a given world coordinate, 00672 e.g., for robots, this would be elbow-up, elbow-down, etc. 00673 00674 The flags are also passed to the forward kinematics and are set by them, 00675 which is how they are changed from their initial value. For example, for 00676 robots you could do a joint move that brings the elbow from a down 00677 configuration to an up configuration. The inverse flags would be set to 00678 indicate this. */ 00679 typedef unsigned long int KINEMATICS_INVERSE_FLAGS; 00680 00681 /* the forward kinematics take joint values and determine world coordinates, 00682 given forward kinematics flags to resolve any ambiguities. The inverse 00683 flags are set to indicate their value appropriate to the joint values 00684 passed in. */ 00685 extern int kinematicsForward(const double * joint, 00686 EmcPose * world, 00687 const KINEMATICS_FORWARD_FLAGS * fflags, 00688 KINEMATICS_INVERSE_FLAGS * iflags); 00689 00690 /* the inverse kinematics take world coordinates and determine joint values, 00691 given the inverse kinematics flags to resolve any ambiguities. The forward 00692 flags are set to indicate their value appropriate to the world coordinates 00693 passed in. */ 00694 extern int kinematicsInverse(const EmcPose * world, 00695 double * joints, 00696 const KINEMATICS_INVERSE_FLAGS * iflags, 00697 KINEMATICS_FORWARD_FLAGS * fflags); 00698 00699 /* the home kinematics function sets all its arguments to their proper 00700 values at the known home position. When called, these should be set, 00701 when known, to initial values, e.g., from an INI file. If the home 00702 kinematics can accept arbitrary starting points, these initial values 00703 should be used. 00704 */ 00705 extern int kinematicsHome(EmcPose * world, 00706 double * joint, 00707 KINEMATICS_FORWARD_FLAGS * fflags, 00708 KINEMATICS_INVERSE_FLAGS * iflags); 00709 00710 00711 extern KINEMATICS_TYPE kinematicsType(void); 00712 00713 /* sets the mechanism parameters. The caller needs to know how to set 00714 each p[] value. Typically this is either hard-coded, or can be part 00715 of a .ini file, e.g., [TRAJ] KINEMATICS_PARAMETERS = 1.0 2.0 -3.1416, 00716 where the writer of the .ini file knows how the kinematicsSetParameters() 00717 function for the particular controller will use these values. */ 00718 extern int kinematicsSetParameters(double *p); 00719 00720 extern int jacobianInverse(const EmcPose * pos, 00721 const EmcPose * vel, 00722 const double * joints, 00723 double * jointvels); 00724 00725 extern int jacobianForward(const double * joints, 00726 const double * jointvels, 00727 const EmcPose * pos, 00728 EmcPose * vel); 00729 00730 /* error ring buffer access functions */ 00731 extern int emcmotErrorInit(EMCMOT_ERROR *errlog); 00732 extern int emcmotErrorPut(EMCMOT_ERROR *errlog, const char *error); 00733 extern int emcmotErrorGet(EMCMOT_ERROR *errlog, char *error); 00734 00735 #ifdef __cplusplus 00736 } 00737 #endif 00738 00739 #endif /* EMCMOT_H */