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
00035
00036 #ifndef NO_STDIO_SUPPORT
00037 #ifdef UNDER_CE
00038 #include "rcs_ce.h"
00039 #else
00040 #include <stdio.h>
00041 #endif
00042 #include "inetfile.hh"
00043 #include "inifile.h"
00044 #include "rcs_prnt.hh"
00045 #include <string.h>
00046 #endif
00047 #include "dcmotor.h"
00048
00049
00050 #ifndef __GNUC__
00051 #ifndef __attribute__
00052 #define __attribute__(x)
00053 #endif
00054 #endif
00055
00056 static char __attribute__((unused)) ident[] = "$Id: 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
00065
00066
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
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
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
00092 return dcmotorResetState(dcmotor);
00093 }
00094
00095 int dcmotorResetState(DC_MOTOR_STRUCT * dcmotor)
00096 {
00097
00098 dcmotor->ia = 0.0;
00099 dcmotor->dia = 0.0;
00100 dcmotor->wm = 0.0;
00101 dcmotor->dwm = 0.0;
00102 dcmotor->thm = 0.0;
00103 dcmotor->dthm = 0.0;
00104
00105 return 0;
00106 }
00107
00108 int dcmotorSetCycleTime(DC_MOTOR_STRUCT * dcmotor, double seconds)
00109 {
00110 if (0 == dcmotor)
00111 {
00112 return -1;
00113 }
00114
00115
00116 dcmotor->cycleTime = seconds;
00117 dcmotor->configured |= CYCLE_TIME_SET;
00118
00119 return 0;
00120 }
00121
00122 double dcmotorGetCycleTime(DC_MOTOR_STRUCT * dcmotor)
00123 {
00124 if (0 == dcmotor ||
00125 ! (dcmotor->configured & CYCLE_TIME_SET))
00126 {
00127 return 0.0;
00128 }
00129
00130 return dcmotor->cycleTime;
00131 }
00132
00133 int dcmotorSetParameters(DC_MOTOR_STRUCT * dcmotor, DC_MOTOR_STRUCT params)
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 }
00150
00151 DC_MOTOR_STRUCT dcmotorGetParameters(DC_MOTOR_STRUCT * dcmotor)
00152 {
00153 DC_MOTOR_STRUCT retval;
00154
00155 if (0 == dcmotor)
00156 {
00157
00158 retval.Ra=0;
00159 retval.La=0;
00160 retval.Kb=0;
00161 retval.Jm=0;
00162 retval.Bm=0;
00163
00164
00165 retval.ia=0;
00166 retval.dia=0;
00167 retval.wm=0;
00168 retval.dwm=0;
00169 retval.thm=0;
00170 retval.dthm=0;
00171 retval.lastTime=0;
00172
00173
00174 retval.configured=0;
00175 retval.cycleTime=0;
00176 retval.offset=0;
00177 retval.revsPerUnit=0;
00178 return retval;
00179 }
00180
00181 return *dcmotor;
00182 }
00183
00184 int dcmotorSetOffset(DC_MOTOR_STRUCT * dcmotor, double _offset)
00185 {
00186 if (0 == dcmotor)
00187 {
00188 return -1;
00189 }
00190
00191 dcmotor->offset = _offset;
00192 dcmotor->configured |= OFFSET_SET;
00193
00194 return 0;
00195 }
00196
00197 double dcmotorGetOffset(DC_MOTOR_STRUCT * dcmotor)
00198 {
00199 if (0 == dcmotor ||
00200 ! (dcmotor->configured & OFFSET_SET))
00201 {
00202 return 0.0;
00203 }
00204
00205 return dcmotor->offset;
00206 }
00207
00208 int dcmotorSetRevsPerUnit(DC_MOTOR_STRUCT * dcmotor, double _revsPerUnit)
00209 {
00210 if (0 == dcmotor ||
00211 _revsPerUnit <= 0.0)
00212 {
00213 return -1;
00214 }
00215
00216 dcmotor->revsPerUnit = _revsPerUnit;
00217 dcmotor->configured |= REVS_PER_UNIT_SET;
00218
00219 return 0;
00220 }
00221
00222 double dcmotorGetRevsPerUnit(DC_MOTOR_STRUCT * dcmotor)
00223 {
00224 if (0 == dcmotor ||
00225 ! (dcmotor->configured & REVS_PER_UNIT_SET))
00226 {
00227 return 0.0;
00228 }
00229
00230 return dcmotor->revsPerUnit;
00231 }
00232
00233 double dcmotorGetOutput(DC_MOTOR_STRUCT * dcmotor)
00234 {
00235 if (0 == dcmotor ||
00236 dcmotor->configured != ALL_SET)
00237 {
00238 return 0.0;
00239 }
00240
00241 return dcmotor->thm + dcmotor->offset;
00242 }
00243
00244 double dcmotorRunCycle(volatile DC_MOTOR_STRUCT * dcm, volatile double ea)
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
00256 if (dcm->cycleTime <= 0.0)
00257 {
00258
00259 if (dcm->lastTime <= 0.0)
00260 {
00261
00262 dcm->lastTime = 0.0;
00263 deltaT = 0.0;
00264 }
00265 else
00266 {
00267
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
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;
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
00323
00324 dcm->ia += dcm->dia;
00325 dcm->wm += dcm->dwm;
00326 dcm->thm += dcm->dthm;
00327
00328
00329
00330 return dcm->thm + dcm->offset;
00331 }
00332
00333 int dcmotorIniLoad(DC_MOTOR_STRUCT * dcmotor, const char * filename, const char *section)
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
00368 if (NULL != (inistring = iniFind(fp, "TORQUE_UNITS", section)))
00369 {
00370
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
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
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
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
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
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
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
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
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
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
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
00561 }