#include <stdio.h>#include "inetfile.hh"#include "inifile.h"#include "rcs_prnt.hh"#include <string.h>#include "dcmotor.h"Include dependency graph for dcmotor.c:

Go to the source code of this file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 56 of file dcmotor.c. 00056 : dcmotor.c,v 1.3 2000/10/27 20:34:42 terrylr Exp $"; 00057 00058 #define PARAMETERS_SET 0x01 00059 #define CYCLE_TIME_SET 0x02 00060 #define OFFSET_SET 0x04 00061 #define REVS_PER_UNIT_SET 0x08 00062 #define ALL_SET (PARAMETERS_SET | CYCLE_TIME_SET | OFFSET_SET | REVS_PER_UNIT_SET) 00063 00064 /* Conversion factors */ 00065 /* oz-in * 0.00708 = newton-meters */ 00066 /* foot-pounds * 1.359 = newton-meters */ 00067 #define OZ_IN_TO_N_M 0.00708 00068 #define LB_FT_TO_N_M 1.359 00069 00070 int dcmotorInit(DC_MOTOR_STRUCT * dcmotor) 00071 { 00072 if (0 == dcmotor) 00073 { 00074 return -1; 00075 } 00076 00077 /* parameters */ 00078 dcmotor->Ra = 0.0; 00079 dcmotor->La = 0.0; 00080 dcmotor->Kb = 0.0; 00081 dcmotor->Jm = 0.0; 00082 dcmotor->Bm = 0.0; 00083 00084 /* internal vars */ 00085 dcmotor->configured = 0; 00086 dcmotor->cycleTime = 0.0; 00087 dcmotor->offset = 0.0; 00088 dcmotor->revsPerUnit = 0.0; 00089 dcmotor->lastTime = -1.0; 00090 00091 /* state vars */ 00092 return dcmotorResetState(dcmotor); 00093 } |
|
|
|
|
|
|
|
|
|
|
|
Definition at line 151 of file dcmotor.c. 00152 {
00153 DC_MOTOR_STRUCT retval;
00154
00155 if (0 == dcmotor)
00156 {
00157 /* parameters */
00158 retval.Ra=0; /* armature resistance, ohms */
00159 retval.La=0; /* armature inductance, henries */
00160 retval.Kb=0; /* back emf constant, V/rad/s, N-m/amp */
00161 retval.Jm=0; /* motor rotor inertia, N-m-s^2 */
00162 retval.Bm=0; /* viscous friction coefficient, N-m/rad/sec */
00163
00164 /* state vars */
00165 retval.ia=0; /* armature current */
00166 retval.dia=0; /* derivative of above */
00167 retval.wm=0; /* angular velocity of motor */
00168 retval.dwm=0; /* derivative of above */
00169 retval.thm=0; /* angular position of motor */
00170 retval.dthm=0; /* derivative of above */
00171 retval.lastTime=0; /* timestamp of last cycle */
00172
00173 /* internal vars */
00174 retval.configured=0;
00175 retval.cycleTime=0; /* copy of arg to setCycleTime() */
00176 retval.offset=0;
00177 retval.revsPerUnit=0;
00178 return retval;
00179 }
00180
00181 return *dcmotor;
00182 }
|
|
|
|
|
||||||||||||||||
|
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 333 of file dcmotor.c. 00334 {
00335 #ifndef NO_STDIO_SUPPORT
00336
00337 DC_MOTOR_STRUCT dcm;
00338 double cycleTime;
00339 double offset;
00340 double revsPerUnit;
00341 int retval = 0;
00342 const char *inistring;
00343 enum {TORQUE_UNITS_INVALID = 0,
00344 N_M,
00345 OZ_IN,
00346 LB_FT
00347 } torque_units;
00348
00349 #ifndef UNDER_CE
00350 FILE *fp;
00351
00352 if (NULL == (fp = fopen(filename, "r")))
00353 {
00354 rcs_print_error( "can't open ini file %s\n", filename);
00355 return -1;
00356 }
00357 #else
00358 INET_FILE *fp;
00359
00360 if (NULL == (fp = inet_file_open(filename, "r")))
00361 {
00362 rcs_print_error( "can't open ini file %s\n", filename);
00363 return -1;
00364 }
00365 #endif
00366
00367 /* look up torque units */
00368 if (NULL != (inistring = iniFind(fp, "TORQUE_UNITS", section)))
00369 {
00370 /* found the entry in the ini file */
00371 if (!strcmp(inistring, "N_M"))
00372 {
00373 torque_units = N_M;
00374 }
00375 else if (!strcmp(inistring, "LB_FT"))
00376 {
00377 torque_units = LB_FT;
00378 }
00379 else if (!strcmp(inistring, "OZ_IN"))
00380 {
00381 torque_units = OZ_IN;
00382 }
00383 else
00384 {
00385 torque_units = TORQUE_UNITS_INVALID;
00386 rcs_print_error( "bad torque units specified in ini file: %s\n",
00387 inistring);
00388 retval = -1;
00389 }
00390 }
00391 else
00392 {
00393 /* not in ini file-- use default */
00394 torque_units = N_M;
00395 }
00396
00397 if (NULL != (inistring = iniFind(fp, "ARMATURE_RESISTANCE", section)))
00398 {
00399 #ifndef UNDER_CE
00400 if (1 != sscanf((char *) inistring, "%lf", &dcm.Ra))
00401 {
00402 /* found, but invalid */
00403 rcs_print_error( "invalid ARMATURE_RESISTANCE: %s\n", inistring);
00404 retval = -1;
00405 }
00406 #else
00407 dcm.Ra = RCS_CE_ATOF(inistring);
00408 #endif
00409 }
00410 if (NULL != (inistring = iniFind(fp, "ARMATURE_INDUCTANCE", section)))
00411 {
00412 #ifndef UNDER_CE
00413 if (1 != sscanf((char *) inistring, "%lf", &dcm.La))
00414 {
00415 /* found, but invalid */
00416 rcs_print_error( "invalid ARMATURE_INDUCTANCE: %s\n", inistring);
00417 retval = -1;
00418 }
00419 #else
00420 dcm.La = RCS_CE_ATOF(inistring);
00421 #endif
00422 }
00423 if (NULL != (inistring = iniFind(fp, "BACK_EMF_CONSTANT", section)))
00424 {
00425 #ifndef UNDER_CE
00426 if (1 != sscanf((char *) inistring, "%lf", &dcm.Kb))
00427 {
00428 /* found, but invalid */
00429 rcs_print_error( "invalid BACK_EMF_CONSTANT: %s\n", inistring);
00430 retval = -1;
00431 }
00432 #else
00433 dcm.Kb = RCS_CE_ATOF(inistring);
00434 #endif
00435 }
00436 if (NULL != (inistring = iniFind(fp, "ROTOR_INERTIA", section)))
00437 {
00438 #ifndef UNDER_CE
00439 if (1 != sscanf((char *) inistring, "%lf", &dcm.Jm))
00440 {
00441 /* found, but invalid */
00442 rcs_print_error( "invalid ROTOR_INERTIA: %s\n", inistring);
00443 retval = -1;
00444 }
00445 #else
00446 dcm.Jm = RCS_CE_ATOF(inistring);
00447 #endif
00448 switch (torque_units)
00449 {
00450 case OZ_IN:
00451 dcm.Jm *= OZ_IN_TO_N_M;
00452 break;
00453 case LB_FT:
00454 dcm.Jm *= LB_FT_TO_N_M;
00455 break;
00456 default:
00457 break;
00458 }
00459 }
00460 if (NULL != (inistring = iniFind(fp, "DAMPING_FRICTION_COEFFICIENT", section)))
00461 {
00462 #ifndef UNDER_CE
00463 if (1 != sscanf((char *) inistring, "%lf", &dcm.Bm))
00464 {
00465 /* found, but invalid */
00466 rcs_print_error( "invalid DAMPING_FRICTION_COEFFICIENT: %s\n", inistring);
00467 retval = -1;
00468 }
00469 #else
00470 dcm.Bm = RCS_CE_ATOF(inistring);
00471 #endif
00472 switch (torque_units)
00473 {
00474 case OZ_IN:
00475 dcm.Bm *= OZ_IN_TO_N_M;
00476 break;
00477 case LB_FT:
00478 dcm.Bm *= LB_FT_TO_N_M;
00479 break;
00480 default:
00481 break;
00482 }
00483 }
00484
00485 if (retval == 0)
00486 {
00487 dcmotorSetParameters(dcmotor, dcm);
00488 }
00489
00490 if (NULL != (inistring = iniFind(fp, "CYCLE_TIME", section)))
00491 {
00492 #ifndef UNDER_CE
00493 if (1 != sscanf((char *) inistring, "%lf", &cycleTime))
00494 {
00495 /* found, but invalid */
00496 rcs_print_error( "invalid CYCLE_TIME: %s\n", inistring);
00497 retval = -1;
00498 }
00499 else
00500 {
00501 dcmotorSetCycleTime(dcmotor, cycleTime);
00502 }
00503 #else
00504 cycleTime = RCS_CE_ATOF(inistring);
00505 dcmotorSetCycleTime(dcmotor, cycleTime);
00506 #endif
00507 }
00508
00509 if (NULL != (inistring = iniFind(fp, "SHAFT_OFFSET", section)))
00510 {
00511 #ifndef UNDER_CE
00512 if (1 != sscanf((char *) inistring, "%lf", &offset))
00513 {
00514 /* found, but invalid */
00515 rcs_print_error( "invalid OFFSET: %s\n", inistring);
00516 retval = -1;
00517 }
00518 else
00519 {
00520 dcmotorSetOffset(dcmotor, offset);
00521 }
00522 #else
00523 offset = RCS_CE_ATOF(inistring);
00524 dcmotorSetOffset(dcmotor, offset);
00525 #endif
00526 }
00527
00528 if (NULL != (inistring = iniFind(fp, "REVS_PER_UNIT", section)))
00529 {
00530 #ifndef UNDER_CE
00531 if (1 != sscanf((char *) inistring, "%lf", &revsPerUnit))
00532 {
00533 /* found, but invalid */
00534 rcs_print_error( "invalid REVS_PER_UNIT: %s\n", inistring);
00535 retval = -1;
00536 }
00537 else
00538 {
00539 dcmotorSetRevsPerUnit(dcmotor, revsPerUnit);
00540 }
00541 #else
00542 revsPerUnit = RCS_CE_ATOF(inistring);
00543 dcmotorSetRevsPerUnit(dcmotor, revsPerUnit);
00544 #endif
00545 }
00546
00547 /* close inifile */
00548 #ifndef UNDER_CE
00549 fclose(fp);
00550 #else
00551 inet_file_close(fp);
00552 #endif
00553
00554 return retval;
00555
00556 #else
00557
00558 return -1;
00559
00560 #endif /* not STDIO_SUPPORT */
00561 }
|
|
|
|
|
||||||||||||
|
Definition at line 244 of file dcmotor.c. 00245 {
00246 volatile double deltaT;
00247 volatile double now;
00248
00249 if (0 == dcm ||
00250 dcm->configured != ALL_SET)
00251 {
00252 return 0.0;
00253 }
00254
00255 /* calculate deltaT */
00256 if (dcm->cycleTime <= 0.0)
00257 {
00258 /* if cycleTime <= 0.0, we want to use real time stamps */
00259 if (dcm->lastTime <= 0.0)
00260 {
00261 /* first time through */
00262 dcm->lastTime = 0.0;
00263 deltaT = 0.0; /* results will all be zero */
00264 }
00265 else
00266 {
00267 /* FIXME-- get current time in 'now', instead of 0 */
00268 now = 0.0;
00269 deltaT = now - dcm->lastTime;
00270 dcm->lastTime = now;
00271 }
00272 }
00273 else
00274 {
00275 deltaT = dcm->cycleTime;
00276 }
00277
00278 /* calculate differentials */
00279
00280 if(dcm->La != 0.0)
00281 {
00282 dcm->dia = deltaT *
00283 (-dcm->Ra * dcm->ia -
00284 dcm->Kb * dcm->wm +
00285 ea) / dcm->La;
00286 }
00287 else if (dcm->Ra != 0.0)
00288 {
00289 dcm->dia = (ea - dcm->Kb * dcm->wm)/dcm->Ra - dcm->ia;
00290 }
00291 else
00292 {
00293 dcm->dia = -dcm->ia;
00294 if(dcm->Kb != 0.0)
00295 {
00296 dcm->wm = ea/dcm->Kb;
00297 }
00298 else
00299 {
00300 dcm->wm = 0.0;
00301 }
00302 }
00303
00304 if(dcm->Jm != 0.0)
00305 {
00306 dcm->dwm = deltaT *
00307 (dcm->Kb * dcm->ia -
00308 dcm->Bm * dcm->wm) / dcm->Jm; /* Ki == Kb, Tl = 0 */
00309 }
00310 else if(dcm->Bm != 0.0)
00311 {
00312 dcm->dwm = (dcm->Kb * dcm->ia)/dcm->Bm - dcm->wm;
00313 }
00314 else
00315 {
00316 dcm->dwm = -dcm->wm;
00317 dcm->ia = 0.0;
00318 }
00319
00320 dcm->dthm = deltaT * dcm->wm;
00321
00322 /* update state vars with differentials */
00323
00324 dcm->ia += dcm->dia;
00325 dcm->wm += dcm->dwm;
00326 dcm->thm += dcm->dthm;
00327
00328 /* return motor position */
00329
00330 return dcm->thm + dcm->offset;
00331 }
|
|
||||||||||||
|
|
|
||||||||||||
|
|
|
||||||||||||
|
Definition at line 133 of file dcmotor.c. 00134 {
00135 if (0 == dcmotor)
00136 {
00137 return -1;
00138 }
00139
00140 dcmotor->Ra = params.Ra;
00141 dcmotor->La = params.La;
00142 dcmotor->Kb = params.Kb;
00143 dcmotor->Jm = params.Jm;
00144 dcmotor->Bm = params.Bm;
00145
00146 dcmotor->configured |= PARAMETERS_SET;
00147
00148 return 0;
00149 }
|
|
||||||||||||
|
|
1.2.11.1 written by Dimitri van Heesch,
© 1997-2001