00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef NO_STDIO_SUPPORT
00035 #ifdef UNDER_CE
00036 #include "rcs_ce.h"
00037 #else
00038 #include <stdio.h>
00039 #endif
00040 #include "inetfile.hh"
00041 #include "inifile.h"
00042 #include "rcs_prnt.hh"
00043 #include <string.h>
00044 #include "inifile.h"
00045 #endif
00046 #include "dcmotor2.h"
00047 #include <math.h>
00048
00049
00050
00051
00052 #ifndef __GNUC__
00053 #ifndef __attribute__
00054 #define __attribute__(x)
00055 #endif
00056 #endif
00057
00058
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
00068
00069
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
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
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
00095 return dcmotorResetState(dcmotor);
00096 }
00097
00098 int dcmotorResetState(DC_MOTOR_STRUCT * dcmotor)
00099 {
00100
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
00119 dcmotor->cycleTime = seconds;
00120 dcmotor->configured |= CYCLE_TIME_SET;
00121
00122
00123 if(dcmotor->configured & PARAMETERS_SET)
00124 {
00125
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
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
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
00268 retval.Ra=0;
00269 retval.La=0;
00270 retval.Kb=0;
00271 retval.Jm=0;
00272 retval.Bm=0;
00273
00274
00275 retval.ia=0;
00276 retval.dia=0;
00277 retval.wm=0;
00278 retval.dwm=0;
00279 retval.thm=0;
00280 retval.dthm=0;
00281 retval.lastTime=0;
00282
00283
00284 retval.configured=0;
00285 retval.cycleTime=0;
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
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
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
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
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
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
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
00529 if (NULL != (inistring = iniFind(fp, "TORQUE_UNITS", section)))
00530 {
00531
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
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
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
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
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
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
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
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
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
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
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
00722 }