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

iniaxis.cc

Go to the documentation of this file.
00001 /*
00002   iniaxis.cc
00003 
00004   INI file initialization routines for axis NML
00005 
00006   Modification history:
00007 
00008   10-Aug-2000  FMP added emcAxisLoadComp() call from COMP_FILE
00009   20-Apr-2000 WPS changed rcs_print(ourAxisSection, "AXIS_%d", axis) to
00010   sprintf(...);
00011   24-Feb-2000  FMP added deadband
00012   23-Feb-2000  FMP added [AXIS_#] MAX_VELOCITY
00013   5-Oct-1999  FMP added min ferror
00014   1-Oct-1999  FMP added printing of [AXIS_#] section in error messages
00015   29-Sep-1999  FMP added HOME_OFFSET
00016   21-Sep-1999  WPS eliminate sscanf and printf calls not supported under CE.
00017   30-Aug-1999  FMP moved emcAxisActivate() to the end of the configuration
00018   9-Aug-1999  FMP added emcAxisSetHome()
00019   3-Aug-1999  FMP added emcAxisActivate()
00020   15-Jun-1999  FMP added bracketing of debug printing with EMC_DEBUG
00021   12-Feb-1999  FMP added FERROR for dumpAxis()
00022   10-Feb-1999  FMP added OUTPUT_SCALE, and iniFormatFloat2(), for dumpAxis()
00023   31-Jan-1999 FMP added dumpAxis();
00024   6-Aug-1998  FMP changed setting of retval = -1 to return -1 in loadAxis,
00025   since it just kept the controller alive longer than it had to since we're
00026   going to quit on an error anyway
00027   8-Jan-1998  FMP honored return values from functions
00028   10-Dec-1997  FMP added rest of INI file params
00029   25-Nov-1997  FMP created
00030   */
00031 
00032 extern "C" {
00033 #ifndef UNDER_CE
00034 #include <stdio.h>              // NULL
00035 #endif
00036 #include <stdlib.h>             // atol(), _itoa()
00037 #include <string.h>             // strcmp()
00038 #include <ctype.h>              // isdigit()
00039 }
00040 
00041 #include "emc.hh"
00042 #include "inifile.h"
00043 #include "iniaxis.hh"           // these decls
00044 #include "emcglb.h"             // EMC_DEBUG
00045 #include "emccfg.h"             // default values for globals
00046 
00047 #ifdef UNDER_CE
00048 #include "rcs_ce.h"
00049 #endif
00050 
00051 // inifile ref'ed by iniAxes(), loadAxis()
00052 static INIFILE *axisInifile = 0;
00053 
00054 /*
00055   loadAxis(int axis)
00056 
00057   Loads ini file params for axis, axis = 0, ...
00058 
00059   TYPE <LINEAR ANGULAR>        type of axis
00060   UNITS <float>                units per mm or deg
00061   HOME <float>                 home position
00062   MAX_VELOCITY <float>         max vel for axis
00063   P <float>                    proportional gain
00064   I <float>                    integral gain
00065   D <float>                    derivative gain
00066   FF0 <float>                  0th order feedforward (position)
00067   FF1 <float>                  1st order feedforward (velocity)
00068   FF2 <float>                  2nd order feedforward (acceleration)
00069   MAX_ERROR <float>            max cumulative error
00070   BACKLASH <float>             backlash
00071   BIAS <float>                 constant bias
00072   DEADBAND <float>             error deadband
00073   CYCLE_TIME <float>           cycle time
00074   INPUT_SCALE <float> <float>  scale, offset
00075   OUTPUT_SCALE <float> <float> scale, offset
00076   MIN_LIMIT <float>            minimum soft position limit
00077   MAX_LIMIT <float>            maximum soft position limit
00078   MIN_OUTPUT <float>           minimum output value (voltage, typically)
00079   MAX_OUTPUT <float>           maximum output value (voltage, typically)
00080   FERROR <float>               maximum following error, scaled to max vel
00081   MIN_FERROR <float>           minimum following error
00082   HOMING_VEL <float>           homing speed, positive
00083   ENABLE_POLARITY <0, 1>       polarity for amp enable output
00084   MIN_LIMIT_SWITCH_POLARITY <0, 1> polarity for min limit switch input
00085   MAX_LIMIT_SWITCH_POLARITY <0, 1> polarity for max limit switch input
00086   HOME_SWITCH_POLARITY <0, 1>  polarity for home switch input
00087   HOMING_POLARITY <0, 1>       direction for homing search
00088   HOME_OFFSET <float>          where to move axis after home
00089   FAULT_POLARITY <0, 1>        polarity for amp fault input
00090   COMP_FILE <filename>         file of axis compensation points
00091 
00092   calls:
00093 
00094   emcAxisSetAxis(int axis, unsigned char axisType);
00095   emcAxisSetUnits(int axis, double units);
00096   emcAxisSetGains(int axis, double p, double i, double d, double ff0, double ff1, double ff2, double backlash, double bias, double maxError, double deadband);
00097   emcAxisSetCycleTime(int axis, double cycleTime);
00098   emcAxisSetInterpolationRate(int axis, int rate);
00099   emcAxisSetInputScale(int axis, double scale, double offset);
00100   emcAxisSetOutputScale(int axis, double scale, double offset);
00101   emcAxisSetMinPositionLimit(int axis, double limit);
00102   emcAxisSetMaxPositionLimit(int axis, double limit);
00103   emcAxisSetMinOutputLimit(int axis, double limit);
00104   emcAxisSetMaxOutputLimit(int axis, double limit);
00105   emcAxisSetFerror(int axis, double ferror);
00106   emcAxisSetMinFerror(int axis, double ferror);
00107   emcAxisSetHomingVel(int axis, double homingVel);
00108   emcAxisSetEnablePolarity(int axis, int level);
00109   emcAxisSetMinLimitSwitchPolarity(int axis, int level);
00110   emcAxisSetMaxLimitSwitchPolarity(int axis, int level);
00111   emcAxisSetHomeSwitchPolarity(int axis, int level);
00112   emcAxisSetHomingPolarity(int axis, int level);
00113   emcAxisSetFaultPolarity(int axis, int level);
00114   emcAxisActivate(int axis);
00115   emcAxisDeactivate(int axis);
00116   emcAxisSetMaxVelocity(int axis, double vel);
00117   emcAxisLoadComp(int axis, const char * file);
00118   */
00119 
00120 static int loadAxis(int axis)
00121 {
00122 #define AXIS_STRING_LEN 16
00123   char axisString[AXIS_STRING_LEN];
00124   const char *inistring;
00125   unsigned char axisType;
00126   double units;
00127   double p, i, d, ff0, ff1, ff2;
00128   double backlash;
00129   double bias;
00130   double maxError;
00131   double deadband;
00132   double cycleTime;
00133   double scale, offset;
00134   double limit;
00135   double homingVel;
00136   double home;
00137   double maxVelocity;
00138   int polarity;
00139   double maxFerror;
00140 
00141   // compose string to match, axis = 0 -> AXIS_1, etc.
00142 #ifndef UNDER_CE
00143   sprintf(axisString, "AXIS_%d", axis);
00144 #else
00145   strcpy(axisString,"AXIS_");
00146   _itoa(axis,axisString+5, 10);
00147 #endif
00148 
00149   // set axis type
00150 
00151   if (NULL != (inistring = axisInifile->find("TYPE", axisString))) {
00152     if (! strcmp(inistring, "LINEAR")) {
00153       // found, and valid
00154       axisType = EMC_AXIS_LINEAR;
00155     }
00156     else if (! strcmp(inistring, "ANGULAR")) {
00157       // found, and valid
00158       axisType = EMC_AXIS_ANGULAR;
00159     }
00160     else {
00161       // found, but invalid
00162       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00163         rcs_print_error("invalid inifile value for [%s] TYPE: %s\n", axisString, inistring);
00164       }
00165       axisType = EMC_AXIS_LINEAR;       // default is linear
00166     }
00167   }
00168   else {
00169     // not found at all
00170     axisType = EMC_AXIS_LINEAR; // default is linear
00171     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00172       rcs_print_error("can't find [%s] TYPE, using default\n", axisString);
00173     }
00174   }
00175   if (0 != emcAxisSetAxis(axis, axisType)) {
00176     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00177       rcs_print_error("bad return from emcAxisSetAxis\n");
00178     }
00179     return -1;
00180   }
00181 
00182   // set units
00183 
00184   if (NULL != (inistring = axisInifile->find("UNITS", axisString))) {
00185 #ifndef UNDER_CE
00186     if (1 == sscanf(inistring, "%lf", &units)) {
00187       // found, and valid
00188     }
00189     else {
00190       // found, but invalid
00191       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00192         rcs_print_error("invalid inifile value for [%s] UNITS: %s\n", axisString, inistring);
00193       }
00194       units = 1.0;                      // default
00195     }
00196 #else
00197     units = RCS_CE_ATOF(inistring);
00198 #endif
00199   }
00200   else {
00201     // not found at all
00202     units = 1.0;                        // default
00203     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00204       rcs_print_error("can't find [%s] UNITS, using default\n", axisString);
00205     }
00206   }
00207   if (0 != emcAxisSetUnits(axis, units)) {
00208     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00209       rcs_print_error("bad return from emcAxisSetUnits\n");
00210     }
00211     return -1;
00212   }
00213 
00214   // set forward gains
00215 
00216   if (NULL != (inistring = axisInifile->find("P", axisString))) {
00217 #ifndef UNDER_CE
00218     if (1 == sscanf(inistring, "%lf", &p)) {
00219       // found, and valid
00220     }
00221     else {
00222       // found, but invalid
00223       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00224         rcs_print_error("invalid inifile value for [%s] P: %s\n", axisString, inistring);
00225       }
00226       p = 0;                    // default
00227     }
00228 #else
00229     p = RCS_CE_ATOF(inistring);
00230 #endif
00231   }
00232   else {
00233     // not found at all
00234     p = 0;                      // default
00235     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00236       rcs_print_error("can't find [%s] P, using default\n", axisString);
00237     }
00238   }
00239 
00240   if (NULL != (inistring = axisInifile->find("I", axisString))) {
00241 #ifndef UNDER_CE
00242     if (1 == sscanf(inistring, "%lf", &i)) {
00243       // found, and valid
00244     }
00245     else {
00246       // found, but invalid
00247       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00248         rcs_print_error("invalid inifile value for [%s] I: %s\n", axisString, inistring);
00249       }
00250       i = 0;                    // default
00251     }
00252 #else
00253     i = RCS_CE_ATOF(inistring);
00254 #endif
00255   }
00256   else {
00257     // not found at all
00258     i = 0;                      // default
00259     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00260       rcs_print_error("can't find [%s] I, using default\n", axisString);
00261     }
00262   }
00263 
00264   if (NULL != (inistring = axisInifile->find("D", axisString))) {
00265 #ifndef UNDER_CE
00266     if (1 == sscanf(inistring, "%lf", &d)) {
00267       // found, and valid
00268     }
00269     else {
00270       // found, but invalid
00271       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00272         rcs_print_error("invalid inifile value for [%s] D: %s\n", axisString, inistring);
00273       }
00274       d = 0;                    // default
00275     }
00276 #else
00277     d = RCS_CE_ATOF(inistring);
00278 #endif
00279   }
00280   else {
00281     // not found at all
00282     d = 0;                      // default
00283     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00284       rcs_print_error("can't find [%s] D, using default\n", axisString);
00285     }
00286   }
00287 
00288   if (NULL != (inistring = axisInifile->find("FF0", axisString))) {
00289 #ifndef UNDER_CE
00290     if (1 == sscanf(inistring, "%lf", &ff0)) {
00291       // found, and valid
00292     }
00293     else {
00294       // found, but invalid
00295       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00296         rcs_print_error("invalid inifile value for [%s] FF0: %s\n", axisString, inistring);
00297       }
00298       ff0 = 0;                  // default
00299     }
00300 #else
00301     ff0 = RCS_CE_ATOF(inistring);
00302 #endif
00303   }
00304   else {
00305     // not found at all
00306     ff0 = 0;                    // default
00307     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00308       rcs_print_error("can't find [%s] FF0, using default\n", axisString);
00309     }
00310   }
00311 
00312   if (NULL != (inistring = axisInifile->find("FF1", axisString))) {
00313 #ifndef UNDER_CE
00314     if (1 == sscanf(inistring, "%lf", &ff1)) {
00315       // found, and valid
00316     }
00317     else {
00318       // found, but invalid
00319       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00320         rcs_print_error("invalid inifile value for [%s] FF1: %s\n", axisString, inistring);
00321       }
00322       ff1 = 0;                  // default
00323     }
00324 #else
00325     ff1 = RCS_CE_ATOF(inistring);
00326 #endif
00327   }
00328   else {
00329     // not found at all
00330     ff1 = 0;                    // default
00331     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00332       rcs_print_error("can't find [%s] FF1, using default\n", axisString);
00333     }
00334   }
00335 
00336   if (NULL != (inistring = axisInifile->find("FF2", axisString))) {
00337 #ifndef UNDER_CE
00338     if (1 == sscanf(inistring, "%lf", &ff2)) {
00339       // found, and valid
00340     }
00341     else {
00342       // found, but invalid
00343       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00344         rcs_print_error("invalid inifile value for [%s] FF2: %s\n", axisString, inistring);
00345       }
00346       ff2 = 0;                  // default
00347     }
00348 #else
00349     ff2 = RCS_CE_ATOF(inistring);
00350 #endif
00351   }
00352   else {
00353     // not found at all
00354     ff2 = 0;                    // default
00355     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00356       rcs_print_error("can't find [%s] FF2, using default\n", axisString);
00357     }
00358   }
00359 
00360   if (NULL != (inistring = axisInifile->find("BACKLASH", axisString))) {
00361 #ifndef UNDER_CE
00362     if (1 == sscanf(inistring, "%lf", &backlash)) {
00363       // found, and valid
00364     }
00365     else {
00366       // found, but invalid
00367       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00368         rcs_print_error("invalid inifile value for [%s] BACKLASH: %s\n", axisString, inistring);
00369       }
00370       backlash = 0;                     // default
00371     }
00372 #else
00373     backlash = RCS_CE_ATOF(inistring);
00374 #endif
00375   }
00376   else {
00377     // not found at all
00378     backlash = 0;                       // default
00379     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00380       rcs_print_error("can't find [%s] BACKLASH, using default\n", axisString);
00381     }
00382   }
00383 
00384   if (NULL != (inistring = axisInifile->find("BIAS", axisString))) {
00385 #ifndef UNDER_CE
00386     if (1 == sscanf(inistring, "%lf", &bias)) {
00387       // found, and valid
00388     }
00389     else {
00390       // found, but invalid
00391       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00392         rcs_print_error("invalid inifile value for [%s] BIAS: %s\n", axisString, inistring);
00393       }
00394       bias = 0;                 // default
00395     }
00396 #else
00397     bias = RCS_CE_ATOF(inistring);
00398 #endif
00399   }
00400   else {
00401     // not found at all
00402     bias = 0;                   // default
00403     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00404       rcs_print_error("can't find [%s] BIAS, using default\n", axisString);
00405     }
00406   }
00407 
00408   // max cumulative error
00409 
00410   if (NULL != (inistring = axisInifile->find("MAX_ERROR", axisString))) {
00411 #ifndef UNDER_CE
00412     if (1 == sscanf(inistring, "%lf", &maxError)) {
00413       // found, and valid
00414     }
00415     else {
00416       // found, but invalid
00417       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00418         rcs_print_error("invalid inifile value for [%s] MAX_ERROR: %s\n", axisString, inistring);
00419       }
00420       maxError = 0;                     // default
00421     }
00422 #else
00423     maxError = RCS_CE_ATOF(inistring);
00424 #endif
00425   }
00426   else {
00427     // not found at all
00428     maxError = 0;                       // default
00429     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00430       rcs_print_error("can't find [%s] MAX_ERROR, using default\n", axisString);
00431     }
00432   }
00433 
00434   // deadband
00435 
00436   if (NULL != (inistring = axisInifile->find("DEADBAND", axisString))) {
00437 #ifndef UNDER_CE
00438     if (1 == sscanf(inistring, "%lf", &deadband)) {
00439       // found, and valid
00440     }
00441     else {
00442       // found, but invalid
00443       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00444         rcs_print_error("invalid inifile value for [%s] DEADBAND: %s\n", axisString, inistring);
00445       }
00446       deadband = 0;                     // default
00447     }
00448 #else
00449     deadband = RCS_CE_ATOF(inistring);
00450 #endif
00451   }
00452   else {
00453     // not found at all
00454     deadband = 0;                       // default
00455     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00456       rcs_print_error("can't find [%s] DEADBAND, using default\n", axisString);
00457     }
00458   }
00459 
00460   // now set them
00461 
00462   if (0 != emcAxisSetGains(axis,
00463                            p, i, d, ff0, ff1, ff2,
00464                            backlash, bias, maxError, deadband)) {
00465     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00466       rcs_print_error("bad return from emcAxisSetGains\n");
00467     }
00468     return -1;
00469   }
00470 
00471   // set cycle time
00472 
00473   if (NULL != (inistring = axisInifile->find("CYCLE_TIME", axisString))) {
00474 #ifndef UNDER_CE
00475     if (1 == sscanf(inistring, "%lf", &cycleTime)) {
00476       // found, and valid
00477     }
00478     else {
00479       // found, but invalid
00480       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00481         rcs_print_error("invalid inifile value for [%s] CYCLE_TIME: %s\n", axisString, inistring);
00482       }
00483       cycleTime = 1.0;                  // default
00484     }
00485 #else
00486     cycleTime = RCS_CE_ATOF(inistring);
00487 #endif
00488   }
00489   else {
00490     // not found at all
00491     cycleTime = 1.0;                    // default
00492     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00493       rcs_print_error("can't find [%s] CYCLE_TIME, using default\n", axisString);
00494     }
00495   }
00496   if (0 != emcAxisSetCycleTime(axis, cycleTime)) {
00497     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00498       rcs_print_error("bad return from emcAxisSetCycleTime\n");
00499     }
00500     return -1;
00501   }
00502 
00503   // set input scale
00504 
00505   if (NULL != (inistring = axisInifile->find("INPUT_SCALE", axisString))) {
00506 #ifndef UNDER_CE
00507     if (2 == sscanf(inistring, "%lf %lf", &scale, &offset)) {
00508       // found, and valid
00509     }
00510     else {
00511       // found, but invalid
00512       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00513         rcs_print_error("invalid inifile value for [%s] INPUT_SCALE: %s\n", axisString, inistring);
00514       }
00515       scale = 1.0;                      // default
00516       offset = 0.0;                     // default
00517     }
00518 #else
00519     scale = RCS_CE_ATOF(inistring);
00520     offset = 0.0;
00521 #endif
00522   }
00523   else {
00524     // not found at all
00525     scale = 1.0;                        // default
00526     offset = 0.0;                       // default
00527     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00528       rcs_print_error("can't find [%s] INPUT_SCALE, using default\n", axisString);
00529     }
00530   }
00531 
00532 
00533 #ifdef UNDER_CE
00534   if (NULL != (inistring = axisInifile->find("INPUT_OFFSET", axisString))) {
00535     offset = RCS_CE_ATOF(inistring);
00536   }
00537 #endif
00538 
00539   if (0 != emcAxisSetInputScale(axis, scale, offset)) {
00540     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00541       rcs_print_error("bad return from emcAxisSetInputScale\n");
00542     }
00543     return -1;
00544   }
00545 
00546   // set output scale
00547 
00548   if (NULL != (inistring = axisInifile->find("OUTPUT_SCALE", axisString))) {
00549 #ifndef UNDER_CE
00550     if (2 == sscanf(inistring, "%lf %lf", &scale, &offset)) {
00551       // found, and valid
00552     }
00553     else {
00554       // found, but invalid
00555       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00556         rcs_print_error("invalid inifile value for [%s] OUTPUT_SCALE: %s\n", axisString, inistring);
00557       }
00558       scale = 1.0;                      // default
00559       offset = 0.0;                     // default
00560     }
00561 #else
00562     scale = RCS_CE_ATOF(inistring);
00563     offset = 0.0;
00564 #endif
00565   }
00566   else {
00567     // not found at all
00568     scale = 1.0;                        // default
00569     offset = 0.0;                       // default
00570     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00571       rcs_print_error("can't find [%s] OUTPUT_SCALE, using default\n", axisString);
00572     }
00573   }
00574 
00575 #ifdef UNDER_CE
00576   if (NULL != (inistring = axisInifile->find("INPUT_OFFSET", axisString))) {
00577     offset = RCS_CE_ATOF(inistring);
00578   }
00579 #endif
00580 
00581   if (0 != emcAxisSetOutputScale(axis, scale, offset)) {
00582     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00583       rcs_print_error("bad return from emcAxisSetOutputScale\n");
00584     }
00585     return -1;
00586   }
00587 
00588   if (NULL != (inistring = axisInifile->find("MIN_LIMIT", axisString))) {
00589 #ifndef UNDER_CE
00590     if (1 == sscanf(inistring, "%lf", &limit)) {
00591       // found, and valid
00592     }
00593     else {
00594       // found, but invalid
00595       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00596         rcs_print_error("invalid inifile value for [%s] MIN_LIMIT: %s\n", axisString, inistring);
00597       }
00598       limit = -1;                       // default for min limit
00599     }
00600 #else
00601     limit = RCS_CE_ATOF(inistring);
00602 #endif
00603   }
00604   else {
00605     // not found at all
00606     limit = -1;                 // default for min limit
00607     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00608       rcs_print_error("can't find [%s] MIN_LIMIT, using default\n", axisString);
00609     }
00610   }
00611 
00612   if (0 != emcAxisSetMinPositionLimit(axis, limit)) {
00613     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00614       rcs_print_error("bad return from emcAxisSetMinPositionLimit\n");
00615     }
00616     return -1;
00617   }
00618 
00619   if (NULL != (inistring = axisInifile->find("MAX_LIMIT", axisString))) {
00620 #ifndef UNDER_CE
00621     if (1 == sscanf(inistring, "%lf", &limit)) {
00622       // found, and valid
00623     }
00624     else {
00625       // found, but invalid
00626       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00627         rcs_print_error("invalid inifile value for [%s] MAX_LIMIT: %s\n", axisString, inistring);
00628       }
00629       limit = 1;                        // default for max limit
00630     }
00631 #else
00632     limit = RCS_CE_ATOF(inistring);
00633 #endif
00634   }
00635   else {
00636     // not found at all
00637     limit = 1;                  // default for max limit
00638     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00639       rcs_print_error("can't find [%s] MAX_LIMIT, using default\n", axisString);
00640     }
00641   }
00642   if (0 != emcAxisSetMaxPositionLimit(axis, limit)) {
00643     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00644       rcs_print_error("bad return from emcAxisSetMaxPositionLimit\n");
00645     }
00646     return -1;
00647   }
00648 
00649   if (NULL != (inistring = axisInifile->find("MIN_OUTPUT", axisString))) {
00650 #ifndef UNDER_CE
00651     if (1 == sscanf(inistring, "%lf", &limit)) {
00652       // found, and valid
00653     }
00654     else {
00655       // found, but invalid
00656       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00657         rcs_print_error("invalid inifile value for [%s] MIN_OUTPUT: %s\n", axisString, inistring);
00658       }
00659       limit = -1;                       // default for min output
00660     }
00661 #else
00662     limit = RCS_CE_ATOF(inistring);
00663 #endif
00664   }
00665   else {
00666     // not found at all
00667     limit = -1;                 // default for min output
00668     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00669       rcs_print_error("can't find [%s] MIN_OUTPUT, using default\n", axisString);
00670     }
00671   }
00672   if (0 != emcAxisSetMinOutputLimit(axis, limit)) {
00673     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00674       rcs_print_error("bad return from emcAxisSetMinOutputLimit\n");
00675     }
00676     return -1;
00677   }
00678 
00679   if (NULL != (inistring = axisInifile->find("MAX_OUTPUT", axisString))) {
00680 #ifndef UNDER_CE
00681     if (1 == sscanf(inistring, "%lf", &limit)) {
00682       // found, and valid
00683     }
00684     else {
00685       // found, but invalid
00686       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00687         rcs_print_error("invalid inifile value for [%s] MAX_OUTPUT: %s\n", axisString, inistring);
00688       }
00689       limit = 1;                        // default for max output
00690     }
00691 #else
00692     limit = RCS_CE_ATOF(inistring);
00693 #endif
00694   }
00695   else {
00696     // not found at all
00697     limit = 1;                  // default for max output
00698     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00699       rcs_print_error("can't find [%s] MAX_OUTPUT, using default\n", axisString);
00700     }
00701   }
00702   if (0 != emcAxisSetMaxOutputLimit(axis, limit)) {
00703     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00704       rcs_print_error("bad return from emcAxisSetMaxOutputLimit\n");
00705     }
00706     return -1;
00707   }
00708 
00709   if (NULL != (inistring = axisInifile->find("FERROR", axisString))) {
00710 #ifndef UNDER_CE
00711     if (1 == sscanf(inistring, "%lf", &maxFerror)) {
00712       // found, and valid
00713     }
00714     else {
00715       // found, but invalid
00716       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00717         rcs_print_error("invalid inifile value for [%s] FERROR: %s\n", axisString, inistring);
00718       }
00719       maxFerror = 1;                    // default for max ferror
00720     }
00721 #else
00722     maxFerror = RCS_CE_ATOF(inistring);
00723 #endif
00724   }
00725   else {
00726     // not found at all
00727     maxFerror = 1;                      // default for max ferror
00728     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00729       rcs_print_error("can't find [%s] FERROR, using default\n", axisString);
00730     }
00731   }
00732   if (0 != emcAxisSetFerror(axis, maxFerror)) {
00733     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00734       rcs_print_error("bad return from emcAxisSetFerror\n");
00735     }
00736     return -1;
00737   }
00738 
00739   // do MIN_FERROR, if it's there. If not, use value of maxFerror above
00740   if (NULL != (inistring = axisInifile->find("MIN_FERROR", axisString))) {
00741 #ifndef UNDER_CE
00742     if (1 == sscanf(inistring, "%lf", &limit)) {
00743       // found, and valid
00744     }
00745     else {
00746       // found, but invalid
00747       limit = maxFerror;        // use prev value of max ferror
00748       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00749         rcs_print_error("invalid inifile value for [%s] MIN_FERROR: %s, using default %f\n", axisString, inistring, limit);
00750       }
00751     }
00752 #else
00753     limit = RCS_CE_ATOF(inistring);
00754 #endif
00755   }
00756   else {
00757     // not found at all
00758     limit = maxFerror;  // use prev value of max ferror
00759     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00760       rcs_print_error("can't find [%s] MIN_FERROR, using default %f\n", axisString, limit);
00761     }
00762   }
00763   if (0 != emcAxisSetMinFerror(axis, limit)) {
00764     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00765       rcs_print_error("bad return from emcAxisSetMinFerror\n");
00766     }
00767     return -1;
00768   }
00769 
00770   if (NULL != (inistring = axisInifile->find("HOMING_VEL", axisString))) {
00771 #ifndef UNDER_CE
00772     if (1 == sscanf(inistring, "%lf", &homingVel)) {
00773       // found, and valid
00774     }
00775     else {
00776       // found, but invalid
00777       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00778         rcs_print_error("invalid inifile value for [%s] HOMING_VEL: %s\n", axisString, inistring);
00779       }
00780       homingVel = 1;                    // default for homing vel
00781     }
00782 #else
00783     homingVel = RCS_CE_ATOF(inistring);
00784 #endif
00785   }
00786   else {
00787     // not found at all
00788     homingVel = 1;
00789     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00790       rcs_print_error("can't find [%s] HOMING_VEL, using default\n", axisString);
00791     }
00792   }
00793   if (0 != emcAxisSetHomingVel(axis, homingVel)) {
00794     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00795       rcs_print_error("bad return from emcAxisSetHomingVel\n");
00796     }
00797     return -1;
00798   }
00799 
00800   if (NULL != (inistring = axisInifile->find("HOME", axisString))) {
00801 #ifndef UNDER_CE
00802     if (1 == sscanf(inistring, "%lf", &home)) {
00803       // found, and valid
00804     }
00805     else {
00806       // found, but invalid
00807       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00808         rcs_print_error("invalid inifile value for [%s] HOME: %s\n", axisString, inistring);
00809       }
00810       home = 0.0;                       // default
00811     }
00812 #else
00813     home = RCS_CE_ATOF(inistring);
00814 #endif
00815   }
00816   else {
00817     // not found at all
00818     home = 0.0;
00819     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00820       rcs_print_error("can't find [%s] HOME, using default\n", axisString);
00821     }
00822   }
00823   if (0 != emcAxisSetHome(axis, home)) {
00824     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00825       rcs_print_error("bad return from emcAxisSetHome\n");
00826     }
00827     return -1;
00828   }
00829 
00830   if (NULL != (inistring = axisInifile->find("MAX_VELOCITY", axisString))) {
00831 #ifndef UNDER_CE
00832     if (1 == sscanf(inistring, "%lf", &maxVelocity)) {
00833       // found, and valid
00834     }
00835     else {
00836       // found, but invalid
00837       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00838         rcs_print_error("invalid inifile value for [%s] MAX_VELOCITY: %s\n", axisString, inistring);
00839       }
00840       maxVelocity = DEFAULT_AXIS_MAX_VELOCITY;  // default
00841     }
00842 #else
00843     maxVelocity = RCS_CE_ATOF(inistring);
00844 #endif
00845   }
00846   else {
00847     // not found at all
00848     maxVelocity = DEFAULT_AXIS_MAX_VELOCITY;
00849     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00850       rcs_print_error("can't find [%s] MAX_VELOCITY, using default\n", axisString);
00851     }
00852   }
00853   if (0 != emcAxisSetMaxVelocity(axis, maxVelocity)) {
00854     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00855       rcs_print_error("bad return from emcAxisSetMaxVelocity\n");
00856     }
00857     return -1;
00858   }
00859 
00860   if (NULL != (inistring = axisInifile->find("ENABLE_POLARITY", axisString))) {
00861 #ifndef UNDER_CE
00862     if (1 == sscanf(inistring, "%d", &polarity)) {
00863       // found, and valid
00864     }
00865     else {
00866       // found, but invalid
00867       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00868         rcs_print_error("invalid inifile value for [%s] ENABLE_POLARITY: %s\n", axisString, inistring);
00869       }
00870       polarity = 1;                     // default for polarities
00871     }
00872 #else
00873     polarity = atol(inistring);
00874 #endif
00875   }
00876   else {
00877     // not found at all
00878     polarity = 1;                       // default for polarities
00879     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00880       rcs_print_error("can't find [%s] ENABLE_POLARITY, using default\n", axisString);
00881     }
00882   }
00883   if (0 != emcAxisSetEnablePolarity(axis, polarity)) {
00884     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00885       rcs_print_error("bad return from emcAxisSetEnablePolarity\n");
00886     }
00887     return -1;
00888   }
00889 
00890   if (NULL != (inistring = axisInifile->find("MIN_LIMIT_SWITCH_POLARITY", axisString))) {
00891 #ifndef UNDER_CE
00892     if (1 == sscanf(inistring, "%d", &polarity)) {
00893       // found, and valid
00894     }
00895     else {
00896       // found, but invalid
00897       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00898         rcs_print_error("invalid inifile value for [%s] MIN_LIMIT_SWITCH_POLARITY: %s\n", axisString, inistring);
00899       }
00900       polarity = 1;                     // default for polarities
00901     }
00902 #else
00903     polarity = atol(inistring);
00904 #endif
00905   }
00906   else {
00907     // not found at all
00908     polarity = 1;                       // default for polarities
00909     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00910       rcs_print_error("can't find [%s] MIN_LIMIT_SWITCH_POLARITY, using default\n", axisString);
00911     }
00912   }
00913   if (0 != emcAxisSetMinLimitSwitchPolarity(axis, polarity)) {
00914     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00915       rcs_print_error("bad return from emcAxisSetMinLimitSwitchPolarity\n");
00916     }
00917     return -1;
00918   }
00919 
00920   if (NULL != (inistring = axisInifile->find("MAX_LIMIT_SWITCH_POLARITY", axisString))) {
00921 #ifndef UNDER_CE
00922     if (1 == sscanf(inistring, "%d", &polarity)) {
00923       // found, and valid
00924     }
00925     else {
00926       // found, but invalid
00927       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00928         rcs_print_error("invalid inifile value for [%s] MAX_LIMIT_SWITCH_POLARITY: %s\n", axisString, inistring);
00929       }
00930       polarity = 1;                     // default for polarities
00931     }
00932 #else
00933     polarity = atol(inistring);
00934 #endif
00935   }
00936   else {
00937     // not found at all
00938     polarity = 1;                       // default for polarities
00939     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00940       rcs_print_error("can't find [%s] MAX_LIMIT_SWITCH_POLARITY, using default\n", axisString);
00941     }
00942   }
00943   if (0 != emcAxisSetMaxLimitSwitchPolarity(axis, polarity)) {
00944     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00945       rcs_print_error("bad return from emcAxisSetMaxLimitSwitchPolarity\n");
00946     }
00947     return -1;
00948   }
00949 
00950   if (NULL != (inistring = axisInifile->find("HOME_SWITCH_POLARITY", axisString))) {
00951 #ifndef UNDER_CE
00952     if (1 == sscanf(inistring, "%d", &polarity)) {
00953       // found, and valid
00954     }
00955     else {
00956       // found, but invalid
00957       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00958         rcs_print_error("invalid inifile value for [%s] HOME_SWITCH_POLARITY: %s\n", axisString, inistring);
00959       }
00960       polarity = 1;                     // default for polarities
00961     }
00962 #else
00963     polarity = atol(inistring);
00964 #endif
00965   }
00966   else {
00967     // not found at all
00968     polarity = 1;                       // default for polarities
00969     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
00970       rcs_print_error("can't find [%s] HOME_SWITCH_POLARITY, using default\n", axisString);
00971     }
00972   }
00973   if (0 != emcAxisSetHomeSwitchPolarity(axis, polarity)) {
00974     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
00975       rcs_print_error("bad return from emcAxisSetHomeSwitchPolarity\n");
00976     }
00977     return -1;
00978   }
00979 
00980   if (NULL != (inistring = axisInifile->find("HOMING_POLARITY", axisString))) {
00981 #ifndef UNDER_CE
00982     if (1 == sscanf(inistring, "%d", &polarity)) {
00983       // found, and valid
00984     }
00985     else {
00986       // found, but invalid
00987       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
00988         rcs_print_error("invalid inifile value for [%s] HOMING_POLARITY: %s\n", axisString, inistring);
00989       }
00990       polarity = 1;                     // default for polarities
00991     }
00992 #else
00993     polarity = atol(inistring);
00994 #endif
00995   }
00996   else {
00997     // not found at all
00998     polarity = 1;                       // default for polarities
00999     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
01000       rcs_print_error("can't find [%s] HOMING_POLARITY, using default\n", axisString);
01001     }
01002   }
01003   if (0 != emcAxisSetHomingPolarity(axis, polarity)) {
01004     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
01005       rcs_print_error("bad return from emcAxisSetHomingPolarity\n");
01006     }
01007     return -1;
01008   }
01009 
01010   if (NULL != (inistring = axisInifile->find("HOME_OFFSET", axisString))) {
01011 #ifndef UNDER_CE
01012     if (1 == sscanf(inistring, "%lf", &offset)) {
01013       // found, and valid
01014     }
01015     else {
01016       // found, but invalid
01017       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
01018         rcs_print_error("invalid inifile value for [%s] HOME_OFFSET: %s\n", axisString, inistring);
01019       }
01020       offset = 0.0;
01021     }
01022 #else
01023     offset = atol(inistring);
01024 #endif
01025   }
01026   else {
01027     // not found at all
01028     offset = 0.0;
01029     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
01030       rcs_print_error("can't find [%s] HOME_OFFSET, using default\n", axisString);
01031     }
01032   }
01033   if (0 != emcAxisSetHomeOffset(axis, offset)) {
01034     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
01035       rcs_print_error("bad return from emcAxisSetHomeOffset\n");
01036     }
01037     return -1;
01038   }
01039 
01040   if (NULL != (inistring = axisInifile->find("FAULT_POLARITY", axisString))) {
01041 #ifndef UNDER_CE
01042     if (1 == sscanf(inistring, "%d", &polarity)) {
01043       // found, and valid
01044     }
01045     else {
01046       // found, but invalid
01047       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
01048         rcs_print_error("invalid inifile value for [%s] FAULT_POLARITY: %s\n", axisString, inistring);
01049       }
01050       polarity = 1;                     // default for polarities
01051     }
01052 #else
01053     polarity = atol(inistring);
01054 #endif
01055   }
01056   else {
01057     // not found at all
01058     polarity = 1;                       // default for polarities
01059     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
01060       rcs_print_error("can't find [%s] FAULT_POLARITY, using default\n", axisString);
01061     }
01062   }
01063   if (0 != emcAxisSetFaultPolarity(axis, polarity)) {
01064     if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
01065       rcs_print_error("bad return from emcAxisSetFaultPolarity\n");
01066     }
01067     return -1;
01068   }
01069 
01070   if (NULL != (inistring = axisInifile->find("COMP_FILE", axisString))) {
01071     if (0 != emcAxisLoadComp(axis, inistring)) {
01072       if (EMC_DEBUG & EMC_DEBUG_CONFIG) {
01073         rcs_print_error("bad return from emcAxisLoadComp\n");
01074       }
01075       return -1;
01076     }
01077   }
01078   // else not found, so ignore
01079 
01080   // lastly, activate axis. Do this last so that the motion controller
01081   // won't flag errors midway during configuration
01082   emcAxisActivate(axis);
01083 
01084   return 0;
01085 }
01086 
01087 /*
01088   iniAxis(int axis, const char *filename)
01089 
01090   Loads ini file parameters for specified axis, [0 .. AXES - 1]
01091 
01092   Looks for AXES in TRAJ section for how many to do, up to
01093   EMC_AXIS_MAX.
01094  */
01095 int iniAxis(int axis, const char *filename)
01096 {
01097   int retval = 0;
01098   const char *inistring;
01099   int axes;
01100 
01101   axisInifile = new INIFILE;
01102   if (-1 == axisInifile->open(filename)) {
01103     return -1;
01104   }
01105 
01106   if (NULL != (inistring = axisInifile->find("AXES", "TRAJ"))) {
01107 #ifndef UNDER_CE
01108     if (1 == sscanf(inistring, "%d", &axes)) {
01109       // found, and valid
01110     }
01111     else {
01112       // found, but invalid
01113       if (EMC_DEBUG & EMC_DEBUG_INVALID) {
01114         rcs_print_error("invalid inifile value for [TRAJ] AXES: %s\n", inistring);
01115       }
01116       axes = 0;
01117     }
01118 #else
01119     axes = atol(inistring);
01120 #endif
01121   }
01122   else {
01123     // not found at all
01124     axes = 1;
01125     if (EMC_DEBUG & EMC_DEBUG_DEFAULTS) {
01126       rcs_print_error("can't find [TRAJ] AXES, using default %d\n", axes);
01127     }
01128   }
01129 
01130   if (axis < 0 ||
01131       axis >= axes) {
01132     // requested axis exceeds machine axes
01133     axisInifile->close();
01134     delete axisInifile;
01135     return -1;
01136   }
01137 
01138   // load its values
01139   if (0 != loadAxis(axis)) {
01140     retval = -1;
01141   }
01142 
01143   // close the inifile
01144   axisInifile->close();
01145   delete axisInifile;
01146 
01147   return retval;
01148 }
01149 
01150 // WPS -- these functions are needed only by dumpAxis(), there
01151 // is no reasonable way to implement dumpAxis under CE.
01152 #ifndef UNDER_CE
01153 
01154 // FIXME-- begin temporary insert of ini file stuff
01155 
01156 #define INIFILE_MIN_FLOAT_PRECISION 3
01157 #define INIFILE_BACKUP_SUFFIX ".bak"
01158 
01159 /* iniIsEntry(const char *line, char *var, char *val) returns 0 if the
01160    line is not interpretable as a variable-value ini file entry. If the
01161    line is interpretable as an ini file entry (i.e., it is of the form
01162    ``<some nonwhite> = {<value>}'' where <value> is optional), then the
01163    variable string is copied to 'var', and the value string is copied to
01164    'val'. Leading and trailing whitespace around 'var' and 'val' are
01165    omitted. */
01166 
01167 static int iniIsEntry(const char *line, char *var, char *val)
01168 {
01169   const char *ptr = line;
01170   char *varptr = var;
01171   char *valptr = val;
01172   char *lastwhite = NULL;
01173   int sawEqual = 0;
01174 
01175   // position ptr to first non-white on line
01176   while (isspace(*ptr)) {
01177     ptr++;
01178   }
01179 
01180   if (*ptr == 0 ||
01181       *ptr == '=') {
01182     // got to end or '=' before any non-white
01183     return 0;
01184   }
01185 
01186   // here's the first non-white, so begin copy to var
01187   while (*ptr != 0) {
01188     if (*ptr == '=') {
01189       sawEqual = 1;
01190       break;
01191     }
01192 
01193     // copy it, including any whitespace
01194     *varptr = *ptr;
01195 
01196     // mark the location of last whitespace, for nulling
01197     if (isspace(*ptr)) {
01198       if (lastwhite == NULL) {
01199         lastwhite = varptr;
01200       }
01201     }
01202     else {
01203       lastwhite = NULL;
01204     }
01205 
01206     varptr++;
01207     ptr++;
01208   }
01209 
01210   if (! sawEqual) {
01211     return 0;
01212   }
01213 
01214   // null-terminate at last whitespace, or end of string if none
01215   if (lastwhite != NULL) {
01216     *lastwhite = 0;
01217   }
01218   else {
01219     *varptr = 0;
01220   }
01221 
01222   // now move to value part
01223 
01224   lastwhite = NULL;
01225   ptr++;                        // step over '='
01226 
01227   // position ptr to first non-white on line
01228   while (isspace(*ptr)) {
01229     ptr++;
01230   }
01231 
01232   if (*ptr == 0) {
01233     // got to end before any non-white
01234     return 0;
01235   }
01236 
01237   // here's the first non-white, so begin copy to var
01238   while (*ptr != 0) {
01239     // copy it, including any whitespace
01240     *valptr = *ptr;
01241 
01242     // mark the location of last whitespace, for nulling
01243     if (isspace(*ptr)) {
01244       if (lastwhite == NULL) {
01245         lastwhite = valptr;
01246       }
01247     }
01248     else {
01249       lastwhite = NULL;
01250     }
01251 
01252     valptr++;
01253     ptr++;
01254   }
01255 
01256   // null-terminate at last whitespace, or end of string if none
01257   if (lastwhite != NULL) {
01258     *lastwhite = 0;
01259   }
01260   else {
01261     *valptr = 0;
01262   }
01263 
01264   return 1;
01265 }
01266 
01267 /* iniIsSection(const char *line, char *section) returns 0 if the line
01268    is not interpretable as a section. If the line is interpretable as a
01269    section (i.e., it has [ <string > ] as the only thing on it), then the
01270    stuff between the [], not including any leading or trailing
01271    whitespace, but including any intervening whitespace, is copied to
01272    'section'. */
01273 
01274 static int iniIsSection(const char *line, char *section)
01275 {
01276   const char *ptr = line;
01277   char *secptr = section;
01278   char *lastwhite = NULL;
01279   int sawClose = 0;
01280 
01281   // position ptr to first non-white on line
01282   while (isspace(*ptr)) {
01283     ptr++;
01284   }
01285 
01286   if (*ptr == 0) {
01287     // got to end before any non-white
01288     return 0;
01289   }
01290 
01291   if (*ptr != '[') {
01292     // not section format
01293     return 0;
01294   }
01295 
01296   // we're on [, so move to next non-white
01297   ptr++;
01298   while (isspace(*ptr)) {
01299     ptr++;
01300   }
01301 
01302   if (*ptr == 0) {
01303     // got to end before any non-white
01304     return 0;
01305   }
01306 
01307   // here's the first non-white after the [, so begin copy to string
01308   while (*ptr != 0) {
01309     if (*ptr == ']') {
01310       sawClose = 1;
01311       break;
01312     }
01313 
01314     // copy it, including any whitespace
01315     *secptr = *ptr;
01316 
01317     // mark the location of last whitespace, for nulling
01318     if (isspace(*ptr)) {
01319       if (lastwhite == NULL) {
01320         lastwhite = secptr;
01321       }
01322     }
01323     else {
01324       lastwhite = NULL;
01325     }
01326 
01327     secptr++;
01328     ptr++;
01329   }
01330 
01331   if (! sawClose) {
01332     // section had a close bracket
01333     return 0;
01334   }
01335 
01336   // null-terminate at last whitespace, or end of string if none
01337   if (lastwhite != NULL) {
01338     *lastwhite = 0;
01339   }
01340   else {
01341     *secptr = 0;
01342   }
01343 
01344   // section didn't have a close bracket
01345   return 1;
01346 }
01347 
01348 int iniGetFloatPrec(const char *str)
01349 {
01350   const char *ptr = str;
01351   int prec = 0;
01352 
01353   // find '.', return min precision if no decimal point
01354   while (1) {
01355     if (*ptr == 0) {
01356       return INIFILE_MIN_FLOAT_PRECISION;
01357     }
01358     if (*ptr == '.') {
01359       break;
01360     }
01361     ptr++;
01362   }
01363 
01364   // ptr is on '.', so step over
01365   ptr++;
01366 
01367   // count number of digits until whitespace or end or non-digit
01368   while (1) {
01369     if (*ptr == 0) {
01370       break;
01371     }
01372     if (! isdigit(*ptr)) {
01373       break;
01374     }
01375     // else it's a digit
01376     prec++;
01377     ptr++;
01378   }
01379 
01380   return prec > INIFILE_MIN_FLOAT_PRECISION ? prec : INIFILE_MIN_FLOAT_PRECISION;
01381 }
01382 
01383 int iniFormatFloat(char *fmt, const char *var, const char *val)
01384 {
01385   sprintf(fmt, "%s = %%.%df\n", var, iniGetFloatPrec(val));
01386 
01387   return 0;
01388 }
01389 
01390 // 'val' in this case is a string with a pair of floats, the first
01391 // which sets the precision
01392 int iniFormatFloat2(char *fmt, const char *var, const char *val)
01393 {
01394   int prec;
01395 
01396   // FIXME-- should capture each one's float precision; right
01397   // now we're using the first as the precision for both
01398   prec = iniGetFloatPrec(val);
01399   sprintf(fmt, "%s = %%.%df %%.%df\n", var, prec, prec);
01400 
01401   return 0;
01402 }
01403 
01404 // end temporary insert of ini file stuff
01405 
01406 /// End of UNDER_CE ifdefing out.
01407 #endif
01408 
01409 /*
01410   dumpAxis(int axis, const char *filename, EMC_AXIS_STAT *stat)
01411 
01412   Takes the file name for the ini file, makes a backup copy, opens the
01413   backup copy, then overwrites the original with a line-by-line version
01414   of the original, parsing the lines for ones it understands and
01415   replacing the values with the current ones.
01416  */
01417 int dumpAxis(int axis, const char *filename, EMC_AXIS_STAT *stat)
01418 {
01419 #ifdef UNDER_CE
01420   return -1;
01421 #else
01422   char ourAxisSection[256];
01423   int ourAxis = 0;
01424   FILE *infp = NULL;
01425   FILE *outfp = NULL;
01426   char line[256];
01427   char section[256];
01428   char var[256], val[256];
01429   char fmt[256];
01430 
01431   // rename with backup suffix
01432   strcpy(line, filename);
01433   strcat(line, INIFILE_BACKUP_SUFFIX);
01434   if (0 != rename(filename, line)) {
01435     fprintf(stderr, "can't make backup copy of INI file %s\n", filename);
01436     return -1;
01437   }
01438 
01439   // open backup for reading
01440   if (NULL == (infp = fopen(line, "r"))) {
01441     fprintf(stderr, "can't open backup copy of INI file %s\n", line);
01442     return -1;
01443   }
01444 
01445   // open original for writing
01446   if (NULL == (outfp = fopen(filename, "w"))) {
01447     fprintf(stderr, "can't open original copy of INI file %s\n", line);
01448     return -1;
01449   }
01450 
01451   // set our axis string and flag that we're in that section
01452   sprintf(ourAxisSection, "AXIS_%d", axis);
01453   ourAxis = 0;
01454 
01455   while (!feof(infp)) {
01456     if (NULL == fgets(line, 256, infp)) {
01457       break;
01458     }
01459 
01460     if (iniIsSection(line, section)) {
01461       // if this is "AXIS_0,1,...", it's what we want
01462       if (!strcmp(section, ourAxisSection)) {
01463         ourAxis = 1;
01464       }
01465       else {
01466         ourAxis = 0;
01467       }
01468     }
01469 
01470     if (ourAxis) {
01471       if (iniIsEntry(line, var, val)) {
01472         if (!strcmp(var, "P")) {
01473           iniFormatFloat(fmt, var, val);
01474           fprintf(outfp, fmt, stat->p);
01475           continue;             // avoid fputs() below, since we wrote it
01476         }
01477         else if (!strcmp(var, "I")) {
01478           iniFormatFloat(fmt, var, val);
01479           fprintf(outfp, fmt, stat->i);
01480           continue;
01481         }
01482         else if (!strcmp(var, "D")) {
01483           iniFormatFloat(fmt, var, val);
01484           fprintf(outfp, fmt, stat->d);
01485           continue;
01486         }
01487         else if (!strcmp(var, "FF0")) {
01488           iniFormatFloat(fmt, var, val);
01489           fprintf(outfp, fmt, stat->ff0);
01490           continue;
01491         }
01492         else if (!strcmp(var, "FF1")) {
01493           iniFormatFloat(fmt, var, val);
01494           fprintf(outfp, fmt, stat->ff1);
01495           continue;
01496         }
01497         else if (!strcmp(var, "FF2")) {
01498           iniFormatFloat(fmt, var, val);
01499           fprintf(outfp, fmt, stat->ff2);
01500           continue;
01501         }
01502         else if (!strcmp(var, "BACKLASH")) {
01503           iniFormatFloat(fmt, var, val);
01504           fprintf(outfp, fmt, stat->backlash);
01505           continue;
01506         }
01507         else if (!strcmp(var, "BIAS")) {
01508           iniFormatFloat(fmt, var, val);
01509           fprintf(outfp, fmt, stat->bias);
01510           continue;
01511         }
01512         else if (!strcmp(var, "MAX_ERROR")) {
01513           iniFormatFloat(fmt, var, val);
01514           fprintf(outfp, fmt, stat->maxError);
01515           continue;
01516         }
01517         else if (!strcmp(var, "DEADBAND")) {
01518           iniFormatFloat(fmt, var, val);
01519           fprintf(outfp, fmt, stat->deadband);
01520           continue;
01521         }
01522         else if (!strcmp(var, "OUTPUT_SCALE")) {
01523           // val will be a string with two floats, e.g., "1.0 0.0",
01524           // and iniFormatFloat2() will set fmt to convert 2 floats
01525           // at the precision of the first in the string
01526           iniFormatFloat2(fmt, var, val);
01527           fprintf(outfp, fmt, stat->outputScale, stat->outputOffset);
01528           continue;
01529         }
01530         else if (!strcmp(var, "FERROR")) {
01531           iniFormatFloat(fmt, var, val);
01532           fprintf(outfp, fmt, stat->maxFerror);
01533           continue;
01534         }
01535         else if (!strcmp(var, "MIN_FERROR")) {
01536           iniFormatFloat(fmt, var, val);
01537           fprintf(outfp, fmt, stat->minFerror);
01538           continue;
01539         }
01540       }
01541     }
01542 
01543     // write it out
01544     fputs(line, outfp);
01545   }
01546 
01547   fclose(infp);
01548   fclose(outfp);
01549 
01550   return 0;
01551 #endif
01552 }

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