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

bridgeporttaskintf.cc

Go to the documentation of this file.
00001 /*
00002   bridgeporttaskintf.cc
00003 
00004   Bridgeport NML interface functions for motion and IO
00005 
00006   Modification history:
00007 
00008   17-Aug-2001  FMP added emcMotionSetDout, LASER stuff
00009   15-Aug-2001  FMP added writing of EMCMOT_SET_AXIS_VEL_LIMIT in
00010   emcAxisSetMaxVelocity(), since now there's an emcmot command for this
00011   1-Jun-2001  FMP added emcIoSetDebug; reworked emcMotionUpdate() so that
00012   it calls usrmotReadEmcmotStatus() once, then passes the fresh structure
00013   to emcTrajUpdate(), emcAxisUpdate().
00014   21-May-2001 WPS made emcioNmlGet try for 5 seconds waiting for the nml 
00015 channels from tool(io) and sleep between each try.
00016   13-May-2001 KJO added return statement to emcLogStart().  Removed intermediate variable 'r1' to emcLogStop()
00017    5-Jan-2001 WPS made sendCommand timeout after 30 seconds, and sleep a little between each check with io still executing.
00018   18-Oct-2000 WPS added more conditions to prevent the system from
00019   dumping the axis values when they are suspect.
00020   16-Aug-2000  FMP added emcAxisAlter(); took out emcmotStatus global
00021   since it's a stack variable in emcAxisUpdate(), emcTrajUpdate(). Called
00022   usrmotQueryAlter() to set axis alter status.
00023   10-Aug-2000  FMP added emcAxisLoadComp().
00024   31-Jul-2000 WPS added emcTrajProbe functions.
00025   7-Jun-2000  FMP added check on serial numbers for executing, in sendCommand
00026   30-Mar-2000 WPS added ferrorCurrent and ferrorHighMark junk.
00027   22-Mar-2000  FMP fixed jog functions to compare vel against both pos
00028   and neg sides of AXIS_MAX_VELOCITY[]
00029   3-Mar-2000  FMP added fault to axis status; clipped axis jog vel to
00030   AXIS_MAX_VELOCITY[] global
00031   24-Feb-2000  FMP added deadband
00032   23-Feb-2000  FMP added emcAxisSetMaxVelocity()
00033   17-Feb-2000  FMP added a section in emcIoUpdate() that compares the command
00034   serial number sent to emcio with the echo serial number, and if they're
00035   different the state is set to RCS_EXEC. This fixes a race condition when
00036   a bunch of IO commands (spindle off, mist off, flood off) are queued up.
00037   22-Jan-2000  FMP added pos-voltage logging; emcAxisSetOutput()
00038   12-Nov-1999  FMP added sending of negative axis for emcAxisOverrideLimits,
00039   to resume normal limit checking
00040   1-Oct-1999  FMP added emcAxisOverrideLimits()
00041   29-Sep-1999  FMP added emcAxisSetHomeOffset()
00042   31-Aug-1999  FMP changed to bridgeporttaskintf.cc
00043   30-Aug-1999  FMP fixed bug in incremental, abs jog
00044   9-Aug-1999  FMP added emcTrajSetHome(), emcAxisSetHome()
00045   3-Aug-1999  FMP added emcAxisActivate,Deactivate
00046   2-Aug-1999  FMP took out deactivation of 4th axis
00047   15-Jul-1999  FMP took looping retry for IO NML out of emcIoInit() since
00048   we're now doing that in the task controller
00049   16-Jun-1999  FMP added setpoint to axis status update
00050   11-Jun-1999  FMP took out saveAxisCycleTime that wouldn't allow greater
00051   values of cycle time to go through. Now the last one is sent out,
00052   superceding all the others. As a result the INI file should have the
00053   same values for all axes until we figure out a better way.
00054   8-Jun-1999  FMP put in sending of EMCMOT_SET_VEL_LIMIT in
00055   emcTrajSetMaxVelocity() now that's it's part of true motion system;
00056   set stat->maxVelocity to be emcmot's status version instead of
00057   global TRAJ_MAX_VELOCITY
00058   7-Jun-1999  FMP removed localEmcMaxVelocity and replaced it with
00059   global TRAJ_MAX_VELOCITY
00060   21-May-1999  FMP added EMC_LOG_TYPE_TRAJ_POS, changing TRAJ_INPOS,OUTPOS
00061   to AXES_INPOS,OUTPOS
00062   25-Feb-1999  FMP added localMotionCommandType to fill in motion
00063   status command_type, as was done with echo_serial_number
00064   22-Feb-1999  FMP added emcToolSetOffset()
00065   19-Feb-1999  FMP kept emcIoCommandSerialNumber locally, capturing
00066   it when starting up, instead of re-reading it each time since this
00067   led to a race condition where the serial number didn't increment.
00068   Made sendCommand() wait until done or error, cycling forever on exec.
00069   Added forceCommand() to send command regardless of exec state.
00070   Added local motion serial number, as in mmtaskintf.cc.
00071   7-Feb-1999  FMP added EMC_LOG_TYPE_TRAJ_FERROR to emcLogOpen()
00072   31-Jan-1999  FMP added backlash, bias, maxError to EMC_AXIS_STAT update;
00073   call to dumpAxis() in emcAxisHalt();
00074   30-Jan-1999  FMP fixed backlash setting in emcAxisSetGains()
00075   21-Oct-1998  FMP used wall clock for timeout to emcIoInit()
00076   15-Oct-1998  FMP changed emcLogError to emcOperatorError per change
00077   in emc.hh
00078   7-Oct-1998 FMP added emcAxisSetHomingVel()
00079   5-Oct-1998  FMP added lube control
00080   1-Oct-1998  FMP added emcSpindleAbort();
00081   2-Sep-1998  FMP added soft and hard limit checking; deactivated 4th axis
00082   20-Aug-1998  FMP added check for log in emcLogClose(); took out log size
00083   in call to usrmotDumpLog();
00084   18-Aug-1998  FMP took out reverse PID gains, added bias
00085   31-Jul-1998  FMP took out suppression of redundant vel, since it caused
00086   a problem where the rapid rate was made slow
00087   6-Jul-1998  FMP added suppression of redundant vel
00088   6-Jul-1998  FMP took out loop continue in sendCommand, since if it's
00089   executing we'll say it got there. Otherwise, task controller spins
00090   too long.
00091   26-Jun-1998  FMP added wait until done/error in sendCommand
00092   17-Jun-1998  FMP added 'which' parameter to EMC_LOG_OPEN, emcLogOpen()
00093   16-Jun-1998  FMP added emcLog* functions
00094   15-Jun-1998  FMP added emcTrajSetTermCond()
00095   8-Jun-1998  FMP added repeat trying of NML buffer in emcIoInit
00096   5-Jun-1998  FMP added reverse gains, backlash, maxError
00097   21-May-1998  FMP added emcSpindleIncrease,Decrease,Constant(); added
00098   motion heartbeat
00099   23-Apr-1998  FMP added iniTool() calls
00100   2-Apr-1998  FMP created from emcmotintf.cc, emciointf.cc
00101   */
00102 
00103 #include <math.h>               // sqrt(), atan2()
00104 #include <float.h>              // DBL_MAX
00105 #include <string.h>             // memcpy()
00106 
00107 #include "rcs.hh"               // RCS_CMD_CHANNEL, etc.
00108 #include "nml_mod.hh"           // RCS_DONE
00109 #include "emc.hh"               // EMC NML, Argc/Argv
00110 #include "usrmotintf.h"         // usrmotInit(), usrmotReadEmcmotStatus(), etc.
00111 #include "emcmot.h"             // EMCMOT_COMMAND,STATUS, etc.
00112 #include "emcmotcfg.h"          // EMCMOT_ERROR_LEN
00113 #include "canon.hh"             // CANON_PLANE
00114 #include "posemath.h"           // PM_POSE
00115 #include "initraj.hh"
00116 #include "iniaxis.hh"
00117 #include "emcglb.h"             // EMC_INIFILE
00118 #include "emcpos.h"             // EmcPose
00119 
00120 /* ident tag */
00121 #ifndef __GNUC__
00122 #ifndef __attribute__
00123 #define __attribute__(x)
00124 #endif
00125 #endif
00126 
00127 static char __attribute__((unused)) ident[] = "$Id: bridgeporttaskintf.cc,v 1.20 2001/08/17 22:05:41 proctor Exp $";
00128 
00129 /* FIXME-- defining LASER to test motion/IO synch */
00130 /* #define LASER */
00131 
00132 // MOTION INTERFACE
00133 
00134 /*
00135   Implementation notes:
00136 
00137   Initing:  the emcmot interface needs to be inited once, but nml_traj_init()
00138   and nml_servo_init() can be called in any order. Similarly, the emcmot
00139   interface needs to be exited once, but nml_traj_exit() and nml_servo_exit()
00140   can be called in any order. They can also be called multiple times. Flags
00141   are used to signify if initing has been done, or if the final exit has
00142   been called.
00143   */
00144 
00145 // define this to catch isnan errors, for rtlinux FPU register problem testing
00146 #ifdef linux
00147 #include <stdio.h>              // printf()
00148 #define ISNAN_TRAP
00149 #endif
00150 
00151 static EMCMOT_COMMAND emcmotCommand;
00152 
00153 static int emcmotTrajInited = 0; // non-zero means traj called init
00154 static int emcmotAxisInited = 0; // non-zero means axis called init
00155 static int emcmotion_initialized=0; // non-zero means both emcMotionInit called.
00156 
00157 // saved value of velocity last sent out, so we don't send redundant requests
00158 // used by emcTrajSetVelocity(), emcMotionAbort()
00159 static double lastVel = -1.0;
00160 
00161 // EMC_AXIS functions
00162 
00163 // local status data, not provided by emcmot
00164 static unsigned long localMotionHeartbeat;
00165 static int localMotionCommandType = 0;
00166 static int localMotionEchoSerialNumber = 0;
00167 static unsigned char localEmcAxisAxisType[EMCMOT_MAX_AXIS];
00168 static double localEmcAxisUnits[EMCMOT_MAX_AXIS];
00169 static double localEmcMaxAcceleration = DBL_MAX;
00170 
00171 // axes are numbered 0..NUM-1
00172 
00173 /*
00174   In emcmot, we need to set the cycle time for traj, and the interpolation
00175   rate, in any order, but both need to be done. The PID cycle time will
00176   be set by emcmot automatically.
00177  */
00178 
00179 int emcAxisSetAxis(int axis, unsigned char axisType)
00180 {
00181   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00182   {
00183     return 0;
00184   }
00185 
00186   localEmcAxisAxisType[axis] = axisType;
00187 
00188   return 0;
00189 }
00190 
00191 int emcAxisSetUnits(int axis, double units)
00192 {
00193   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00194   {
00195     return 0;
00196   }
00197 
00198   localEmcAxisUnits[axis] = units;
00199 
00200   return 0;
00201 }
00202 
00203 int emcAxisSetGains(int axis, double p, double i, double d,
00204                     double ff0, double ff1, double ff2,
00205                     double backlash, double bias, double maxError,
00206                     double deadband)
00207 {
00208   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00209   {
00210     return 0;
00211   }
00212 
00213   emcmotCommand.command = EMCMOT_SET_PID;
00214   emcmotCommand.axis = axis;
00215 
00216   emcmotCommand.pid.p = p;
00217   emcmotCommand.pid.i = i;
00218   emcmotCommand.pid.d = d;
00219   emcmotCommand.pid.ff0 = ff0;
00220   emcmotCommand.pid.ff1 = ff1;
00221   emcmotCommand.pid.ff2 = ff2;
00222   emcmotCommand.pid.backlash = backlash;
00223   emcmotCommand.pid.bias = bias;
00224   emcmotCommand.pid.maxError = maxError;
00225   emcmotCommand.pid.deadband = deadband;
00226 
00227 #ifdef ISNAN_TRAP
00228   if (isnan(emcmotCommand.pid.p) ||
00229       isnan(emcmotCommand.pid.i) ||
00230       isnan(emcmotCommand.pid.d) ||
00231       isnan(emcmotCommand.pid.ff0) ||
00232       isnan(emcmotCommand.pid.ff1) ||
00233       isnan(emcmotCommand.pid.ff2) ||
00234       isnan(emcmotCommand.pid.backlash) ||
00235       isnan(emcmotCommand.pid.bias) ||
00236       isnan(emcmotCommand.pid.maxError) ||
00237       isnan(emcmotCommand.pid.deadband))
00238   {
00239     printf("isnan error in emcAxisSetGains\n");
00240     return -1;
00241   }
00242 #endif
00243 
00244   return usrmotWriteEmcmotCommand(&emcmotCommand);
00245 }
00246 
00247 int emcAxisSetCycleTime(int axis, double cycleTime)
00248 {
00249   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00250   {
00251     return 0;
00252   }
00253 
00254   if (cycleTime <= 0.0)
00255   {
00256     return -1;
00257   }
00258 
00259   emcmotCommand.command = EMCMOT_SET_SERVO_CYCLE_TIME;
00260   emcmotCommand.cycleTime = cycleTime;
00261 
00262   return usrmotWriteEmcmotCommand(&emcmotCommand);
00263 }
00264 
00265 int emcAxisSetInputScale(int axis, double scale, double offset)
00266 {
00267   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00268   {
00269     return 0;
00270   }
00271 
00272   emcmotCommand.command = EMCMOT_SET_INPUT_SCALE;
00273   emcmotCommand.axis = axis;
00274   emcmotCommand.scale = scale;
00275   emcmotCommand.offset = offset;
00276 
00277 #ifdef ISNAN_TRAP
00278   if (isnan(emcmotCommand.scale) ||
00279       isnan(emcmotCommand.offset))
00280   {
00281     printf("isnan eror in emcAxisSetInputScale\n");
00282     return -1;
00283   }
00284 #endif
00285 
00286   return usrmotWriteEmcmotCommand(&emcmotCommand);
00287 }
00288 
00289 int emcAxisSetOutputScale(int axis, double scale, double offset)
00290 {
00291   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00292   {
00293     return 0;
00294   }
00295 
00296   emcmotCommand.command = EMCMOT_SET_OUTPUT_SCALE;
00297   emcmotCommand.axis = axis;
00298   emcmotCommand.scale = scale;
00299   emcmotCommand.offset = offset;
00300 
00301 #ifdef ISNAN_TRAP
00302   if (isnan(emcmotCommand.scale) ||
00303       isnan(emcmotCommand.offset))
00304   {
00305     printf("isnan eror in emcAxisSetOutputScale\n");
00306     return -1;
00307   }
00308 #endif
00309 
00310   return usrmotWriteEmcmotCommand(&emcmotCommand);
00311 }
00312 
00313 // saved values of limits, since emcmot expects them to be set in
00314 // pairs and we set them individually.
00315 static double saveMinLimit[EMCMOT_MAX_AXIS];
00316 static double saveMaxLimit[EMCMOT_MAX_AXIS];
00317 
00318 int emcAxisSetMinPositionLimit(int axis, double limit)
00319 {
00320   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00321   {
00322     return 0;
00323   }
00324 
00325   emcmotCommand.command = EMCMOT_SET_POSITION_LIMITS;
00326   emcmotCommand.axis = axis;
00327   emcmotCommand.maxLimit = saveMaxLimit[axis];
00328   emcmotCommand.minLimit = limit;
00329   saveMinLimit[axis] = limit;
00330 
00331 #ifdef ISNAN_TRAP
00332   if (isnan(emcmotCommand.maxLimit) ||
00333       isnan(emcmotCommand.minLimit))
00334   {
00335     printf("isnan error in emcAxisSetMinPosition\n");
00336     return -1;
00337   }
00338 #endif
00339 
00340   return usrmotWriteEmcmotCommand(&emcmotCommand);
00341 }
00342 
00343 int emcAxisSetMaxPositionLimit(int axis, double limit)
00344 {
00345   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00346   {
00347     return 0;
00348   }
00349 
00350   emcmotCommand.command = EMCMOT_SET_POSITION_LIMITS;
00351   emcmotCommand.axis = axis;
00352   emcmotCommand.minLimit = saveMinLimit[axis];
00353   emcmotCommand.maxLimit = limit;
00354   saveMaxLimit[axis] = limit;
00355 
00356 #ifdef ISNAN_TRAP
00357   if (isnan(emcmotCommand.maxLimit) ||
00358       isnan(emcmotCommand.minLimit))
00359   {
00360     printf("isnan error in emcAxisSetMaxPosition\n");
00361     return -1;
00362   }
00363 #endif
00364 
00365   return usrmotWriteEmcmotCommand(&emcmotCommand);
00366 }
00367 
00368 // saved values of limits, since emcmot expects them to be set in
00369 // pairs and we set them individually.
00370 static double saveMinOutput[EMCMOT_MAX_AXIS];
00371 static double saveMaxOutput[EMCMOT_MAX_AXIS];
00372 
00373 int emcAxisSetMinOutputLimit(int axis, double limit)
00374 {
00375   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00376   {
00377     return 0;
00378   }
00379 
00380   emcmotCommand.command = EMCMOT_SET_OUTPUT_LIMITS;
00381   emcmotCommand.axis = axis;
00382   emcmotCommand.maxLimit = saveMaxOutput[axis];
00383   emcmotCommand.minLimit = limit;
00384   saveMinOutput[axis] = limit;
00385 
00386 #ifdef ISNAN_TRAP
00387   if (isnan(emcmotCommand.maxLimit) ||
00388       isnan(emcmotCommand.minLimit))
00389   {
00390     printf("isnan error in emcAxisSetMinOutputLimit\n");
00391     return -1;
00392   }
00393 #endif
00394 
00395   return usrmotWriteEmcmotCommand(&emcmotCommand);
00396 }
00397 
00398 int emcAxisSetMaxOutputLimit(int axis, double limit)
00399 {
00400   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00401   {
00402     return 0;
00403   }
00404 
00405   emcmotCommand.command = EMCMOT_SET_OUTPUT_LIMITS;
00406   emcmotCommand.axis = axis;
00407   emcmotCommand.minLimit = saveMinOutput[axis];
00408   emcmotCommand.maxLimit = limit;
00409   saveMaxOutput[axis] = limit;
00410 
00411 #ifdef ISNAN_TRAP
00412   if (isnan(emcmotCommand.maxLimit) ||
00413       isnan(emcmotCommand.minLimit))
00414   {
00415     printf("isnan error in emcAxisSetMaxOutputLimit\n");
00416     return -1;
00417   }
00418 #endif
00419 
00420   return usrmotWriteEmcmotCommand(&emcmotCommand);
00421 }
00422 
00423 int emcAxisSetFerror(int axis, double ferror)
00424 {
00425   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00426   {
00427     return 0;
00428   }
00429 
00430   emcmotCommand.command = EMCMOT_SET_MAX_FERROR;
00431   emcmotCommand.axis = axis;
00432   emcmotCommand.maxFerror = ferror;
00433 
00434 #ifdef ISNAN_TRAP
00435   if (isnan(emcmotCommand.maxFerror))
00436   {
00437     printf("isnan error in emcAxisSetFerror\n");
00438     return -1;
00439   }
00440 #endif
00441 
00442   return usrmotWriteEmcmotCommand(&emcmotCommand);
00443 }
00444 
00445 int emcAxisSetMinFerror(int axis, double ferror)
00446 {
00447   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00448   {
00449     return 0;
00450   }
00451 
00452   emcmotCommand.command = EMCMOT_SET_MIN_FERROR;
00453   emcmotCommand.axis = axis;
00454   emcmotCommand.minFerror = ferror;
00455 
00456 #ifdef ISNAN_TRAP
00457   if (isnan(emcmotCommand.minFerror))
00458   {
00459     printf("isnan error in emcAxisSetMinFerror\n");
00460     return -1;
00461   }
00462 #endif
00463 
00464   return usrmotWriteEmcmotCommand(&emcmotCommand);
00465 }
00466 
00467 int emcAxisSetHomingVel(int axis, double homingVel)
00468 {
00469   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00470   {
00471     return 0;
00472   }
00473 
00474   emcmotCommand.command = EMCMOT_SET_HOMING_VEL;
00475   emcmotCommand.axis = axis;
00476   emcmotCommand.vel = homingVel;
00477 
00478 #ifdef ISNAN_TRAP
00479   if (isnan(emcmotCommand.vel))
00480   {
00481     printf("isnan error in emcAxisSetHomingVel\n");
00482     return -1;
00483   }
00484 #endif
00485 
00486   return usrmotWriteEmcmotCommand(&emcmotCommand);
00487 }
00488 
00489 int emcAxisSetMaxVelocity(int axis, double vel)
00490 {
00491   if (axis < 0 || axis >= EMC_AXIS_MAX)
00492   {
00493     return 0;
00494   }
00495 
00496   if (vel < 0.0)
00497   {
00498     vel = 0.0;
00499   }
00500 
00501   AXIS_MAX_VELOCITY[axis] = vel;
00502 
00503   emcmotCommand.command = EMCMOT_SET_AXIS_VEL_LIMIT;
00504   emcmotCommand.axis = axis;
00505   emcmotCommand.vel = vel;
00506 
00507   return usrmotWriteEmcmotCommand(&emcmotCommand);
00508 }
00509 
00510 int emcAxisSetHomeOffset(int axis, double offset)
00511 {
00512   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00513   {
00514     return 0;
00515   }
00516 
00517   emcmotCommand.command = EMCMOT_SET_HOME_OFFSET;
00518   emcmotCommand.axis = axis;
00519   emcmotCommand.offset = offset;
00520 
00521 #ifdef ISNAN_TRAP
00522   if (isnan(emcmotCommand.offset))
00523   {
00524     printf("isnan error in emcAxisSetHomeOffset\n");
00525     return -1;
00526   }
00527 #endif
00528 
00529   return usrmotWriteEmcmotCommand(&emcmotCommand);
00530 }
00531 
00532 int emcAxisSetEnablePolarity(int axis, int level)
00533 {
00534   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00535   {
00536     return 0;
00537   }
00538 
00539   emcmotCommand.command = EMCMOT_SET_POLARITY;
00540   emcmotCommand.axis = axis;
00541   emcmotCommand.level = level;
00542   emcmotCommand.axisFlag = EMCMOT_AXIS_ENABLE_BIT;
00543 
00544   return usrmotWriteEmcmotCommand(&emcmotCommand);
00545 }
00546 
00547 int emcAxisSetMinLimitSwitchPolarity(int axis, int level)
00548 {
00549   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00550   {
00551     return 0;
00552   }
00553 
00554   emcmotCommand.command = EMCMOT_SET_POLARITY;
00555   emcmotCommand.axis = axis;
00556   emcmotCommand.level = level;
00557   emcmotCommand.axisFlag = EMCMOT_AXIS_MIN_HARD_LIMIT_BIT;
00558 
00559   return usrmotWriteEmcmotCommand(&emcmotCommand);
00560 }
00561 
00562 int emcAxisSetMaxLimitSwitchPolarity(int axis, int level)
00563 {
00564   if (axis < 0)
00565   {
00566     axis = 0;
00567   }
00568   else if (axis >= EMCMOT_MAX_AXIS)
00569   {
00570     axis = EMCMOT_MAX_AXIS - 1;
00571   }
00572 
00573   emcmotCommand.command = EMCMOT_SET_POLARITY;
00574   emcmotCommand.axis = axis;
00575   emcmotCommand.level = level;
00576   emcmotCommand.axisFlag = EMCMOT_AXIS_MAX_HARD_LIMIT_BIT;
00577 
00578   return usrmotWriteEmcmotCommand(&emcmotCommand);
00579 }
00580 
00581 int emcAxisSetHomeSwitchPolarity(int axis, int level)
00582 {
00583   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00584   {
00585     return 0;
00586   }
00587 
00588   emcmotCommand.command = EMCMOT_SET_POLARITY;
00589   emcmotCommand.axis = axis;
00590   emcmotCommand.level = level;
00591   emcmotCommand.axisFlag = EMCMOT_AXIS_HOME_SWITCH_BIT;
00592 
00593   return usrmotWriteEmcmotCommand(&emcmotCommand);
00594 }
00595 
00596 int emcAxisSetHomingPolarity(int axis, int level)
00597 {
00598   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00599   {
00600     return 0;
00601   }
00602 
00603   emcmotCommand.command = EMCMOT_SET_POLARITY;
00604   emcmotCommand.axis = axis;
00605   emcmotCommand.level = level;
00606   emcmotCommand.axisFlag = EMCMOT_AXIS_HOMING_BIT;
00607 
00608   return usrmotWriteEmcmotCommand(&emcmotCommand);
00609 }
00610 
00611 int emcAxisSetFaultPolarity(int axis, int level)
00612 {
00613   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00614   {
00615     return 0;
00616   }
00617 
00618   emcmotCommand.command = EMCMOT_SET_POLARITY;
00619   emcmotCommand.axis = axis;
00620   emcmotCommand.level = level;
00621   emcmotCommand.axisFlag = EMCMOT_AXIS_FAULT_BIT;
00622 
00623   return usrmotWriteEmcmotCommand(&emcmotCommand);
00624 }
00625 
00626 int emcAxisInit(int axis)
00627 {
00628   int retval = 0;
00629 
00630   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00631   {
00632     return 0;
00633   }
00634 
00635   // init emcmot interface
00636   if (! emcmotAxisInited &&
00637       ! emcmotTrajInited)
00638   {
00639     usrmotIniLoad(EMC_INIFILE);
00640 
00641     if (0 != usrmotInit())
00642     {
00643       return -1;
00644     }
00645   }
00646   emcmotAxisInited = 1;
00647 
00648   if (0 != iniAxis(axis, EMC_INIFILE))
00649   {
00650     retval = -1;
00651   }
00652 
00653   return retval;
00654 }
00655 
00656 int emcAxisHalt(int axis)
00657 {
00658   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00659   {
00660     return 0;
00661   }
00662 
00663   // FIXME-- refs global emcStatus; should make EMC_AXIS_STAT an arg here
00664   if(NULL != emcStatus && emcmotion_initialized && emcmotAxisInited)
00665   {
00666     dumpAxis(axis, EMC_INIFILE, &emcStatus->motion.axis[axis]);
00667   }
00668 
00669   if (! emcmotTrajInited)       // traj clears its inited flag on exit
00670   {
00671     usrmotExit();               // ours is final exit
00672   }
00673   emcmotAxisInited = 0;
00674 
00675   return 0;
00676 }
00677 
00678 int emcAxisAbort(int axis)
00679 {
00680   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00681   {
00682     return 0;
00683   }
00684 
00685   emcmotCommand.command = EMCMOT_ABORT;
00686   emcmotCommand.axis = axis;
00687 
00688   return usrmotWriteEmcmotCommand(&emcmotCommand);
00689 }
00690 
00691 int emcAxisActivate(int axis)
00692 {
00693   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00694   {
00695     return 0;
00696   }
00697 
00698   emcmotCommand.command = EMCMOT_ACTIVATE_AXIS;
00699   emcmotCommand.axis = axis;
00700 
00701   return usrmotWriteEmcmotCommand(&emcmotCommand);
00702 }
00703 
00704 int emcAxisDeactivate(int axis)
00705 {
00706   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00707   {
00708     return 0;
00709   }
00710 
00711   emcmotCommand.command = EMCMOT_DEACTIVATE_AXIS;
00712   emcmotCommand.axis = axis;
00713 
00714   return usrmotWriteEmcmotCommand(&emcmotCommand);
00715 }
00716 
00717 int emcAxisOverrideLimits(int axis)
00718 {
00719   // can have axis < 0, for resuming normal limit checking
00720   if (axis >= EMCMOT_MAX_AXIS)
00721   {
00722     return 0;
00723   }
00724 
00725   emcmotCommand.command = EMCMOT_OVERRIDE_LIMITS;
00726   emcmotCommand.axis = axis;
00727 
00728   return usrmotWriteEmcmotCommand(&emcmotCommand);
00729 
00730 }
00731 
00732 int emcAxisSetOutput(int axis, double output)
00733 {
00734   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00735   {
00736     return 0;
00737   }
00738 
00739   emcmotCommand.command = EMCMOT_DAC_OUT;
00740   emcmotCommand.axis = axis;
00741   emcmotCommand.dacOut = output;
00742 
00743   return usrmotWriteEmcmotCommand(&emcmotCommand);
00744 }
00745 
00746 int emcAxisEnable(int axis)
00747 {
00748   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00749   {
00750     return 0;
00751   }
00752 
00753   emcmotCommand.command = EMCMOT_ENABLE_AMPLIFIER;
00754   emcmotCommand.axis = axis;
00755 
00756   return usrmotWriteEmcmotCommand(&emcmotCommand);
00757 }
00758 
00759 int emcAxisDisable(int axis)
00760 {
00761   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00762   {
00763     return 0;
00764   }
00765 
00766   emcmotCommand.command = EMCMOT_DISABLE_AMPLIFIER;
00767   emcmotCommand.axis = axis;
00768 
00769   return usrmotWriteEmcmotCommand(&emcmotCommand);
00770 }
00771 
00772 int emcAxisHome(int axis)
00773 {
00774   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00775   {
00776     return 0;
00777   }
00778 
00779   emcmotCommand.command = EMCMOT_HOME;
00780   emcmotCommand.axis = axis;
00781 
00782   return usrmotWriteEmcmotCommand(&emcmotCommand);
00783 }
00784 
00785 int emcAxisSetHome(int axis, double home)
00786 {
00787   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00788   {
00789     return 0;
00790   }
00791 
00792   emcmotCommand.command = EMCMOT_SET_JOINT_HOME;
00793   emcmotCommand.axis = axis;
00794   emcmotCommand.offset = home;
00795 
00796   return usrmotWriteEmcmotCommand(&emcmotCommand);
00797 }
00798 
00799 int emcAxisJog(int axis, double vel)
00800 {
00801   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00802   {
00803     return 0;
00804   }
00805 
00806   if (vel > AXIS_MAX_VELOCITY[axis])
00807   {
00808     vel = AXIS_MAX_VELOCITY[axis];
00809   }
00810   else if (vel < -AXIS_MAX_VELOCITY[axis])
00811   {
00812     vel = -AXIS_MAX_VELOCITY[axis];
00813   }
00814 
00815   emcmotCommand.command = EMCMOT_JOG_CONT;
00816   emcmotCommand.axis = axis;
00817   emcmotCommand.vel = vel;
00818 
00819   return usrmotWriteEmcmotCommand(&emcmotCommand);
00820 }
00821 
00822 int emcAxisIncrJog(int axis, double incr, double vel)
00823 {
00824   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00825   {
00826     return 0;
00827   }
00828 
00829   if (vel > AXIS_MAX_VELOCITY[axis])
00830   {
00831     vel = AXIS_MAX_VELOCITY[axis];
00832   }
00833   else if (vel < -AXIS_MAX_VELOCITY[axis])
00834   {
00835     vel = -AXIS_MAX_VELOCITY[axis];
00836   }
00837 
00838   emcmotCommand.command = EMCMOT_JOG_INCR;
00839   emcmotCommand.axis = axis;
00840   emcmotCommand.vel = vel;
00841   emcmotCommand.offset = incr;
00842 
00843   return usrmotWriteEmcmotCommand(&emcmotCommand);
00844 }
00845 
00846 int emcAxisAbsJog(int axis, double pos, double vel)
00847 {
00848   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
00849   {
00850     return 0;
00851   }
00852 
00853   if (vel > AXIS_MAX_VELOCITY[axis])
00854   {
00855     vel = AXIS_MAX_VELOCITY[axis];
00856   }
00857   else if (vel < -AXIS_MAX_VELOCITY[axis])
00858   {
00859     vel = -AXIS_MAX_VELOCITY[axis];
00860   }
00861 
00862   emcmotCommand.command = EMCMOT_JOG_ABS;
00863   emcmotCommand.axis = axis;
00864   emcmotCommand.vel = vel;
00865   emcmotCommand.offset = pos;
00866 
00867   return usrmotWriteEmcmotCommand(&emcmotCommand);
00868 }
00869 
00870 int emcAxisLoadComp(int axis, const char * file)
00871 {
00872   return usrmotLoadComp(axis, file);
00873 }
00874 
00875 int emcAxisAlter(int axis, double alter)
00876 {
00877   return usrmotAlter(axis, alter);
00878 }
00879 
00880 static EMCMOT_CONFIG emcmotConfig;
00881 int get_emcmot_debug_info = 0;
00882 
00883 /*
00884   these globals are set in emcMotionUpdate(), then referenced in
00885   emcAxisUpdate(), emcTrajUpdate() to save calls to usrmotReadEmcmotStatus
00886  */
00887 static EMCMOT_STATUS emcmotStatus;
00888 static EMCMOT_DEBUG emcmotDebug;
00889 static char errorString[EMCMOT_ERROR_LEN];
00890 static int new_config = 0;
00891 
00892 int emcAxisUpdate(EMC_AXIS_STAT stat[], int numAxes)
00893 {
00894   int axis;
00895 
00896   // check for valid range
00897   if (numAxes <= 0 || numAxes > EMCMOT_MAX_AXIS) {
00898     return -1;
00899   }
00900 
00901   for (axis = 0; axis < numAxes; axis++) {
00902     stat[axis].axisType = localEmcAxisAxisType[axis];
00903     stat[axis].units = localEmcAxisUnits[axis];
00904 
00905     stat[axis].inputScale = emcmotStatus.inputScale[axis];
00906     stat[axis].inputOffset = emcmotStatus.inputOffset[axis];
00907     stat[axis].outputScale = emcmotStatus.outputScale[axis];
00908     stat[axis].outputOffset = emcmotStatus.outputOffset[axis];
00909 
00910     if (new_config) {
00911       stat[axis].p = emcmotConfig.pid[axis].p;
00912       stat[axis].i = emcmotConfig.pid[axis].i;
00913       stat[axis].d = emcmotConfig.pid[axis].d;
00914       stat[axis].ff0 = emcmotConfig.pid[axis].ff0;
00915       stat[axis].ff1 = emcmotConfig.pid[axis].ff1;
00916       stat[axis].ff2 = emcmotConfig.pid[axis].ff2;
00917       stat[axis].backlash = emcmotConfig.pid[axis].backlash;
00918       stat[axis].bias = emcmotConfig.pid[axis].bias;
00919       stat[axis].maxError = emcmotConfig.pid[axis].maxError;
00920       stat[axis].deadband = emcmotConfig.pid[axis].deadband;
00921       stat[axis].cycleTime = emcmotConfig.servoCycleTime;
00922       stat[axis].minPositionLimit = emcmotConfig.minLimit[axis];
00923       stat[axis].maxPositionLimit = emcmotConfig.maxLimit[axis];
00924       stat[axis].minOutputLimit = emcmotConfig.minOutput[axis];
00925       stat[axis].maxOutputLimit = emcmotConfig.maxOutput[axis];
00926       stat[axis].minFerror = emcmotConfig.minFerror[axis];
00927       stat[axis].maxFerror = emcmotConfig.maxFerror[axis];
00928       stat[axis].homeOffset = emcmotConfig.homeOffset[axis];
00929       stat[axis].enablePolarity = (emcmotConfig.axisPolarity[axis] &
00930                                    EMCMOT_AXIS_ENABLE_BIT) ? 1 : 0;
00931       stat[axis].minLimitSwitchPolarity = (emcmotConfig.axisPolarity[axis] &
00932                                            EMCMOT_AXIS_MIN_HARD_LIMIT_BIT) ? 1 : 0;
00933       stat[axis].maxLimitSwitchPolarity = (emcmotConfig.axisPolarity[axis] &
00934                                            EMCMOT_AXIS_MAX_HARD_LIMIT_BIT) ? 1 : 0;
00935       stat[axis].homeSwitchPolarity = (emcmotConfig.axisPolarity[axis] &
00936                                        EMCMOT_AXIS_HOME_SWITCH_BIT) ? 1 : 0;
00937       stat[axis].homingPolarity = (emcmotConfig.axisPolarity[axis] &
00938                                    EMCMOT_AXIS_HOMING_BIT) ? 1 : 0;
00939       stat[axis].faultPolarity = (emcmotConfig.axisPolarity[axis] &
00940                                   EMCMOT_AXIS_FAULT_BIT) ? 1 : 0;
00941     }
00942 
00943     stat[axis].setpoint = emcmotStatus.axisPos[axis];
00944      
00945     if (get_emcmot_debug_info) {
00946       stat[axis].ferrorCurrent = emcmotDebug.ferrorCurrent[axis];
00947       stat[axis].ferrorHighMark = emcmotDebug.ferrorHighMark[axis];
00948     }
00949       
00950     stat[axis].output = emcmotStatus.output[axis];
00951     stat[axis].input = emcmotStatus.input[axis];
00952     stat[axis].homing = (emcmotStatus.axisFlag[axis] & EMCMOT_AXIS_HOMING_BIT ? 1 : 0);
00953     stat[axis].homed = (emcmotStatus.axisFlag[axis] & EMCMOT_AXIS_HOMED_BIT ? 1 : 0);
00954     stat[axis].fault = (emcmotStatus.axisFlag[axis] & EMCMOT_AXIS_FAULT_BIT ? 1 : 0);
00955     stat[axis].enabled = (emcmotStatus.axisFlag[axis] & EMCMOT_AXIS_ENABLE_BIT ? 1 : 0);
00956 
00957     stat[axis].minSoftLimit = (emcmotStatus.axisFlag[axis] & EMCMOT_AXIS_MIN_SOFT_LIMIT_BIT ? 1 : 0);
00958     stat[axis].maxSoftLimit = (emcmotStatus.axisFlag[axis] & EMCMOT_AXIS_MAX_SOFT_LIMIT_BIT ? 1 : 0);
00959     stat[axis].minHardLimit = (emcmotStatus.axisFlag[axis] & EMCMOT_AXIS_MIN_HARD_LIMIT_BIT ? 1 : 0);
00960     stat[axis].maxHardLimit = (emcmotStatus.axisFlag[axis] & EMCMOT_AXIS_MAX_HARD_LIMIT_BIT ? 1 : 0);
00961     stat[axis].overrideLimits = (emcmotStatus.overrideLimits); // one for all
00962 
00963     stat[axis].scale = emcmotStatus.axVscale[axis];
00964     usrmotQueryAlter(axis, &stat[axis].alter);
00965 
00966     if (emcmotStatus.axisFlag[axis] & EMCMOT_AXIS_ERROR_BIT) {
00967       if (stat[axis].status != RCS_ERROR) {
00968         rcs_print_error("Error on axis %d.\n",axis);
00969         stat[axis].status = RCS_ERROR;
00970       }
00971     }
00972     else if (emcmotStatus.axisFlag[axis] & EMCMOT_AXIS_INPOS_BIT) {
00973       stat[axis].status = RCS_DONE;
00974     }
00975     else {
00976       stat[axis].status = RCS_EXEC;
00977     }
00978   }
00979 
00980   return 0;
00981 }
00982 
00983 // EMC_TRAJ functions
00984 
00985 // local status data, not provided by emcmot
00986 static int localEmcTrajAxes = 0;
00987 static double localEmcTrajLinearUnits = 1.0;
00988 static double localEmcTrajAngularUnits = 1.0;
00989 static int localEmcTrajMotionId = 0;
00990 
00991 int emcTrajSetAxes(int axes)
00992 {
00993   if (axes <= 0 || axes > EMCMOT_MAX_AXIS)
00994   {
00995     return -1;
00996   }
00997 
00998   localEmcTrajAxes = axes;
00999 
01000   return 0;
01001 }
01002 
01003 int emcTrajSetUnits(double linearUnits, double angularUnits)
01004 {
01005   if (linearUnits <= 0.0 ||
01006       angularUnits <= 0.0)
01007   {
01008     return -1;
01009   }
01010 
01011   localEmcTrajLinearUnits = linearUnits;
01012   localEmcTrajAngularUnits = angularUnits;
01013 
01014   return 0;
01015 }
01016 
01017 int emcTrajSetCycleTime(double cycleTime)
01018 {
01019   if (cycleTime <= 0.0)
01020   {
01021     return -1;
01022   }
01023 
01024   emcmotCommand.command = EMCMOT_SET_TRAJ_CYCLE_TIME;
01025   emcmotCommand.cycleTime = cycleTime;
01026 
01027   return usrmotWriteEmcmotCommand(&emcmotCommand);
01028 }
01029 
01030 int emcTrajSetMode(int mode)
01031 {
01032   switch (mode)
01033   {
01034     case EMC_TRAJ_MODE_FREE:
01035       emcmotCommand.command = EMCMOT_FREE;
01036       return usrmotWriteEmcmotCommand(&emcmotCommand);
01037 
01038     case EMC_TRAJ_MODE_COORD:
01039       emcmotCommand.command = EMCMOT_COORD;
01040       return usrmotWriteEmcmotCommand(&emcmotCommand);
01041 
01042     case EMC_TRAJ_MODE_TELEOP:
01043       emcmotCommand.command = EMCMOT_TELEOP;
01044       return usrmotWriteEmcmotCommand(&emcmotCommand);
01045 
01046     default:
01047       return -1;
01048   }
01049 }
01050 
01051 
01052 
01053 int emcTrajSetTeleopVector(EmcPose vel)
01054 {
01055   emcmotCommand.command = EMCMOT_SET_TELEOP_VECTOR;
01056   emcmotCommand.pos = vel;
01057   return usrmotWriteEmcmotCommand(&emcmotCommand);
01058 }
01059 
01060 int emcTrajSetVelocity(double vel)
01061 {
01062   int retval;
01063 
01064   if (vel < 0.0)
01065   {
01066     vel = 0.0;
01067   }
01068   else if (vel > TRAJ_MAX_VELOCITY)
01069   {
01070     vel = TRAJ_MAX_VELOCITY;
01071   }
01072 
01073 #if 0
01074   // FIXME-- this fixes rapid rate reset problem
01075   if (vel == lastVel)
01076   {
01077     // suppress it
01078     return 0;
01079   }
01080 #endif
01081 
01082   emcmotCommand.command = EMCMOT_SET_VEL;
01083   emcmotCommand.vel = vel;
01084 
01085   retval = usrmotWriteEmcmotCommand(&emcmotCommand);
01086 
01087   if (0 == retval)
01088   {
01089     lastVel = vel;
01090   }
01091 
01092   return retval;
01093 }
01094 
01095 int emcTrajSetAcceleration(double acc)
01096 {
01097   if (acc < 0.0)
01098   {
01099     acc = 0.0;
01100   }
01101   else if (acc > localEmcMaxAcceleration)
01102   {
01103     acc = localEmcMaxAcceleration;
01104   }
01105 
01106   emcmotCommand.command = EMCMOT_SET_ACC;
01107   emcmotCommand.acc = acc;
01108 
01109   return usrmotWriteEmcmotCommand(&emcmotCommand);
01110 }
01111 
01112 /*
01113   emcmot has no limits on max velocity, acceleration so we'll save them
01114   here and apply them in the functions above
01115   */
01116 int emcTrajSetMaxVelocity(double vel)
01117 {
01118   if (vel < 0.0)
01119   {
01120     vel = 0.0;
01121   }
01122 
01123   TRAJ_MAX_VELOCITY = vel;
01124 
01125   emcmotCommand.command = EMCMOT_SET_VEL_LIMIT;
01126   emcmotCommand.vel = vel;
01127 
01128   return usrmotWriteEmcmotCommand(&emcmotCommand);
01129 }
01130 
01131 int emcTrajSetMaxAcceleration(double acc)
01132 {
01133   if (acc < 0.0)
01134   {
01135     acc = 0.0;
01136   }
01137 
01138   localEmcMaxAcceleration = acc;
01139 
01140   return 0;
01141 }
01142 
01143 int emcTrajSetHome(EmcPose home)
01144 {
01145   emcmotCommand.command = EMCMOT_SET_WORLD_HOME;
01146 
01147   emcmotCommand.pos = home;
01148 
01149 
01150 #ifdef ISNAN_TRAP
01151   if (isnan(emcmotCommand.pos.tran.x) ||
01152       isnan(emcmotCommand.pos.tran.y) ||
01153       isnan(emcmotCommand.pos.tran.z))
01154   {
01155     printf("isnan error in emcTrajSetHome\n");
01156     return 0;                 // ignore it for now, just don't send it
01157   }
01158 #endif
01159 
01160   return usrmotWriteEmcmotCommand(&emcmotCommand);
01161 }
01162 
01163 int emcTrajSetScale(double scale)
01164 {
01165   if (scale < 0.0)
01166   {
01167     scale = 0.0;
01168   }
01169 
01170   emcmotCommand.command = EMCMOT_SCALE;
01171   emcmotCommand.scale = scale;
01172 
01173   return usrmotWriteEmcmotCommand(&emcmotCommand);
01174 }
01175 
01176 int emcTrajSetMotionId(int id)
01177 {
01178 
01179   if(EMC_DEBUG_MOTION_TIME & EMC_DEBUG)
01180     {
01181       if(id != localEmcTrajMotionId)
01182         {
01183           rcs_print("Outgoing motion id is %d.\n",id);
01184         }
01185     }
01186   localEmcTrajMotionId = id;
01187 
01188   return 0;
01189 }
01190 
01191 int emcTrajInit()
01192 {
01193   int retval = 0;
01194 
01195   // init emcmot interface
01196   if (! emcmotAxisInited &&
01197       ! emcmotTrajInited)
01198   {
01199     usrmotIniLoad(EMC_INIFILE);
01200 
01201     if (0 != usrmotInit())
01202     {
01203       return -1;
01204     }
01205   }
01206   emcmotTrajInited = 1;
01207 
01208   // initialize parameters from ini file
01209   if (0 != iniTraj(EMC_INIFILE))
01210   {
01211     retval = -1;
01212   }
01213 
01214   return retval;
01215 }
01216 
01217 int emcTrajHalt()
01218 {
01219   if (! emcmotAxisInited)       // axis clears its inited flag on exit
01220   {
01221     usrmotExit();             // ours is final exit
01222   }
01223   emcmotTrajInited = 0;
01224 
01225   return 0;
01226 }
01227 
01228 int emcTrajEnable()
01229 {
01230   emcmotCommand.command = EMCMOT_ENABLE;
01231 
01232   return usrmotWriteEmcmotCommand(&emcmotCommand);
01233 }
01234 
01235 int emcTrajDisable()
01236 {
01237   emcmotCommand.command = EMCMOT_DISABLE;
01238 
01239   return usrmotWriteEmcmotCommand(&emcmotCommand);
01240 }
01241 
01242 int emcTrajAbort()
01243 {
01244   emcmotCommand.command = EMCMOT_ABORT;
01245 
01246   return usrmotWriteEmcmotCommand(&emcmotCommand);
01247 }
01248 
01249 int emcTrajPause()
01250 {
01251   emcmotCommand.command = EMCMOT_PAUSE;
01252 
01253   return usrmotWriteEmcmotCommand(&emcmotCommand);
01254 }
01255 
01256 int emcTrajStep()
01257 {
01258   emcmotCommand.command = EMCMOT_STEP;
01259 
01260   return usrmotWriteEmcmotCommand(&emcmotCommand);
01261 }
01262 
01263 int emcTrajResume()
01264 {
01265   emcmotCommand.command = EMCMOT_RESUME;
01266 
01267   return usrmotWriteEmcmotCommand(&emcmotCommand);
01268 }
01269 
01270 int emcTrajDelay(double delay)
01271 {
01272   // nothing need be done here-- it's done in task controller
01273 
01274   return 0;
01275 }
01276 
01277 int emcTrajSetTermCond(int cond)
01278 {
01279   emcmotCommand.command = EMCMOT_SET_TERM_COND;
01280   emcmotCommand.termCond = (cond == EMC_TRAJ_TERM_COND_STOP ? EMCMOT_TERM_COND_STOP : EMCMOT_TERM_COND_BLEND);
01281 
01282   return usrmotWriteEmcmotCommand(&emcmotCommand);
01283 }
01284 
01285 int emcTrajLinearMove(EmcPose end)
01286 {
01287   emcmotCommand.command = EMCMOT_SET_LINE;
01288 
01289   emcmotCommand.pos = end;
01290 
01291   emcmotCommand.id = localEmcTrajMotionId;
01292 
01293 #ifdef ISNAN_TRAP
01294   if (isnan(emcmotCommand.pos.tran.x) ||
01295       isnan(emcmotCommand.pos.tran.y) ||
01296       isnan(emcmotCommand.pos.tran.z))
01297   {
01298     printf("isnan error in emcTrajLinearMove\n");
01299     return 0;                 // ignore it for now, just don't send it
01300   }
01301 #endif
01302 
01303   return usrmotWriteEmcmotCommand(&emcmotCommand);
01304 }
01305 
01306 int emcTrajCircularMove(EmcPose end, PM_CARTESIAN center,
01307                         PM_CARTESIAN normal, int turn)
01308 {
01309   emcmotCommand.command = EMCMOT_SET_CIRCLE;
01310 
01311   emcmotCommand.pos  = end;
01312 
01313   emcmotCommand.center.x = center.x;
01314   emcmotCommand.center.y = center.y;
01315   emcmotCommand.center.z = center.z;
01316 
01317   emcmotCommand.normal.x = normal.x;
01318   emcmotCommand.normal.y = normal.y;
01319   emcmotCommand.normal.z = normal.z;
01320 
01321   emcmotCommand.turn = turn;
01322   emcmotCommand.id = localEmcTrajMotionId;
01323 
01324 #ifdef ISNAN_TRAP
01325   if (isnan(emcmotCommand.pos.tran.x) ||
01326       isnan(emcmotCommand.pos.tran.y) ||
01327       isnan(emcmotCommand.pos.tran.z) ||
01328       isnan(emcmotCommand.pos.a) ||
01329       isnan(emcmotCommand.pos.b) ||
01330       isnan(emcmotCommand.pos.c) ||
01331       isnan(emcmotCommand.center.x) ||
01332       isnan(emcmotCommand.center.y) ||
01333       isnan(emcmotCommand.center.z) ||
01334       isnan(emcmotCommand.normal.x) ||
01335       isnan(emcmotCommand.normal.y) ||
01336       isnan(emcmotCommand.normal.z))
01337   {
01338     printf("isnan error in emcTrajCircularMove\n");
01339     return 0;                 // ignore it for now, just don't send it
01340   }
01341 #endif
01342 
01343   return usrmotWriteEmcmotCommand(&emcmotCommand);
01344 }
01345 
01346 int emcTrajSetProbeIndex(int index)
01347 {
01348   emcmotCommand.command = EMCMOT_SET_PROBE_INDEX;
01349   emcmotCommand.probeIndex = index;
01350 
01351   return usrmotWriteEmcmotCommand(&emcmotCommand);
01352 }
01353 
01354 int emcTrajSetProbePolarity(int polarity)
01355 {
01356   emcmotCommand.command = EMCMOT_SET_PROBE_POLARITY;
01357   emcmotCommand.level = polarity;
01358 
01359   return usrmotWriteEmcmotCommand(&emcmotCommand);
01360 }
01361 
01362 int emcTrajClearProbeTrippedFlag()
01363 {
01364   emcmotCommand.command = EMCMOT_CLEAR_PROBE_FLAGS;
01365 
01366   return usrmotWriteEmcmotCommand(&emcmotCommand);
01367 }
01368 
01369 int emcTrajProbe(EmcPose pos)
01370 {
01371   emcmotCommand.command = EMCMOT_PROBE;
01372   emcmotCommand.pos.tran.x = pos.tran.x;
01373   emcmotCommand.pos.tran.y = pos.tran.y;
01374   emcmotCommand.pos.tran.z = pos.tran.z;
01375   emcmotCommand.id = localEmcTrajMotionId;
01376   return usrmotWriteEmcmotCommand(&emcmotCommand);
01377 }
01378 
01379 static int last_id_printed = 0;
01380 static int last_status = 0;
01381 static int last_id = 0;
01382 static double last_id_time;
01383 
01384 int emcTrajUpdate(EMC_TRAJ_STAT *stat)
01385 {
01386   int axis;
01387 
01388   stat->axes = localEmcTrajAxes;
01389   stat->linearUnits = localEmcTrajLinearUnits;
01390   stat->angularUnits = localEmcTrajAngularUnits;
01391 
01392   stat->mode = 
01393     emcmotStatus.motionFlag & EMCMOT_MOTION_TELEOP_BIT ? EMC_TRAJ_MODE_TELEOP :
01394     ( emcmotStatus.motionFlag & EMCMOT_MOTION_COORD_BIT ? EMC_TRAJ_MODE_COORD : 
01395       EMC_TRAJ_MODE_FREE ) ;
01396 
01397   // enabled iff motion enabled and all axes enabled
01398   stat->enabled = 0;            // start at disabled
01399   if (emcmotStatus.motionFlag & EMCMOT_MOTION_ENABLE_BIT) {
01400     for (axis = 0; axis < localEmcTrajAxes; axis++) {
01401       if (! emcmotStatus.axisFlag[axis] & EMCMOT_AXIS_ENABLE_BIT) {
01402         break;
01403       }
01404 
01405       // got here, then all are enabled
01406       stat->enabled = 1;
01407     }
01408   }
01409 
01410   stat->inpos = emcmotStatus.motionFlag & EMCMOT_MOTION_INPOS_BIT ? 1 : 0;
01411   stat->queue = emcmotStatus.depth;
01412   stat->activeQueue = emcmotStatus.activeDepth;
01413   stat->queueFull = emcmotStatus.queueFull;
01414   stat->id = emcmotStatus.id;
01415   if (EMC_DEBUG_MOTION_TIME & EMC_DEBUG) {
01416     if (stat->id != last_id) {
01417       if (last_id != last_id_printed) {
01418         rcs_print("Motion id %d took %f seconds.\n",last_id, etime()-last_id_time);
01419         last_id_printed = last_id;
01420       }
01421       last_id = stat->id;
01422       last_id_time = etime();
01423     }
01424   }
01425 
01426   stat->paused = emcmotStatus.paused;
01427   stat->scale = emcmotStatus.qVscale;
01428 
01429   stat->position = emcmotStatus.pos;
01430 
01431   stat->actualPosition = emcmotStatus.actualPos;
01432 
01433   stat->velocity = emcmotStatus.vel;
01434   stat->acceleration = emcmotStatus.acc;
01435   stat->maxAcceleration = localEmcMaxAcceleration;
01436 
01437   if (emcmotStatus.motionFlag & EMCMOT_MOTION_ERROR_BIT) {
01438     stat->status = RCS_ERROR;
01439   }
01440   else if (stat->inpos &&
01441            (stat->queue == 0)) {
01442     stat->status = RCS_DONE;
01443   }
01444   else {
01445     stat->status = RCS_EXEC;
01446   }
01447 
01448   if (EMC_DEBUG_MOTION_TIME & EMC_DEBUG) {
01449     if(stat->status == RCS_DONE && last_status != RCS_DONE && stat->id != last_id_printed) {
01450       rcs_print("Motion id %d took %f seconds.\n",last_id, etime()-last_id_time);
01451       last_id_printed = last_id = stat->id;
01452       last_id_time = etime();
01453     }
01454   }
01455 
01456   // update logging
01457   if (emcmotStatus.logOpen) {
01458     // we're logging motion
01459     emcStatus->logType = emcmotStatus.logType;
01460     emcStatus->logSize = emcmotStatus.logSize;
01461     emcStatus->logSkip = emcmotStatus.logSkip;
01462     emcStatus->logOpen = emcmotStatus.logOpen;
01463     emcStatus->logStarted = emcmotStatus.logStarted;
01464     emcStatus->logPoints = emcmotStatus.logPoints;
01465   }
01466   // else if it's not open, don't update emcStatus-- someone else may
01467   // be logging
01468 
01469   stat->probedPosition.tran.x = emcmotStatus.probedPos.tran.x;
01470   stat->probedPosition.tran.y = emcmotStatus.probedPos.tran.y;
01471   stat->probedPosition.tran.z = emcmotStatus.probedPos.tran.z;
01472   stat->probeval = emcmotStatus.probeval;
01473   stat->probe_tripped = emcmotStatus.probeTripped;
01474 
01475   if (new_config) {
01476     stat->cycleTime = emcmotConfig.trajCycleTime;
01477     stat->probe_index = emcmotConfig.probeIndex;
01478     stat->probe_polarity = emcmotConfig.probePolarity;
01479     stat->kinematics_type = emcmotConfig.kinematics_type;
01480     stat->maxVelocity = emcmotConfig.limitVel;
01481   }
01482 
01483   return 0;
01484 }
01485 
01486 // EMC_MOTION functions
01487 int emcMotionInit()
01488 {
01489   int r1;
01490   int r2;
01491   int axis;
01492 
01493   r1 = -1;
01494   for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01495   {
01496     if (0 == emcAxisInit(axis))
01497     {
01498       r1 = 0;               // at least one is okay
01499     }
01500   }
01501 
01502   r2 = emcTrajInit();
01503 
01504   if(r1 == 0 && r2 == 0)
01505   {
01506     emcmotion_initialized=1;
01507   }
01508 
01509   return (r1 == 0 &&
01510           r2 == 0) ? 0 : -1;
01511 }
01512 
01513 int emcMotionHalt()
01514 {
01515   int r1;
01516   int r2;
01517   int t;
01518 
01519   r1 = -1;
01520   for (t = 0; t < EMCMOT_MAX_AXIS; t++)
01521   {
01522     if (0 == emcAxisHalt(t))
01523     {
01524       r1 = 0;               // at least one is okay
01525     }
01526   }
01527 
01528   r2 = emcTrajHalt();
01529 
01530   emcmotion_initialized=0;
01531   return (r1 == 0 &&
01532           r2 == 0) ? 0 : -1;
01533 }
01534 
01535 int emcMotionAbort()
01536 {
01537   int r1;
01538   int r2;
01539   int t;
01540 
01541   r1 = -1;
01542   for (t = 0; t < EMCMOT_MAX_AXIS; t++)
01543   {
01544     if (0 == emcAxisAbort(t))
01545     {
01546       r1 = 0;               // at least one is okay
01547     }
01548   }
01549 
01550   r2 = emcTrajAbort();
01551 
01552   // reset optimization flag which suppresses duplicate speed requests
01553   lastVel = -1.0;
01554 
01555   return (r1 == 0 &&
01556           r2 == 0) ? 0 : -1;
01557 }
01558 
01559 int emcMotionSetDebug(int debug)
01560 {
01561   emcmotCommand.command = EMCMOT_ABORT;
01562 
01563   return usrmotWriteEmcmotCommand(&emcmotCommand);
01564 }
01565 
01566 int emcMotionSetAout(unsigned char index, double start, double end)
01567 {
01568   emcmotCommand.command = EMCMOT_SET_AOUT;
01569   /* FIXME-- if this works, set up some dedicated cmd fields instead of
01570      borrowing these */
01571   emcmotCommand.out = index;
01572   emcmotCommand.minLimit = start;
01573   emcmotCommand.maxLimit = end;
01574 
01575   return usrmotWriteEmcmotCommand(&emcmotCommand);
01576 }
01577 
01578 int emcMotionSetDout(unsigned char index, unsigned char start, unsigned char end)
01579 {
01580   emcmotCommand.command = EMCMOT_SET_DOUT;
01581   emcmotCommand.out = index;
01582   emcmotCommand.start = start;
01583   emcmotCommand.end = end;
01584 
01585   return usrmotWriteEmcmotCommand(&emcmotCommand);
01586 }
01587 
01588 int emcMotionUpdate(EMC_MOTION_STAT *stat)
01589 {
01590   int r1;
01591   int r2;
01592   int axis;
01593   int error;
01594   int exec;
01595 
01596   // read the emcmot status
01597   if (0 != usrmotReadEmcmotStatus(&emcmotStatus)) {
01598     return -1;
01599   }
01600 
01601   new_config = 0;
01602   if (emcmotStatus.config_num != emcmotConfig.config_num) {
01603     if (0 != usrmotReadEmcmotConfig(&emcmotConfig)) {
01604       return -1;
01605     }
01606     new_config = 1;
01607   }
01608 
01609   if (get_emcmot_debug_info) {
01610     if (0 != usrmotReadEmcmotDebug(&emcmotDebug)) {
01611       return -1;
01612     }
01613   }
01614 
01615   // read the emcmot error
01616   if (0 != usrmotReadEmcmotError(errorString)) {
01617     // no error, so ignore
01618   }
01619   else {
01620     // an error to report
01621     emcOperatorError(0, errorString);
01622   }
01623 
01624   // save the heartbeat and command number locally,
01625   // for use with emcMotionUpdate
01626   localMotionHeartbeat = emcmotStatus.heartbeat;
01627   localMotionCommandType = emcmotStatus.commandEcho; // FIXME-- not NML one!
01628   localMotionEchoSerialNumber = emcmotStatus.commandNumEcho;
01629 
01630   r1 = emcAxisUpdate(&stat->axis[0], EMCMOT_MAX_AXIS);
01631   r2 = emcTrajUpdate(&stat->traj);
01632   stat->heartbeat = localMotionHeartbeat;
01633   stat->command_type = localMotionCommandType;
01634   stat->echo_serial_number = localMotionEchoSerialNumber;
01635   stat->debug = emcmotConfig.debug;
01636 
01637   // set the status flag
01638   error = 0;
01639   exec = 0;
01640 
01641   for (axis = 0; axis < stat->traj.axes; axis++) {
01642     if (stat->axis[axis].status == RCS_ERROR) {
01643       error = 1;
01644       break;
01645     }
01646     if (stat->axis[axis].status == RCS_EXEC) {
01647       exec = 1;
01648       break;
01649     }
01650   }
01651 
01652   if (stat->traj.status == RCS_ERROR) {
01653     error = 1;
01654   }
01655   else if (stat->traj.status == RCS_EXEC) {
01656     exec = 1;
01657   }
01658 
01659   if (error) {
01660     stat->status = RCS_ERROR;
01661   }
01662   else if (exec) {
01663     stat->status = RCS_EXEC;
01664   }
01665   else {
01666     stat->status = RCS_DONE;
01667   }
01668 
01669   return (r1 == 0 &&
01670           r2 == 0) ? 0 : -1;
01671 }
01672 
01673 // IO INTERFACE
01674 
01675 // the NML channels to the EMCIO controller
01676 static RCS_CMD_CHANNEL *emcIoCommandBuffer = 0;
01677 static RCS_STAT_CHANNEL *emcIoStatusBuffer = 0;
01678 
01679 // global status structure
01680 EMC_IO_STAT *emcIoStatus = 0;
01681 
01682 // serial number for communication
01683 static int emcIoCommandSerialNumber = 0;
01684 static double EMCIO_BUFFER_GET_TIMEOUT=5.0;
01685 
01686 static int emcioNmlGet()
01687 {
01688   int retval = 0;
01689   double start_time;
01690   RCS_PRINT_DESTINATION_TYPE orig_dest;
01691   if (emcIoCommandBuffer == 0)
01692     {
01693       orig_dest = get_rcs_print_destination();
01694       set_rcs_print_destination(RCS_PRINT_TO_NULL);
01695       start_time = etime();
01696       while(start_time-etime() < EMCIO_BUFFER_GET_TIMEOUT)
01697         {
01698           emcIoCommandBuffer = new RCS_CMD_CHANNEL(emcFormat, "toolCmd", "emc", EMC_NMLFILE);
01699           if (! emcIoCommandBuffer->valid())
01700             {
01701               delete emcIoCommandBuffer;
01702               emcIoCommandBuffer = 0;
01703             }
01704           else
01705             {
01706               break;
01707             }
01708           esleep(0.1);
01709         }
01710       set_rcs_print_destination(orig_dest);
01711     }
01712 
01713   if (emcIoCommandBuffer == 0)
01714     {
01715       emcIoCommandBuffer = new RCS_CMD_CHANNEL(emcFormat, "toolCmd", "emc", EMC_NMLFILE);
01716       if (! emcIoCommandBuffer->valid())
01717         {
01718           delete emcIoCommandBuffer;
01719           emcIoCommandBuffer = 0;
01720           retval=-1;
01721         }
01722     }
01723   
01724   if (emcIoStatusBuffer == 0)
01725     {
01726       orig_dest = get_rcs_print_destination();
01727       set_rcs_print_destination(RCS_PRINT_TO_NULL);
01728       start_time = etime();
01729       while(start_time-etime() < EMCIO_BUFFER_GET_TIMEOUT)
01730         {
01731           emcIoStatusBuffer = new RCS_STAT_CHANNEL(emcFormat, "toolSts", "emc", EMC_NMLFILE);
01732           if (! emcIoStatusBuffer->valid())
01733             {
01734               delete emcIoStatusBuffer;
01735               emcIoStatusBuffer = 0;
01736             }
01737           else
01738             {
01739               emcIoStatus = (EMC_IO_STAT *) emcIoStatusBuffer->get_address();
01740               // capture serial number for next send
01741               emcIoCommandSerialNumber = emcIoStatus->echo_serial_number;
01742               break;
01743             }
01744           esleep(0.1);
01745         }
01746       set_rcs_print_destination(orig_dest);
01747     }
01748 
01749   if (emcIoStatusBuffer == 0)
01750     {
01751       emcIoStatusBuffer = new RCS_STAT_CHANNEL(emcFormat, "toolSts", "emc", EMC_NMLFILE);
01752       if (! emcIoStatusBuffer->valid() ||
01753           EMC_IO_STAT_TYPE != emcIoStatusBuffer->peek())
01754         {
01755           delete emcIoStatusBuffer;
01756           emcIoStatusBuffer = 0;
01757           emcIoStatus = 0;
01758           retval = -1;
01759         }
01760       else
01761         {
01762           emcIoStatus = (EMC_IO_STAT *) emcIoStatusBuffer->get_address();
01763           // capture serial number for next send
01764           emcIoCommandSerialNumber = emcIoStatus->echo_serial_number;
01765         }
01766     }
01767 
01768   return retval;
01769 }
01770 
01771 /*
01772   sendCommand() waits until any currently executing command has finished,
01773   then writes the given command.
01774 */
01775 static int sendCommand(RCS_CMD_MSG *msg)
01776 {
01777   // need command buffer to be there
01778   if (0 == emcIoCommandBuffer)
01779   {
01780     return -1;
01781   }
01782 
01783   // need status buffer also, to check for command received
01784   if (0 == emcIoStatusBuffer ||
01785       ! emcIoStatusBuffer->valid())
01786   {
01787     return -1;
01788   }
01789 
01790   double send_command_timeout = etime() + 30.0;
01791 
01792   // check if we're executing, and wait until we're done
01793   while(etime() < send_command_timeout) {
01794     emcIoStatusBuffer->peek();
01795     if (emcIoStatus->echo_serial_number != emcIoCommandSerialNumber ||
01796         emcIoStatus->status == RCS_EXEC) {
01797       esleep(0.001);
01798       continue;
01799     }
01800     else {
01801       break;
01802     }
01803   }
01804 
01805   if (emcIoStatus->echo_serial_number != emcIoCommandSerialNumber ||
01806       emcIoStatus->status == RCS_EXEC) {
01807     // Still not done, must have timed out.
01808     return -1;
01809   }
01810 
01811 
01812   // now we can send
01813   msg->serial_number = ++emcIoCommandSerialNumber;
01814   if (0 != emcIoCommandBuffer->write(msg))
01815   {
01816     return -1;
01817   }
01818 
01819   return 0;
01820 }
01821 
01822 /*
01823   forceCommand() writes the given command regardless of the executing
01824   status of any previous command.
01825 */
01826 static int forceCommand(RCS_CMD_MSG *msg)
01827 {
01828   // need command buffer to be there
01829   if (0 == emcIoCommandBuffer)
01830   {
01831     return -1;
01832   }
01833 
01834   // need status buffer also, to check for command received
01835   if (0 == emcIoStatusBuffer ||
01836       ! emcIoStatusBuffer->valid())
01837   {
01838     return -1;
01839   }
01840 
01841   // send it immediately
01842   msg->serial_number = ++emcIoCommandSerialNumber;
01843   if (0 != emcIoCommandBuffer->write(msg))
01844   {
01845     return -1;
01846   }
01847 
01848   return 0;
01849 }
01850 
01851 // NML commands
01852 
01853 int emcIoInit()
01854 {
01855   EMC_TOOL_INIT ioInitMsg;
01856   int retval;
01857 
01858   // get NML buffer to emcio
01859   if (0 != (retval = emcioNmlGet()))
01860   {
01861     return -1;
01862   }
01863 
01864   // send init command to emcio
01865   return forceCommand(&ioInitMsg);
01866 }
01867 
01868 int emcIoHalt()
01869 {
01870   EMC_TOOL_HALT ioHaltMsg;
01871 
01872   // send halt command to emcio
01873   if (emcIoCommandBuffer != 0)
01874   {
01875     forceCommand(&ioHaltMsg);
01876   }
01877 
01878   // clear out the buffers
01879 
01880   if (emcIoStatusBuffer != 0)
01881   {
01882     delete emcIoStatusBuffer;
01883     emcIoStatusBuffer = 0;
01884     emcIoStatus = 0;
01885   }
01886 
01887   if (emcIoCommandBuffer != 0)
01888   {
01889     delete emcIoCommandBuffer;
01890     emcIoCommandBuffer = 0;
01891   }
01892 
01893   return 0;
01894 }
01895 
01896 int emcIoAbort()
01897 {
01898   EMC_TOOL_ABORT ioAbortMsg;
01899 
01900   // send abort command to emcio
01901   forceCommand(&ioAbortMsg);
01902 
01903   return 0;
01904 }
01905 
01906 int emcIoSetDebug(int debug)
01907 {
01908   EMC_SET_DEBUG ioDebugMsg;
01909 
01910   ioDebugMsg.debug = debug;
01911 
01912   return sendCommand(&ioDebugMsg);
01913 }
01914 
01915 int emcAuxEstopOn()
01916 {
01917   EMC_AUX_ESTOP_ON estopOnMsg;
01918 
01919   return forceCommand(&estopOnMsg);
01920 }
01921 
01922 int emcAuxEstopOff()
01923 {
01924   EMC_AUX_ESTOP_OFF estopOffMsg;
01925 
01926   return sendCommand(&estopOffMsg);
01927 }
01928 
01929 int emcSpindleAbort()
01930 {
01931   return emcSpindleOff();
01932 }
01933 
01934 int emcSpindleOn(double speed)
01935 {
01936   EMC_SPINDLE_ON spindleOnMsg;
01937 
01938   spindleOnMsg.speed = speed;
01939   sendCommand(&spindleOnMsg);
01940 
01941   return 0;
01942 }
01943 
01944 int emcSpindleOff()
01945 {
01946   EMC_SPINDLE_OFF spindleOffMsg;
01947 
01948   sendCommand(&spindleOffMsg);
01949 
01950   return 0;
01951 }
01952 
01953 int emcSpindleBrakeRelease()
01954 {
01955   EMC_SPINDLE_BRAKE_RELEASE spindleBrakeReleaseMsg;
01956 
01957   sendCommand(&spindleBrakeReleaseMsg);
01958 
01959   return 0;
01960 }
01961 
01962 int emcSpindleBrakeEngage()
01963 {
01964   EMC_SPINDLE_BRAKE_ENGAGE spindleBrakeEngageMsg;
01965 
01966   sendCommand(&spindleBrakeEngageMsg);
01967 
01968   return 0;
01969 }
01970 
01971 int emcSpindleIncrease()
01972 {
01973   EMC_SPINDLE_INCREASE spindleIncreaseMsg;
01974 
01975   sendCommand(&spindleIncreaseMsg);
01976 
01977   return 0;
01978 }
01979 
01980 int emcSpindleDecrease()
01981 {
01982   EMC_SPINDLE_DECREASE spindleDecreaseMsg;
01983 
01984   sendCommand(&spindleDecreaseMsg);
01985 
01986   return 0;
01987 }
01988 
01989 int emcSpindleConstant()
01990 {
01991   EMC_SPINDLE_CONSTANT spindleConstantMsg;
01992 
01993   sendCommand(&spindleConstantMsg);
01994 
01995   return 0;
01996 }
01997 
01998 #ifdef LASER
01999 
02000 int emcCoolantMistOn()
02001 {
02002   return emcMotionSetDout(0, 1, 1);
02003 }
02004 
02005 int emcCoolantMistOff()
02006 {
02007   return emcMotionSetDout(0, 1, 0);
02008 }
02009 
02010 int emcCoolantFloodOn()
02011 {
02012   return 0;
02013 }
02014 
02015 int emcCoolantFloodOff()
02016 {
02017   return 0;
02018 }
02019 
02020 #else
02021 
02022 int emcCoolantMistOn()
02023 {
02024   EMC_COOLANT_MIST_ON mistOnMsg;
02025 
02026   sendCommand(&mistOnMsg);
02027 
02028   return 0;
02029 }
02030 
02031 int emcCoolantMistOff()
02032 {
02033   EMC_COOLANT_MIST_OFF mistOffMsg;
02034 
02035   sendCommand(&mistOffMsg);
02036 
02037   return 0;
02038 }
02039 
02040 int emcCoolantFloodOn()
02041 {
02042   EMC_COOLANT_FLOOD_ON floodOnMsg;
02043 
02044   sendCommand(&floodOnMsg);
02045 
02046   return 0;
02047 }
02048 
02049 int emcCoolantFloodOff()
02050 {
02051   EMC_COOLANT_FLOOD_OFF floodOffMsg;
02052 
02053   sendCommand(&floodOffMsg);
02054 
02055   return 0;
02056 }
02057 
02058 #endif // LASER
02059 
02060 int emcLubeInit()
02061 {
02062   EMC_LUBE_INIT lubeInitMsg;
02063 
02064   sendCommand(&lubeInitMsg);
02065 
02066   return 0;
02067 }
02068 
02069 int emcLubeHalt()
02070 {
02071   EMC_LUBE_HALT lubeHaltMsg;
02072 
02073   sendCommand(&lubeHaltMsg);
02074 
02075   return 0;
02076 }
02077 
02078 int emcLubeAbort()
02079 {
02080   EMC_LUBE_ABORT lubeAbortMsg;
02081 
02082   sendCommand(&lubeAbortMsg);
02083 
02084   return 0;
02085 }
02086 
02087 int emcLubeOn()
02088 {
02089   EMC_LUBE_ON lubeOnMsg;
02090 
02091   sendCommand(&lubeOnMsg);
02092 
02093   return 0;
02094 }
02095 
02096 int emcLubeOff()
02097 {
02098   EMC_LUBE_OFF lubeOffMsg;
02099 
02100   sendCommand(&lubeOffMsg);
02101 
02102   return 0;
02103 }
02104 
02105 int emcToolPrepare(int tool)
02106 {
02107   EMC_TOOL_PREPARE toolPrepareMsg;
02108 
02109   toolPrepareMsg.tool = tool;
02110   sendCommand(&toolPrepareMsg);
02111 
02112   return 0;
02113 }
02114 
02115 int emcToolLoad()
02116 {
02117   EMC_TOOL_LOAD toolLoadMsg;
02118 
02119   sendCommand(&toolLoadMsg);
02120 
02121   return 0;
02122 }
02123 
02124 int emcToolUnload()
02125 {
02126   EMC_TOOL_UNLOAD toolUnloadMsg;
02127 
02128   sendCommand(&toolUnloadMsg);
02129 
02130   return 0;
02131 }
02132 
02133 int emcToolLoadToolTable(const char *file)
02134 {
02135   EMC_TOOL_LOAD_TOOL_TABLE toolLoadToolTableMsg;
02136 
02137   strcpy(toolLoadToolTableMsg.file, file);
02138 
02139   sendCommand(&toolLoadToolTableMsg);
02140 
02141   return 0;
02142 }
02143 
02144 int emcToolSetOffset(int tool, double length, double diameter)
02145 {
02146   EMC_TOOL_SET_OFFSET toolSetOffsetMsg;
02147 
02148   toolSetOffsetMsg.tool = tool;
02149   toolSetOffsetMsg.length = length;
02150   toolSetOffsetMsg.diameter = diameter;
02151 
02152   sendCommand(&toolSetOffsetMsg);
02153 
02154   return 0;
02155 }
02156 
02157 int emcLogOpen(char *file, int type, int size, int skip, int which, int triggerType, int triggerVar, double triggerThreshold)
02158 {
02159   int r1;
02160 
02161   emcmotCommand.command = EMCMOT_OPEN_LOG;
02162   emcmotCommand.logSize = size;
02163   emcmotCommand.logSkip = skip;
02164   emcmotCommand.axis = which;
02165 
02166   // Note that EMC NML and emcmot will be different, in general--
02167   // need to map types
02168   switch (type)
02169   {
02170     case EMC_LOG_TYPE_AXIS_POS:
02171       emcmotCommand.logType = EMCMOT_LOG_TYPE_AXIS_POS;
02172       break;
02173 
02174     case EMC_LOG_TYPE_AXES_INPOS:
02175       emcmotCommand.logType = EMCMOT_LOG_TYPE_ALL_INPOS;
02176       break;
02177 
02178     case EMC_LOG_TYPE_AXES_OUTPOS:
02179       emcmotCommand.logType = EMCMOT_LOG_TYPE_ALL_OUTPOS;
02180       break;
02181 
02182     case EMC_LOG_TYPE_AXIS_VEL:
02183       emcmotCommand.logType = EMCMOT_LOG_TYPE_AXIS_VEL;
02184       break;
02185 
02186     case EMC_LOG_TYPE_AXES_FERROR:
02187       emcmotCommand.logType = EMCMOT_LOG_TYPE_ALL_FERROR;
02188       break;
02189 
02190     case EMC_LOG_TYPE_TRAJ_POS:
02191       emcmotCommand.logType = EMCMOT_LOG_TYPE_TRAJ_POS;
02192       break;
02193 
02194     case EMC_LOG_TYPE_TRAJ_VEL:
02195       emcmotCommand.logType = EMCMOT_LOG_TYPE_TRAJ_VEL;
02196       break;
02197 
02198     case EMC_LOG_TYPE_TRAJ_ACC:
02199       emcmotCommand.logType = EMCMOT_LOG_TYPE_TRAJ_ACC;
02200       break;
02201 
02202     case EMC_LOG_TYPE_POS_VOLTAGE:
02203       emcmotCommand.logType = EMCMOT_LOG_TYPE_POS_VOLTAGE;
02204       break;
02205 
02206     default:
02207       return -1;
02208   }
02209   emcmotCommand.logTriggerType = triggerType;
02210   emcmotCommand.logTriggerVariable = triggerVar;
02211   emcmotCommand.logTriggerThreshold = triggerThreshold;
02212 
02213   r1 = usrmotWriteEmcmotCommand(&emcmotCommand);
02214 
02215   if (r1 == 0)
02216   {
02217     strncpy(emcStatus->logFile, file, EMC_LOG_FILENAME_LEN - 1);
02218     emcStatus->logFile[EMC_LOG_FILENAME_LEN - 1] = 0;
02219   }
02220   // type, size, skip, open, and started will be gotten out of
02221   // subsystem status, e.g., emcTrajUpdate()
02222 
02223   return r1;
02224 }
02225 
02226 int emcLogStart()
02227 {
02228   emcmotCommand.command = EMCMOT_START_LOG;
02229   return(usrmotWriteEmcmotCommand(&emcmotCommand));
02230 }
02231 
02232 int emcLogStop()
02233 {
02234   emcmotCommand.command = EMCMOT_STOP_LOG;
02235   return(usrmotWriteEmcmotCommand(&emcmotCommand));
02236 }
02237 
02238 int emcLogClose()
02239 {
02240   int r1;
02241   int r2;
02242 
02243   // first check for active log, return nicely if not
02244   if (emcStatus->logFile[0] == 0 ||
02245       emcStatus->logSize == 0)
02246   {
02247     return 0;
02248   }
02249 
02250   emcmotCommand.command = EMCMOT_CLOSE_LOG;
02251 
02252   r1 = usrmotWriteEmcmotCommand(&emcmotCommand);
02253   r2 = usrmotDumpLog(emcStatus->logFile, EMCLOG_INCLUDE_HEADER);
02254 
02255   emcStatus->logFile[0] = 0;
02256   emcStatus->logType = 0;
02257   emcStatus->logSize = 0;
02258   emcStatus->logSkip = 0;
02259   emcStatus->logOpen = 0;
02260   emcStatus->logStarted = 0;
02261 
02262   return (r1 || r2 ? -1 : 0);
02263 }
02264 
02265 // Status functions
02266 
02267 int emcIoUpdate(EMC_IO_STAT *stat)
02268 {
02269   if (0 == emcIoStatusBuffer ||
02270       ! emcIoStatusBuffer->valid())
02271   {
02272     return -1;
02273   }
02274 
02275   switch (emcIoStatusBuffer->peek())
02276   {
02277     case -1:
02278       // error on CMS channel
02279       return -1;
02280       break;
02281 
02282     case 0:                     // nothing new
02283     case EMC_IO_STAT_TYPE:      // something new
02284       // drop out to copy
02285       break;
02286 
02287     default:
02288       // something else is in there
02289       return -1;
02290       break;
02291   }
02292 
02293   // copy status
02294   *stat = *emcIoStatus;
02295 
02296   /*
02297     We need to check that the RCS_DONE isn't left over from the previous
02298     command, by comparing the command number we sent with the command
02299     number that emcio echoes. If they're different, then the command hasn't
02300     been acknowledged yet and the state should be forced to be RCS_EXEC.
02301   */
02302   if (stat->echo_serial_number != emcIoCommandSerialNumber)
02303   {
02304     stat->status = RCS_EXEC;
02305   }
02306 
02307   return 0;
02308 }

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