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

minimilltool.cc

Go to the documentation of this file.
00001 /*
00002   minimilltool.cc
00003 
00004   Top-level controller for NIST minimill discrete I/O hierarchy
00005 
00006   Modification history:
00007 
00008   1-Jun-2001  FMP added handling of EMC_SET_DEBUG in decision process
00009   31-Aug-1999  FMP changed to minimilltool.cc
00010   22-Feb-1999  FMP added EMC_TOOL_SET_OFFSET, saveToolTable()
00011   19-Feb-1999  FMP took out setSubordinates()
00012   23-Apr-1998  FMP took out iniLoad(), called iniTool()
00013   2-Apr-1998  FMP took out spindle stuff altogether
00014   1-Apr-1998  FMP created from Shaver Bridgeport
00015   */
00016 
00017 #include "rcs.hh"               // NML
00018 #include "emc.hh"               // EMC NML
00019 #include "canon.hh"             // CANON_TOOL_TABLE
00020 #include "emcio.hh"             // these decls
00021 #include "emcglb.h"             // global TOOL_TABLE_FILE[]
00022 #include "initool.hh"           // iniTool()
00023 
00024 /* ident tag */
00025 #ifndef __GNUC__
00026 #ifndef __attribute__
00027 #define __attribute__(x)
00028 #endif
00029 #endif
00030 
00031 static char __attribute__((unused)) ident[] = "$Id: minimilltool.cc,v 1.4 2001/06/29 20:27:29 wshackle Exp $";
00032 
00033 // shortcuts to NML module subordinate statuses
00034 #define auxStatus ((EMC_AUX_STAT *) statusInData[auxSubNum])
00035 
00036 /*
00037   load the tool table from file filename into toolTable[] array.
00038   Array is CANON_TOOL_MAX + 1 entries, since 0 is included.
00039 
00040   If filename is "", use global established from ini file
00041   */
00042 static int loadToolTable(const char *filename, CANON_TOOL_TABLE toolTable[])
00043 {
00044   int t;
00045   FILE *fp;
00046   char buffer[CANON_TOOL_ENTRY_LEN];
00047   const char *name;
00048 
00049   // check filename
00050   if (filename[0] == 0)
00051     {
00052       name = TOOL_TABLE_FILE;
00053     }
00054   else
00055     {
00056       // point to name provided
00057       name = filename;
00058     }
00059 
00060   // open tool table file
00061   if (NULL == (fp = fopen(name, "r")))
00062     {
00063       // can't open file
00064       return -1;
00065     }
00066 
00067   // clear out tool table
00068   for (t = 0; t <= CANON_TOOL_MAX; t++)
00069     {
00070       // unused tools are 0, 0.0, 0.0
00071       toolTable[t].id = 0;
00072       toolTable[t].length = 0.0;
00073       toolTable[t].diameter = 0.0;
00074     }
00075 
00076   /*
00077      Override 0's with codes from tool file
00078 
00079      File format is:
00080 
00081      <header>
00082      <pocket # 0..CANON_TOOL_MAX> <FMS id> <length> <diameter>
00083      ...
00084 
00085      */
00086 
00087   // read and discard header
00088   if (NULL == fgets(buffer, 256, fp))
00089     {
00090       // nothing in file at all
00091       fclose(fp);
00092       return -1;
00093     }
00094 
00095   while (!feof(fp))
00096     {
00097       int pocket;
00098       int id;
00099       double length;
00100       double diameter;
00101 
00102       // just read pocket, ID, and length offset
00103       if (NULL == fgets(buffer, CANON_TOOL_ENTRY_LEN, fp))
00104         {
00105           break;
00106         }
00107 
00108       if (4 != sscanf(buffer, "%d %d %lf %lf",
00109                       &pocket, &id, &length, &diameter))
00110         {
00111           // bad entry-- skip
00112           continue;
00113         }
00114       else
00115         {
00116           if (pocket < 0 || pocket > CANON_TOOL_MAX)
00117             {
00118               continue;
00119             }
00120           else
00121             {
00122               toolTable[pocket].id = id;
00123               toolTable[pocket].length = length;
00124               toolTable[pocket].diameter = diameter;
00125             }
00126         }
00127     }
00128 
00129   // close the file
00130   fclose(fp);
00131 
00132   return 0;
00133 }
00134 
00135 /*
00136   save the tool table to file filename from toolTable[] array.
00137   Array is CANON_TOOL_MAX + 1 entries, since 0 is included.
00138 
00139   If filename is "", use global established from ini file
00140   */
00141 static int saveToolTable(const char *filename, CANON_TOOL_TABLE toolTable[])
00142 {
00143   int pocket;
00144   FILE *fp;
00145   const char *name;
00146 
00147   // check filename
00148   if (filename[0] == 0)
00149     {
00150       name = TOOL_TABLE_FILE;
00151     }
00152   else
00153     {
00154       // point to name provided
00155       name = filename;
00156     }
00157 
00158   // open tool table file
00159   if (NULL == (fp = fopen(name, "w")))
00160     {
00161       // can't open file
00162       return -1;
00163     }
00164 
00165   // write header
00166   fprintf(fp, "POC\tFMS\tLEN\t\tDIAM\n");
00167 
00168   for (pocket = 1; pocket <= CANON_TOOL_MAX; pocket++)
00169     {
00170       fprintf(fp, "%d\t%d\t%f\t%f\n",
00171               pocket,
00172               toolTable[pocket].id,
00173               toolTable[pocket].length,
00174               toolTable[pocket].diameter);
00175     }
00176 
00177   // close the file
00178   fclose(fp);
00179 
00180   return 0;
00181 }
00182 
00183 // constructor
00184 
00185 EMC_TOOL_MODULE::EMC_TOOL_MODULE()
00186 {
00187   EMC_TOOL_INIT initMsg;
00188 
00189   setErrorLogChannel(new NML(nmlErrorFormat, "emcError", "tool", EMC_NMLFILE));
00190 
00191   setCmdChannel(new RCS_CMD_CHANNEL(emcFormat, "toolCmd", "tool", EMC_NMLFILE));
00192 
00193   setStatChannel(new RCS_STAT_CHANNEL(emcFormat, "toolSts", "tool", EMC_NMLFILE), &ioStatus);
00194 
00195   auxSubNum = addSubordinate(new RCS_CMD_CHANNEL(emcFormat, "auxCmd", "tool", EMC_NMLFILE), new RCS_STAT_CHANNEL(emcFormat, "auxSts", "tool", EMC_NMLFILE));
00196 
00197   // local data
00198   deltaClock = 0.0;
00199 
00200   // stuff an INIT to get things going
00201   initMsg.serial_number = 1;    // comes up as 0
00202   commandIn->write(initMsg);
00203 }
00204 
00205 // destructor
00206 
00207 EMC_TOOL_MODULE::~EMC_TOOL_MODULE(void)
00208 {
00209 }
00210 
00211 void EMC_TOOL_MODULE::DECISION_PROCESS(void)
00212 {
00213   switch (commandInData->type)
00214     {
00215     case EMC_SET_DEBUG_TYPE:
00216       /* this will be done "immediately", without a state table, since
00217          it's trivial. We have to make sure to manipulate the state
00218          table vars as we would any command */
00219       EMC_DEBUG = ((EMC_SET_DEBUG *) commandInData)->debug;
00220       ioStatus.debug = EMC_DEBUG;
00221       status = RCS_DONE;
00222       stateNext(S0);
00223       break;
00224 
00225     case EMC_TOOL_INIT_TYPE:
00226       INIT((EMC_TOOL_INIT *) commandInData);
00227       break;
00228 
00229     case EMC_TOOL_HALT_TYPE:
00230       HALT((EMC_TOOL_HALT *) commandInData);
00231       break;
00232 
00233     case EMC_TOOL_ABORT_TYPE:
00234       ABORT((EMC_TOOL_ABORT *) commandInData);
00235       break;
00236 
00237     case EMC_TOOL_PREPARE_TYPE:
00238       TOOL_PREPARE((EMC_TOOL_PREPARE *) commandInData);
00239       break;
00240 
00241     case EMC_TOOL_LOAD_TYPE:
00242       TOOL_LOAD((EMC_TOOL_LOAD *) commandInData);
00243       break;
00244 
00245     case EMC_TOOL_UNLOAD_TYPE:
00246       TOOL_UNLOAD((EMC_TOOL_UNLOAD *) commandInData);
00247       break;
00248 
00249     case EMC_TOOL_LOAD_TOOL_TABLE_TYPE:
00250       TOOL_LOAD_TOOL_TABLE((EMC_TOOL_LOAD_TOOL_TABLE *) commandInData);
00251       break;
00252 
00253     case EMC_TOOL_SET_OFFSET_TYPE:
00254       TOOL_SET_OFFSET((EMC_TOOL_SET_OFFSET *) commandInData);
00255       break;
00256 
00257     case EMC_AUX_ESTOP_ON_TYPE:
00258       AUX_ESTOP_ON((EMC_AUX_ESTOP_ON *) commandInData);
00259       break;
00260 
00261     case EMC_AUX_ESTOP_OFF_TYPE:
00262       AUX_ESTOP_OFF((EMC_AUX_ESTOP_OFF *) commandInData);
00263       break;
00264 
00265     case EMC_AUX_DIO_WRITE_TYPE:
00266       AUX_DIO_WRITE((EMC_AUX_DIO_WRITE *) commandInData);
00267       break;
00268 
00269     case EMC_AUX_AIO_WRITE_TYPE:
00270       AUX_AIO_WRITE((EMC_AUX_AIO_WRITE *) commandInData);
00271       break;
00272 
00273     default:
00274       REPORT_ERROR(commandInData);
00275       break;
00276     }
00277 }
00278 
00279 void EMC_TOOL_MODULE::PRE_PROCESS(void)
00280 {
00281 }
00282 
00283 void EMC_TOOL_MODULE::POST_PROCESS(void)
00284 {
00285   // copy in the subordinate status
00286   ioStatus.aux = *auxStatus;
00287 
00288   // update the heartbeat
00289   ioStatus.heartbeat++;
00290 }
00291 
00292 void EMC_TOOL_MODULE::INIT(EMC_TOOL_INIT *cmdIn)
00293 {
00294   EMC_AUX_INIT auxInitMsg;
00295 
00296   if (STATE_MATCH(NEW_COMMAND))
00297     {
00298       // load params from ini file
00299       iniTool(EMC_INIFILE);
00300       loadToolTable(TOOL_TABLE_FILE, ioStatus.tool.toolTable);
00301 
00302       // send commands to subordinates
00303       sendCommand(&auxInitMsg, auxSubNum);
00304 
00305       status = RCS_EXEC;
00306       stateNext(S1);
00307 
00308     }
00309   else if (STATE_MATCH(S0))
00310     {
00311       // idle
00312     }
00313   else if (STATE_MATCH(S1,
00314                        auxStatus->status == RCS_DONE))
00315     {
00316       // all are done
00317       status = RCS_DONE;
00318       stateNext(S0);
00319     }
00320   else if (STATE_MATCH(S1,
00321                        auxStatus->status == RCS_ERROR))
00322     {
00323       // a subordinate reported an error
00324       status = RCS_ERROR;
00325       stateNext(S0);
00326     }
00327   else if (STATE_MATCH(S1))
00328     {
00329       // one or more are still executing-- keep waiting
00330     }
00331 }
00332 
00333 void EMC_TOOL_MODULE::HALT(EMC_TOOL_HALT *cmdIn)
00334 {
00335   EMC_AUX_HALT auxHaltMsg;
00336 
00337   if (STATE_MATCH(NEW_COMMAND))
00338     {
00339       sendCommand(&auxHaltMsg, auxSubNum);
00340 
00341       status = RCS_EXEC;
00342       stateNext(S1);
00343     }
00344   else if (STATE_MATCH(S0))
00345     {
00346       // idle
00347     }
00348   else if (STATE_MATCH(S1,
00349                        auxStatus->status == RCS_DONE))
00350 
00351     {
00352       // both are done
00353 
00354       status = RCS_DONE;
00355       stateNext(S0);
00356     }
00357   else if (STATE_MATCH(S1,
00358                        auxStatus->status == RCS_ERROR))
00359     {
00360       // a subordinate reported an error
00361 
00362       status = RCS_ERROR;
00363       stateNext(S0);
00364     }
00365   else if (STATE_MATCH(S1))
00366     {
00367       // one or more are still executing-- keep waiting
00368     }
00369 }
00370 
00371 void EMC_TOOL_MODULE::ABORT(EMC_TOOL_ABORT *cmdIn)
00372 {
00373   EMC_AUX_ABORT auxAbortMsg;
00374 
00375   if (STATE_MATCH(NEW_COMMAND))
00376     {
00377       sendCommand(&auxAbortMsg, auxSubNum);
00378 
00379       status = RCS_EXEC;
00380       stateNext(S1);
00381     }
00382   else if (STATE_MATCH(S0))
00383     {
00384       // idle
00385     }
00386   else if (STATE_MATCH(S1,
00387                        auxStatus->status == RCS_DONE))
00388     {
00389       // both are done
00390 
00391       status = RCS_DONE;
00392       stateNext(S0);
00393     }
00394   else if (STATE_MATCH(S1,
00395                        auxStatus->status == RCS_ERROR))
00396     {
00397       // a subordinate reported an error
00398 
00399       status = RCS_ERROR;
00400       stateNext(S0);
00401     }
00402   else if (STATE_MATCH(S1))
00403     {
00404       // one or more are still executing-- keep waiting
00405     }
00406 }
00407 
00408 void EMC_TOOL_MODULE::REPORT_ERROR(RCS_CMD_MSG *cmdIn)
00409 {
00410   if (STATE_MATCH(NEW_COMMAND))
00411     {
00412       rcs_print_error("EMC_TOOL_MODULE: unknown command %d\n",
00413                       cmdIn->type);
00414       status = RCS_ERROR;
00415       stateNext(S0);
00416     }
00417   else if (STATE_MATCH(S0))
00418     {
00419       // idle
00420     }
00421 }
00422 
00423 void EMC_TOOL_MODULE::TOOL_PREPARE(EMC_TOOL_PREPARE *cmdIn)
00424 {
00425   if (STATE_MATCH(NEW_COMMAND))
00426     {
00427       ioStatus.tool.toolPrepped = cmdIn->tool;
00428 
00429       status = RCS_DONE;
00430       stateNext(S0);
00431     }
00432   else if (STATE_MATCH(S0))
00433     {
00434       // idle
00435     }
00436 }
00437 
00438 void EMC_TOOL_MODULE::TOOL_LOAD(EMC_TOOL_LOAD *cmdIn)
00439 {
00440   if (STATE_MATCH(NEW_COMMAND))
00441     {
00442       ioStatus.tool.toolInSpindle = ioStatus.tool.toolPrepped;
00443       ioStatus.tool.toolPrepped = 0;
00444 
00445       status = RCS_DONE;
00446       stateNext(S0);
00447     }
00448   else if (STATE_MATCH(S0))
00449     {
00450       // idle
00451     }
00452 }
00453 
00454 void EMC_TOOL_MODULE::TOOL_UNLOAD(EMC_TOOL_UNLOAD *cmdIn)
00455 {
00456   if (STATE_MATCH(NEW_COMMAND))
00457     {
00458       ioStatus.tool.toolInSpindle = 0;
00459 
00460       status = RCS_DONE;
00461       stateNext(S0);
00462     }
00463   else if (STATE_MATCH(S0))
00464     {
00465       // idle
00466     }
00467 }
00468 
00469 void EMC_TOOL_MODULE::TOOL_LOAD_TOOL_TABLE(EMC_TOOL_LOAD_TOOL_TABLE *cmdIn)
00470 {
00471   if (STATE_MATCH(NEW_COMMAND))
00472     {
00473       if (0 != loadToolTable(cmdIn->file, ioStatus.tool.toolTable))
00474         {
00475           status = RCS_ERROR;
00476         }
00477       else
00478         {
00479           status = RCS_DONE;
00480         }
00481       stateNext(S0);
00482     }
00483   else if (STATE_MATCH(S0))
00484     {
00485       // idle
00486     }
00487 }
00488 
00489 void EMC_TOOL_MODULE::TOOL_SET_OFFSET(EMC_TOOL_SET_OFFSET *cmdIn)
00490 {
00491   if (STATE_MATCH(NEW_COMMAND))
00492     {
00493       if (cmdIn->tool < 0 || cmdIn->tool > CANON_TOOL_MAX)
00494         {
00495           status = RCS_ERROR;
00496           stateNext(S0);
00497         }
00498       else
00499         {
00500           // good tool number, so record it and save it
00501           ioStatus.tool.toolTable[cmdIn->tool].length = cmdIn->length;
00502           ioStatus.tool.toolTable[cmdIn->tool].diameter = cmdIn->diameter;
00503 
00504           if (0 != saveToolTable(TOOL_TABLE_FILE, ioStatus.tool.toolTable))
00505             {
00506               status = RCS_ERROR;
00507             }
00508           else
00509             {
00510               status = RCS_DONE;
00511             }
00512           stateNext(S0);
00513         }
00514     }
00515   else if (STATE_MATCH(S0))
00516     {
00517       // idle
00518     }
00519 }
00520 
00521 // auxiliary functions
00522 void EMC_TOOL_MODULE::AUX_ESTOP_ON(EMC_AUX_ESTOP_ON *cmdIn)
00523 {
00524   EMC_AUX_ESTOP_ON estopOnMsg;
00525 
00526   if (STATE_MATCH(NEW_COMMAND))
00527     {
00528       sendCommand(&estopOnMsg, auxSubNum);
00529 
00530       status = RCS_EXEC;
00531       stateNext(S1);
00532     }
00533   else if (STATE_MATCH(S0))
00534     {
00535       // idle
00536     }
00537   else if (STATE_MATCH(S1,
00538                        auxStatus->status == RCS_DONE))
00539     {
00540       status = RCS_DONE;
00541       stateNext(S0);
00542     }
00543   else if (STATE_MATCH(S1,
00544                        auxStatus->status == RCS_ERROR))
00545     {
00546       status = RCS_ERROR;
00547       stateNext(S0);
00548     }
00549   else if (STATE_MATCH(S1,
00550                        auxStatus->status == RCS_EXEC))
00551     {
00552       // still working
00553     }
00554 }
00555 
00556 void EMC_TOOL_MODULE::AUX_ESTOP_OFF(EMC_AUX_ESTOP_OFF *cmdIn)
00557 {
00558   EMC_AUX_ESTOP_OFF estopOffMsg;
00559 
00560   if (STATE_MATCH(NEW_COMMAND))
00561     {
00562       sendCommand(&estopOffMsg, auxSubNum);
00563 
00564       status = RCS_EXEC;
00565       stateNext(S1);
00566     }
00567   else if (STATE_MATCH(S0))
00568     {
00569       // idle
00570     }
00571   else if (STATE_MATCH(S1,
00572                        auxStatus->status == RCS_DONE))
00573     {
00574       status = RCS_DONE;
00575       stateNext(S0);
00576     }
00577   else if (STATE_MATCH(S1,
00578                        auxStatus->status == RCS_ERROR))
00579     {
00580       status = RCS_ERROR;
00581       stateNext(S0);
00582     }
00583   else if (STATE_MATCH(S1,
00584                        auxStatus->status == RCS_EXEC))
00585     {
00586       // still working
00587     }
00588 }
00589 
00590 void EMC_TOOL_MODULE::AUX_DIO_WRITE(EMC_AUX_DIO_WRITE *cmdIn)
00591 {
00592   EMC_AUX_DIO_WRITE dioWriteMsg = *cmdIn;
00593 
00594   if (STATE_MATCH(NEW_COMMAND))
00595     {
00596       sendCommand(&dioWriteMsg, auxSubNum);
00597 
00598       status = RCS_EXEC;
00599       stateNext(S1);
00600     }
00601   else if (STATE_MATCH(S0))
00602     {
00603       // idle
00604     }
00605   else if (STATE_MATCH(S1,
00606                        auxStatus->status == RCS_DONE))
00607     {
00608       status = RCS_DONE;
00609       stateNext(S0);
00610     }
00611   else if (STATE_MATCH(S1,
00612                        auxStatus->status == RCS_ERROR))
00613     {
00614       status = RCS_ERROR;
00615       stateNext(S0);
00616     }
00617   else if (STATE_MATCH(S1,
00618                        auxStatus->status == RCS_EXEC))
00619     {
00620       // still working
00621     }
00622 }
00623 
00624 void EMC_TOOL_MODULE::AUX_AIO_WRITE(EMC_AUX_AIO_WRITE *cmdIn)
00625 {
00626   EMC_AUX_AIO_WRITE aioWriteMsg = *cmdIn;
00627 
00628   if (STATE_MATCH(NEW_COMMAND))
00629     {
00630       sendCommand(&aioWriteMsg, auxSubNum);
00631 
00632       status = RCS_EXEC;
00633       stateNext(S1);
00634     }
00635   else if (STATE_MATCH(S0))
00636     {
00637       // idle
00638     }
00639   else if (STATE_MATCH(S1,
00640                        auxStatus->status == RCS_DONE))
00641     {
00642       status = RCS_DONE;
00643       stateNext(S0);
00644     }
00645   else if (STATE_MATCH(S1,
00646                        auxStatus->status == RCS_ERROR))
00647     {
00648       status = RCS_ERROR;
00649       stateNext(S0);
00650     }
00651   else if (STATE_MATCH(S1,
00652                        auxStatus->status == RCS_EXEC))
00653     {
00654       // still working
00655     }
00656 }

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