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

dcmotor.h File Reference

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Defines

#define __attribute__(x)

Functions

char __attribute__ ((unused)) dcmotor_h[]="$Id
int dcmotorInit (DC_MOTOR_STRUCT *dcmotor)
int dcmotorResetState (DC_MOTOR_STRUCT *dcmotor)
int dcmotorSetCycleTime (DC_MOTOR_STRUCT *dcmotor, double seconds)
double dcmotorGetCycleTime (DC_MOTOR_STRUCT *dcmotor)
int dcmotorSetParameters (DC_MOTOR_STRUCT *dcmotor, DC_MOTOR_STRUCT params)
DC_MOTOR_STRUCT dcmotorGetParameters (DC_MOTOR_STRUCT *dcmotor)
int dcmotorSetOffset (DC_MOTOR_STRUCT *dcmotor, double _offset)
double dcmotorGetOffset (DC_MOTOR_STRUCT *dcmotor)
int dcmotorSetRevsPerUnit (DC_MOTOR_STRUCT *dcmotor, double _revsPerUnit)
double dcmotorGetRevsPerUnit (DC_MOTOR_STRUCT *dcmotor)
double dcmotorGetOutput (DC_MOTOR_STRUCT *dcmotor)
double dcmotorRunCycle (volatile DC_MOTOR_STRUCT *dcmotor, volatile double ea)
int dcmotorIniLoad (DC_MOTOR_STRUCT *dcmotor, const char *filename, const char *section)

Variables

 DC_MOTOR_STRUCT


Define Documentation

#define __attribute__  
 

Definition at line 38 of file dcmotor.h.


Function Documentation

char __attribute__ (unused)    [static]
 

Definition at line 42 of file dcmotor.h.

00042                                                       : dcmotor.h,v 1.2 2000/10/27 20:34:42 terrylr Exp $";
00043 
00044 typedef struct
00045 {
00046   /* parameters */
00047   double Ra;                    /* armature resistance, ohms */
00048   double La;                    /* armature inductance, henries */
00049   double Kb;                    /* back emf constant, V/rad/s, N-m/amp */
00050   double Jm;                    /* motor rotor inertia, N-m-s^2 */
00051   double Bm;                    /* viscous friction coefficient, N-m/rad/sec */
00052 
00053   /* state vars */
00054   double ia;                    /* armature current */
00055   double dia;                   /* derivative of above */
00056   double wm;                    /* angular velocity of motor */
00057   double dwm;                   /* derivative of above */
00058   double thm;                   /* angular position of motor */
00059   double dthm;                  /* derivative of above */
00060   double lastTime;              /* timestamp of last cycle */
00061 
00062   /* internal vars */
00063   int configured;
00064   double cycleTime;             /* copy of arg to setCycleTime() */
00065   double offset;
00066   double revsPerUnit;
00067 
00068 } DC_MOTOR_STRUCT;

double dcmotorGetCycleTime DC_MOTOR_STRUCT   dcmotor
 

Definition at line 132 of file dcmotor2.c.

00133 {
00134   if (0 == dcmotor ||
00135       ! (dcmotor->configured & CYCLE_TIME_SET))
00136   {
00137     return 0.0;
00138   }
00139 
00140   return dcmotor->cycleTime;
00141 }

double dcmotorGetOffset DC_MOTOR_STRUCT   dcmotor
 

Definition at line 307 of file dcmotor2.c.

00308 {
00309   if (0 == dcmotor ||
00310       ! (dcmotor->configured & OFFSET_SET))
00311   {
00312     return 0.0;
00313   }
00314 
00315   return dcmotor->offset;
00316 }

double dcmotorGetOutput DC_MOTOR_STRUCT   dcmotor
 

Definition at line 343 of file dcmotor2.c.

00344 {
00345   if (0 == dcmotor ||
00346       dcmotor->configured != ALL_SET)
00347   {
00348     return 0.0;
00349   }
00350 
00351   return dcmotor->thm + dcmotor->offset;
00352 }

DC_MOTOR_STRUCT dcmotorGetParameters DC_MOTOR_STRUCT   dcmotor
 

Definition at line 261 of file dcmotor2.c.

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 }

double dcmotorGetRevsPerUnit DC_MOTOR_STRUCT   dcmotor
 

Definition at line 332 of file dcmotor2.c.

00333 {
00334   if (0 == dcmotor ||
00335       ! (dcmotor->configured & REVS_PER_UNIT_SET))
00336   {
00337     return 0.0;
00338   }
00339 
00340   return dcmotor->revsPerUnit;
00341 }

int dcmotorIniLoad DC_MOTOR_STRUCT   dcmotor,
const char *    filename,
const char *    section
 

The angular velocity(w) is controlled by the equation.

(14) w = A*e^(sa_real*t)*cos(sa_img*t)+ B*e^(sa_real*t)*sin(sa_img*t)+ea/c

sa_real, sa_img and c were calculated in dcmotorSetParameters() (e is ofcourse 2.7182818 ... )

A and B still need to be calculated from the initial conditions.

At time t = 0, e^(sa_real)*t = 1, cos(sa_img*t)=1, sin(sa_img*t)=0, and w = wo, so

(15) wo = A*(1)*(1) + B*(1)*(0) + ea/c

The derivative of both sides of (14)

(16) w' = A*sa_real*e^(sa_real*t)*cos(sa_real*t)+ -A*sa_img*e^(sa_real*t)*sin(sa_real*t)+ B*sa_real*e^(sa_real*t)*sin(sa_real*t)+ A*sa_img*e^(sa_real*t)*cos(sa_real*t)

At time t = 0, e^(sa_real)*t = 1, cos(sa_img*t)=1, sin(sa_img*t)=0, and w' = dwo, so

(17) dwo = A*sa_real*(1)*(1) + -A*sa_real*(1)*(0) + B*sa_real*(1)*(0) + B*sa_img*(1)*(1)

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).

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.

To get the change in position or delta_thm, integrate (14) from 0 to time t=cycleTime.

Definition at line 494 of file dcmotor2.c.

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 }

int dcmotorInit DC_MOTOR_STRUCT   dcmotor
 

int dcmotorResetState DC_MOTOR_STRUCT   dcmotor
 

Definition at line 98 of file dcmotor2.c.

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 }

double dcmotorRunCycle volatile DC_MOTOR_STRUCT   dcmotor,
volatile double    ea
 

Definition at line 354 of file dcmotor2.c.

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 }

int dcmotorSetCycleTime DC_MOTOR_STRUCT   dcmotor,
double    seconds
 

Definition at line 111 of file dcmotor2.c.

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 }

int dcmotorSetOffset DC_MOTOR_STRUCT   dcmotor,
double    _offset
 

Definition at line 294 of file dcmotor2.c.

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 }

int dcmotorSetParameters DC_MOTOR_STRUCT   dcmotor,
DC_MOTOR_STRUCT    params
 

Definition at line 143 of file dcmotor2.c.

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 }

int dcmotorSetRevsPerUnit DC_MOTOR_STRUCT   dcmotor,
double    _revsPerUnit
 

Definition at line 318 of file dcmotor2.c.

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 }


Variable Documentation

DC_MOTOR_STRUCT
 

Definition at line 68 of file dcmotor.h.


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