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

dcmotor2.c

Go to the documentation of this file.
00001 /*
00002    dcmotor.c
00003 
00004    DC motor simulation
00005 
00006    From Benjamin C. Kuo, "Automatic Control Systems," Fourth Edition,
00007    pp. 176-186.
00008 
00009    Units are SI for all quantities. Note that back EMF constant Kb is
00010    identically equal to Torque Constant in SI units, so Ki is omitted
00011    from interface and replaced with Kb in calculations.
00012 
00013    Modification history:
00014 
00015    23-Oct-2000 WPS split this file from dcmotor.c to provide an algorithm
00016    based on integrating the differential equations more accurately.
00017    23-Sep-1999  WPS replaced stdio functions with inet_file functions
00018    which work under CE.
00019    23-Sep-1999 WPS initialized suspicious return retval from dcmotorGetParameters
00020    27-Jan-1999 WPS added "volatile"'s to avoid NT optimization problem.
00021    23-Mar-1998  FMP included <string.h>, as I should have
00022    17-Mar-1998  FMP added section arg to dcmotorIniLoad()
00023    9-Sep-1997  FMP added dcmotorResetState();
00024    17-Aug-1997  FMP took out etime() call in dcmotorRunCycle-- need to
00025    add a function to get real time-- etime() in rcs library does this,
00026    but we don't want to include all of that here
00027    2-May-1997  FMP fixed bug in dcmotorRunCycle() where I left deltaT
00028    unset if cycleTime was not <= 0.0. This bug, of course, cost me a week.
00029    25-Apr-1997  FMP added lastTime and etime() for real-time sim
00030    24-Apr-1997  FMP added dcmotorIniLoad()
00031    17-Apr-1997  FMP created from C part of original dcmotor.c
00032 */
00033 
00034 #ifndef NO_STDIO_SUPPORT
00035 #ifdef UNDER_CE
00036 #include "rcs_ce.h"             /* RCS_CE_ATOF() */
00037 #else
00038 #include <stdio.h>
00039 #endif
00040 #include "inetfile.hh"          /* inet_file_open() */
00041 #include "inifile.h"
00042 #include "rcs_prnt.hh"          /* rcs_print() */
00043 #include <string.h>
00044 #include "inifile.h"
00045 #endif
00046 #include "dcmotor2.h"           /* these decls */
00047 #include <math.h>
00048 
00049 // Setup __attribute__() macro so that non-gnu compilers still work.
00050 // For gnu compilers the __attribute__((unused)) eliminates the warning
00051 // for unused variables.
00052 #ifndef __GNUC__
00053 #ifndef __attribute__
00054 #define __attribute__(x)
00055 #endif
00056 #endif
00057 
00058 /* ident tag */
00059 static char __attribute__((unused)) ident[] = "$Id: dcmotor2.c,v 1.3 2001/01/16 17:35:13 wshackle Exp $";
00060 
00061 #define PARAMETERS_SET 0x01
00062 #define CYCLE_TIME_SET 0x02
00063 #define OFFSET_SET 0x04
00064 #define REVS_PER_UNIT_SET 0x08
00065 #define ALL_SET (PARAMETERS_SET | CYCLE_TIME_SET | OFFSET_SET | REVS_PER_UNIT_SET)
00066 
00067 /* Conversion factors */
00068 /* oz-in * 0.00708 = newton-meters */
00069 /* foot-pounds * 1.359 = newton-meters */
00070 #define OZ_IN_TO_N_M 0.00708
00071 #define LB_FT_TO_N_M 1.359
00072 
00073 int dcmotorInit(DC_MOTOR_STRUCT * dcmotor)
00074 {
00075   if (0 == dcmotor)
00076   {
00077     return -1;
00078   }
00079 
00080   /* parameters */
00081   dcmotor->Ra = 0.0;
00082   dcmotor->La = 0.0;
00083   dcmotor->Kb = 0.0;
00084   dcmotor->Jm = 0.0;
00085   dcmotor->Bm = 0.0;
00086 
00087   /* internal vars */
00088   dcmotor->configured = 0;
00089   dcmotor->cycleTime = 0.0;
00090   dcmotor->offset = 0.0;
00091   dcmotor->revsPerUnit = 0.0;
00092   dcmotor->lastTime = -1.0;
00093 
00094   /* state vars */
00095   return dcmotorResetState(dcmotor);
00096 }
00097 
00098 int dcmotorResetState(DC_MOTOR_STRUCT * dcmotor)
00099 {
00100   /* state vars */
00101   dcmotor->ia = 0.0;
00102   dcmotor->dia = 0.0;
00103   dcmotor->wm = 0.0;
00104   dcmotor->dwm = 0.0;
00105   dcmotor->thm = 0.0;
00106   dcmotor->dthm = 0.0;
00107 
00108   return 0;
00109 }
00110 
00111 int dcmotorSetCycleTime(DC_MOTOR_STRUCT * dcmotor, double seconds)
00112 {
00113   if (0 == dcmotor)
00114   {
00115     return -1;
00116   }
00117 
00118   /* note that seconds <= 0.0 means use real time */
00119   dcmotor->cycleTime = seconds;
00120   dcmotor->configured |= CYCLE_TIME_SET;
00121 
00122 
00123   if(dcmotor->configured  & PARAMETERS_SET)
00124     {
00125       // The sa_time_factor and sb_time_factor probably need to be recalculated.
00126       dcmotorSetParameters(dcmotor,*dcmotor);
00127     }
00128 
00129   return 0;
00130 }
00131 
00132 double dcmotorGetCycleTime(DC_MOTOR_STRUCT * dcmotor)
00133 {
00134   if (0 == dcmotor ||
00135       ! (dcmotor->configured & CYCLE_TIME_SET))
00136   {
00137     return 0.0;
00138   }
00139 
00140   return dcmotor->cycleTime;
00141 }
00142 
00143 int dcmotorSetParameters(DC_MOTOR_STRUCT * dcmotor, DC_MOTOR_STRUCT params)
00144 {
00145   if (0 == dcmotor)
00146   {
00147     return -1;
00148   }
00149 
00150   dcmotor->Ra = params.Ra;
00151   dcmotor->La = params.La;
00152   dcmotor->Kb = params.Kb;
00153   dcmotor->Jm = params.Jm;
00154   dcmotor->Bm = params.Bm;
00155 
00156   /***
00157       The simulation is based on two  differential equations.
00158       From modified version  of Newton's second law the rotor inertia(Jm) * angular accelleration(w') equals the sum of the torques. The torque applied by the motor is  the torque constant(Kb==Ki)*armature current(i). A torque in the opposite direction caused by friction  or the friction coefficent (Bm) * angular velocity(w).
00159 
00160      (1)    Jm*w' + Bm*w + Kb*i = 0.
00161 
00162      From ohms law the sum of all the voltages around a loop must equal zero. The voltages include the externally applied voltage from the amplifier (ea), the voltage across the armature resistance (Ra) * the current (i) , the voltage accross the armature inductance (La) * the derivative of the current(i'), and the voltage caued by back emf or Kb * the angular velocity (w).
00163 
00164      (2)   La*i' + Ra*i + Kb*w  - ea = 0.
00165 
00166      Solving for i from equation (1):
00167 
00168      (3)   i = (Jm*w' + Bm*w)/Kb
00169 
00170      Taking the derivative of both sides of (3):
00171 
00172      (4)   i' = (Jm*w'' + Bm*w')/Kb
00173 
00174      where (w'') is the second derivative of angular velocity.
00175 
00176      Substituting equations (3) and (4) into (2) :
00177 
00178      (5)  La*Jm/Kb * w'' + (Ra*Jm+La*Bm)/Kb * w' + (Ra*Bm/Kb + Kb)* w - ea = 0
00179 
00180      The coefficients of w'',w' and w are calculated below and stored in
00181      a,b and c respecively.
00182 
00183      If a is not equal to zero, the roots of this differential equation  can be calculated with the quadratic formula. The roots are sa and sb.
00184 
00185      (6) sa = -(b + sqrt(4*a*c-b^2))/(2*a)
00186 
00187      (7) sb = -(b - sqrt(4*a*c-b^2))/(2*a)
00188 
00189      If 4*a*c-b^2 is greater than zero then the real parts of sa and sb (sa_real and sb_real are calculate using (6) and (7), and the imaginary parts are zero. Otherwise both sb_real and sa_real equal -b/(2*a) and the imaginary parts sa_img and sb_img equal sqrt(4*a*c-b^2)/(2*a) and its negative.
00190 
00191      If the cycle time is set and can therefore be considered constant, the time dependant parts of the solution can be calculated ahead of time and hopefully save the CPU bandwidth. If 4*a*c-b^2 is less than zero then the  variable names sa_time_factor and sb_time_factor are a little misleading. They actually correspond to the cos factor (sa_time_factor) and sin factor (sb_time_factor).
00192 
00193      Some degenerate cases to consider:
00194 
00195      if a = 0 then it is only a first order system.
00196 
00197      if b = 0 then any exitation would cause it to oscillate forever, a fairly unrealistic system, not handled here.
00198 
00199      if c = 0 then Kb must be zero and the input voltage will have no effect on
00200      motor position.
00201 
00202   */
00203   if (params.Kb > 1E-15)
00204     {
00205       dcmotor->a = params.La*params.Jm/params.Kb;
00206       dcmotor->b = (params.La*params.Bm + params.Ra*params.Jm)/params.Kb;
00207       dcmotor->c = params.Ra*params.Bm/params.Kb + params.Kb;
00208       if( dcmotor->a > 1E-15)
00209         {
00210           dcmotor->order = 2;
00211           dcmotor->fourac_minus_b_squared = 4*dcmotor->a*dcmotor->c - dcmotor->b*dcmotor->b;
00212           if(dcmotor->fourac_minus_b_squared >= 0)
00213             {
00214               dcmotor->sa_real = -(dcmotor->b+sqrt(dcmotor->fourac_minus_b_squared))/(2*dcmotor->a);
00215               dcmotor->sa_img = 0;
00216               dcmotor->sb_real = -(dcmotor->b+sqrt(dcmotor->fourac_minus_b_squared))/(2*dcmotor->a);
00217               dcmotor->sb_img = 0;
00218               if(dcmotor->configured & CYCLE_TIME_SET)
00219                 {
00220                   dcmotor->sa_time_factor = exp(dcmotor->cycleTime*dcmotor->sa_real);
00221                   if(dcmotor->fourac_minus_b_squared != 0)
00222                     {
00223                       dcmotor->sb_time_factor = exp(dcmotor->cycleTime*dcmotor->sb_real);
00224                     }
00225                   else
00226                     {
00227                       dcmotor->sb_time_factor = dcmotor->cycleTime*exp(dcmotor->cycleTime*dcmotor->sb_real);
00228                     }
00229                 }
00230             }
00231           else
00232             {
00233               dcmotor->sa_real = dcmotor->sb_real = -(dcmotor->b/(2*dcmotor->a));
00234               dcmotor->sa_img = sqrt(-dcmotor->fourac_minus_b_squared)/(2*dcmotor->a);
00235               dcmotor->sb_img = -dcmotor->sa_img;
00236               if(dcmotor->configured & CYCLE_TIME_SET)
00237                 {
00238                   dcmotor->sa_time_factor = exp(dcmotor->cycleTime*dcmotor->sa_real)*cos(dcmotor->cycleTime*dcmotor->sa_img);
00239                   dcmotor->sb_time_factor = exp(dcmotor->cycleTime*dcmotor->sa_real)*sin(dcmotor->cycleTime*dcmotor->sa_img);
00240                 }
00241             }
00242         }
00243       else if(dcmotor->b > 1E-15)
00244         {
00245           dcmotor->order =1;
00246           dcmotor->sa_real = -dcmotor->c/dcmotor->b;
00247           dcmotor->sb_real = dcmotor->sa_img = dcmotor->sb_img = 0;
00248           if(dcmotor->configured & CYCLE_TIME_SET)
00249             {
00250               dcmotor->sa_time_factor = exp(dcmotor->cycleTime*dcmotor->sa_real);
00251               dcmotor->sb_time_factor = 0;
00252             }
00253         }
00254     }
00255 
00256   dcmotor->configured |= PARAMETERS_SET;
00257 
00258   return 0;
00259 }
00260 
00261 DC_MOTOR_STRUCT dcmotorGetParameters(DC_MOTOR_STRUCT * dcmotor)
00262 {
00263   DC_MOTOR_STRUCT retval;
00264 
00265   if (0 == dcmotor)
00266   {
00267      /* parameters */
00268     retval.Ra=0;                        /* armature resistance, ohms */
00269     retval.La=0;                        /* armature inductance, henries */
00270     retval.Kb=0;                        /* back emf constant, V/rad/s, N-m/amp */
00271     retval.Jm=0;                        /* motor rotor inertia, N-m-s^2 */
00272     retval.Bm=0;                        /* viscous friction coefficient, N-m/rad/sec */
00273 
00274   /* state vars */
00275     retval.ia=0;                        /* armature current */
00276     retval.dia=0;                       /* derivative of above */
00277     retval.wm=0;                        /* angular velocity of motor */
00278     retval.dwm=0;                       /* derivative of above */
00279     retval.thm=0;                       /* angular position of motor */
00280     retval.dthm=0;                      /* derivative of above */
00281     retval.lastTime=0;          /* timestamp of last cycle */
00282 
00283   /* internal vars */
00284     retval.configured=0;
00285     retval.cycleTime=0;         /* copy of arg to setCycleTime() */
00286     retval.offset=0;
00287     retval.revsPerUnit=0;
00288     return retval;
00289   }
00290 
00291   return *dcmotor;
00292 }
00293 
00294 int dcmotorSetOffset(DC_MOTOR_STRUCT * dcmotor, double _offset)
00295 {
00296   if (0 == dcmotor)
00297   {
00298     return -1;
00299   }
00300 
00301   dcmotor->offset = _offset;
00302   dcmotor->configured |= OFFSET_SET;
00303 
00304   return 0;
00305 }
00306 
00307 double dcmotorGetOffset(DC_MOTOR_STRUCT * dcmotor)
00308 {
00309   if (0 == dcmotor ||
00310       ! (dcmotor->configured & OFFSET_SET))
00311   {
00312     return 0.0;
00313   }
00314 
00315   return dcmotor->offset;
00316 }
00317 
00318 int dcmotorSetRevsPerUnit(DC_MOTOR_STRUCT * dcmotor, double _revsPerUnit)
00319 {
00320   if (0 == dcmotor ||
00321       _revsPerUnit <= 0.0)
00322   {
00323     return -1;
00324   }
00325 
00326   dcmotor->revsPerUnit = _revsPerUnit;
00327   dcmotor->configured |= REVS_PER_UNIT_SET;
00328 
00329   return 0;
00330 }
00331 
00332 double dcmotorGetRevsPerUnit(DC_MOTOR_STRUCT * dcmotor)
00333 {
00334   if (0 == dcmotor ||
00335       ! (dcmotor->configured & REVS_PER_UNIT_SET))
00336   {
00337     return 0.0;
00338   }
00339 
00340   return dcmotor->revsPerUnit;
00341 }
00342 
00343 double dcmotorGetOutput(DC_MOTOR_STRUCT * dcmotor)
00344 {
00345   if (0 == dcmotor ||
00346       dcmotor->configured != ALL_SET)
00347   {
00348     return 0.0;
00349   }
00350 
00351   return dcmotor->thm + dcmotor->offset;
00352 }
00353 
00354 double dcmotorRunCycle(volatile DC_MOTOR_STRUCT * dcm, volatile double ea)
00355 {
00356   double A,B;
00357   double delta_thm;
00358 
00359   A=0.0;
00360   B=0.0;
00361   delta_thm=0.0;
00362 
00363   if (0 == dcm ||
00364       dcm->configured != ALL_SET)
00365     {
00366       return 0.0;
00367     }
00368 
00369   if(dcm->order == 2)
00370     {
00371       if(dcm->fourac_minus_b_squared > 0 )
00372       {
00373         /* The angular velocity  is (w) is controlled by a formula of the
00374            form:
00375 
00376            (10) w = A* e^(sa*t) + B*e^(sb*t) + ea/c
00377 
00378            sb, sa and c were previously calculated in dcmotorSetParameters.
00379            (e is ofcourse 2.7182818 ... )
00380 
00381 
00382            A and B still need to be calculated from the initial conditions.
00383 
00384            At time t = 0, e^(sa*t) = e^(sb*t) = 1, and w = wo.
00385 
00386            (11) wo = A + B + ea/c
00387 
00388            The derivative of both sides of (10);
00389 
00390            (12) w' = A*sa*e^(sa*t)+ B*sb*e^(sb*t)
00391 
00392            at time t = 0, e^(sa*t) = e^(sb*t) = 1 again, and w`=dwo.
00393 
00394            (13) dwo = A*sa + B*sb
00395 
00396            Once A and B are calculated from (13) and (11)  it is straight forward to calculate the current values of w and w' by substiting t=cycleTime in to equations 10 and 12.
00397 
00398            e^(sa*cycleTime)  and e^(sb*cycleTime)  were previously  calculated in dcmotorSetParameters and stored in sa_time_factor and sb_time_factor.
00399 
00400            To get the change in position or delta_thm, integrate (10) from 0 to time t=cycleTime.
00401 
00402         */
00403 
00404         if( (dcm->sb_real - dcm->sa_real) > 1E-15 ||
00405            (dcm->sb_real - dcm->sa_real) < -1E-15
00406          )
00407         {
00408           B = (dcm->dwo - dcm->sa_real *(dcm->wo-ea/dcm->c))/(dcm->sb_real - dcm->sa_real);
00409           A = dcm->wo -ea/dcm->c - B;
00410         }
00411         dcm->wo = A*dcm->sa_time_factor + B*dcm->sb_time_factor + ea/dcm->c;
00412         dcm->dwo = A*dcm->sa_real*dcm->sa_time_factor + B*dcm->sb_real*dcm->sb_time_factor;
00413         delta_thm = A*(dcm->sa_time_factor-1)/dcm->sa_real + B*(dcm->sb_time_factor -1)/dcm->sb_real + ea/dcm->c*dcm->cycleTime;
00414       }
00415       else if (dcm->fourac_minus_b_squared < 0)
00416       {
00417         /**
00418            The angular velocity(w) is controlled by the equation.
00419 
00420            (14) w = A*e^(sa_real*t)*cos(sa_img*t)+ B*e^(sa_real*t)*sin(sa_img*t)+ea/c
00421 
00422            sa_real, sa_img and c were calculated in dcmotorSetParameters()
00423            (e is ofcourse 2.7182818 ... )
00424 
00425            A and B still need to be calculated from the initial conditions.
00426 
00427            At time t = 0, e^(sa_real)*t = 1, cos(sa_img*t)=1, sin(sa_img*t)=0, and w = wo, so
00428 
00429            (15) wo = A*(1)*(1) + B*(1)*(0) + ea/c
00430 
00431            The derivative of both sides of (14)
00432 
00433            (16) w' = A*sa_real*e^(sa_real*t)*cos(sa_real*t)+
00434                      -A*sa_img*e^(sa_real*t)*sin(sa_real*t)+
00435                      B*sa_real*e^(sa_real*t)*sin(sa_real*t)+
00436                      A*sa_img*e^(sa_real*t)*cos(sa_real*t)
00437 
00438            At time t = 0, e^(sa_real)*t = 1, cos(sa_img*t)=1, sin(sa_img*t)=0, and w' = dwo, so
00439 
00440            (17) dwo = A*sa_real*(1)*(1) +
00441                       -A*sa_real*(1)*(0) +
00442                       B*sa_real*(1)*(0) +
00443                       B*sa_img*(1)*(1)
00444 
00445 
00446            Once A and B are calculated from (15) and (17)  it is straight forward to calculate the current values of w and w' by substiting t=cycleTime in to equations (14) and (16).
00447 
00448            e^(sa_real*cycleTime)*cos(sa_img*cycleTime)  and e^(sa_real*cycleTime)*sin(sa_img*cycleTime)  were previously  calculated in dcmotorSetParameters and stored in sa_time_factor and sb_time_factor.
00449 
00450            To get the change in position or delta_thm, integrate (14) from 0 to time t=cycleTime.
00451 
00452         */
00453         if(
00454            (dcm->sa_img > 1E-15 || dcm->sa_img < -1E-15 ) &&
00455            (dcm->c > 1E-15 || dcm->c < -1E-15 ) &&
00456            (dcm->sa_real > 1E-15 || dcm->sa_real < -1E-15 )
00457            )
00458           {
00459             A = dcm->wo-ea/dcm->c;
00460             B = (dcm->dwo-dcm->sa_real*A)/dcm->sa_img;
00461             dcm->wo = A*dcm->sa_time_factor +
00462               B*dcm->sb_time_factor +
00463               ea/dcm->c;
00464             dcm->dwo = A*dcm->sa_real*dcm->sa_time_factor -
00465               A*dcm->sa_img*dcm->sb_time_factor +
00466               B*dcm->sb_real*dcm->sb_time_factor +
00467               B*dcm->sa_img*dcm->sa_time_factor;
00468             delta_thm =
00469               A*(dcm->sa_real*dcm->sa_time_factor+
00470                  dcm->sa_img*dcm->sb_time_factor - dcm->sa_real)/
00471               (dcm->sa_real*dcm->sa_real + dcm->sa_img*dcm->sa_img) +
00472               B*(dcm->sa_real*dcm->sb_time_factor-
00473                  dcm->sa_img*dcm->sa_time_factor + dcm->sa_img)/
00474               (dcm->sa_real*dcm->sa_real + dcm->sa_img*dcm->sa_img) +
00475               (ea/dcm->c)*dcm->cycleTime;
00476           }
00477       }
00478       else
00479         {
00480           //FINISHME handle the case of fourac_minus_b_squared exactly equal zero.
00481         }
00482     }
00483   dcm->delta_thm = delta_thm;
00484   dcm->A = A;
00485   dcm->B = B;
00486   dcm->last_ea = ea;
00487   dcm->thm += delta_thm;
00488 
00489   /* return motor position */
00490 
00491   return dcm->thm + dcm->offset;
00492 }
00493 
00494 int dcmotorIniLoad(DC_MOTOR_STRUCT * dcmotor, const char * filename, const char *section)
00495 {
00496 #ifndef NO_STDIO_SUPPORT
00497 
00498   DC_MOTOR_STRUCT dcm;
00499   double cycleTime;
00500   double offset;
00501   double revsPerUnit;
00502   int retval = 0;
00503   const char *inistring;
00504   enum {TORQUE_UNITS_INVALID = 0,
00505         N_M,
00506         OZ_IN,
00507         LB_FT
00508         } torque_units;
00509 
00510 #ifndef UNDER_CE
00511   FILE *fp;
00512 
00513   if (NULL == (fp = fopen(filename, "r")))
00514   {
00515     rcs_print_error( "can't open ini file %s\n", filename);
00516     return -1;
00517   }
00518 #else
00519   INET_FILE *fp;
00520 
00521   if (NULL == (fp = inet_file_open(filename, "r")))
00522   {
00523     rcs_print_error( "can't open ini file %s\n", filename);
00524     return -1;
00525   }
00526 #endif
00527 
00528   /* look up torque units */
00529   if (NULL != (inistring = iniFind(fp, "TORQUE_UNITS", section)))
00530   {
00531     /* found the entry in the ini file */
00532     if (!strcmp(inistring, "N_M"))
00533     {
00534       torque_units = N_M;
00535     }
00536     else if (!strcmp(inistring, "LB_FT"))
00537     {
00538       torque_units = LB_FT;
00539     }
00540     else if (!strcmp(inistring, "OZ_IN"))
00541     {
00542       torque_units = OZ_IN;
00543     }
00544     else
00545     {
00546       torque_units = TORQUE_UNITS_INVALID;
00547       rcs_print_error( "bad torque units specified in ini file: %s\n",
00548               inistring);
00549       retval = -1;
00550     }
00551   }
00552   else
00553   {
00554     /* not in ini file-- use default */
00555     torque_units = N_M;
00556   }
00557 
00558   if (NULL != (inistring = iniFind(fp, "ARMATURE_RESISTANCE", section)))
00559   {
00560 #ifndef UNDER_CE
00561     if (1 != sscanf((char *) inistring, "%lf", &dcm.Ra))
00562     {
00563       /* found, but invalid */
00564       rcs_print_error( "invalid ARMATURE_RESISTANCE: %s\n", inistring);
00565       retval = -1;
00566     }
00567 #else
00568     dcm.Ra = RCS_CE_ATOF(inistring);
00569 #endif
00570   }
00571   if (NULL != (inistring = iniFind(fp, "ARMATURE_INDUCTANCE", section)))
00572   {
00573 #ifndef UNDER_CE
00574     if (1 != sscanf((char *) inistring, "%lf", &dcm.La))
00575     {
00576       /* found, but invalid */
00577       rcs_print_error( "invalid ARMATURE_INDUCTANCE: %s\n", inistring);
00578       retval = -1;
00579     }
00580 #else
00581     dcm.La = RCS_CE_ATOF(inistring);
00582 #endif
00583   }
00584   if (NULL != (inistring = iniFind(fp, "BACK_EMF_CONSTANT", section)))
00585   {
00586 #ifndef UNDER_CE
00587     if (1 != sscanf((char *) inistring, "%lf", &dcm.Kb))
00588     {
00589       /* found, but invalid */
00590       rcs_print_error( "invalid BACK_EMF_CONSTANT: %s\n", inistring);
00591       retval = -1;
00592     }
00593 #else
00594     dcm.Kb = RCS_CE_ATOF(inistring);
00595 #endif
00596   }
00597   if (NULL != (inistring = iniFind(fp, "ROTOR_INERTIA", section)))
00598   {
00599 #ifndef UNDER_CE
00600     if (1 != sscanf((char *) inistring, "%lf", &dcm.Jm))
00601     {
00602       /* found, but invalid */
00603       rcs_print_error( "invalid ROTOR_INERTIA: %s\n", inistring);
00604       retval = -1;
00605     }
00606 #else
00607     dcm.Jm = RCS_CE_ATOF(inistring);
00608 #endif
00609     switch (torque_units)
00610     {
00611     case OZ_IN:
00612       dcm.Jm *= OZ_IN_TO_N_M;
00613       break;
00614     case LB_FT:
00615       dcm.Jm *= LB_FT_TO_N_M;
00616       break;
00617     default:
00618       break;
00619     }
00620   }
00621   if (NULL != (inistring = iniFind(fp, "DAMPING_FRICTION_COEFFICIENT", section)))
00622   {
00623 #ifndef UNDER_CE
00624     if (1 != sscanf((char *) inistring, "%lf", &dcm.Bm))
00625     {
00626       /* found, but invalid */
00627       rcs_print_error( "invalid DAMPING_FRICTION_COEFFICIENT: %s\n", inistring);
00628       retval = -1;
00629     }
00630 #else
00631     dcm.Bm = RCS_CE_ATOF(inistring);
00632 #endif
00633     switch (torque_units)
00634     {
00635     case OZ_IN:
00636       dcm.Bm *= OZ_IN_TO_N_M;
00637       break;
00638     case LB_FT:
00639       dcm.Bm *= LB_FT_TO_N_M;
00640       break;
00641     default:
00642       break;
00643     }
00644   }
00645 
00646   if (retval == 0)
00647   {
00648     dcmotorSetParameters(dcmotor, dcm);
00649   }
00650 
00651   if (NULL != (inistring = iniFind(fp, "CYCLE_TIME", section)))
00652   {
00653 #ifndef UNDER_CE
00654     if (1 != sscanf((char *) inistring, "%lf", &cycleTime))
00655     {
00656       /* found, but invalid */
00657       rcs_print_error( "invalid CYCLE_TIME: %s\n", inistring);
00658       retval = -1;
00659     }
00660     else
00661     {
00662       dcmotorSetCycleTime(dcmotor, cycleTime);
00663     }
00664 #else
00665     cycleTime = RCS_CE_ATOF(inistring);
00666     dcmotorSetCycleTime(dcmotor, cycleTime);
00667 #endif
00668   }
00669 
00670   if (NULL != (inistring = iniFind(fp, "SHAFT_OFFSET", section)))
00671   {
00672 #ifndef UNDER_CE
00673     if (1 != sscanf((char *) inistring, "%lf", &offset))
00674     {
00675       /* found, but invalid */
00676       rcs_print_error( "invalid OFFSET: %s\n", inistring);
00677       retval = -1;
00678     }
00679     else
00680     {
00681       dcmotorSetOffset(dcmotor, offset);
00682     }
00683 #else
00684     offset = RCS_CE_ATOF(inistring);
00685     dcmotorSetOffset(dcmotor, offset);
00686 #endif
00687   }
00688 
00689   if (NULL != (inistring = iniFind(fp, "REVS_PER_UNIT", section)))
00690   {
00691 #ifndef UNDER_CE
00692     if (1 != sscanf((char *) inistring, "%lf", &revsPerUnit))
00693     {
00694       /* found, but invalid */
00695       rcs_print_error( "invalid REVS_PER_UNIT: %s\n", inistring);
00696       retval = -1;
00697     }
00698     else
00699     {
00700       dcmotorSetRevsPerUnit(dcmotor, revsPerUnit);
00701     }
00702 #else
00703     revsPerUnit = RCS_CE_ATOF(inistring);
00704     dcmotorSetRevsPerUnit(dcmotor, revsPerUnit);
00705 #endif
00706   }
00707 
00708   /* close inifile */
00709 #ifndef UNDER_CE
00710   fclose(fp);
00711 #else
00712   inet_file_close(fp);
00713 #endif
00714 
00715   return retval;
00716 
00717 #else
00718 
00719   return -1;
00720 
00721 #endif /* not STDIO_SUPPORT */
00722 }

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