00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <OPENR/OPENRAPI.h>
00013 #include <OPENR/OUnits.h>
00014 #include <OPENR/OSyslog.h>
00015 #include <OPENR/core_macro.h>
00016 #include "PIDControl.h"
00017
00018 PIDControl::PIDControl() : pidControlState(PCS_IDLE), pidControlInfo(),
00019 initSensorIndex(false)
00020 {
00021 for (int i = 0; i < NUM_JOINTS; i++) jointID[i] = oprimitiveID_UNDEF;
00022 for (int i = 0; i < NUM_COMMAND_VECTOR; i++) region[i] = 0;
00023 for (int i = 0; i < NUM_JOINTS; i++) sensorIndex[i] = -1;
00024 }
00025
00026 OStatus
00027 PIDControl::DoInit(const OSystemEvent& event)
00028 {
00029 OSYSDEBUG(("PIDControl::DoInit()\n"));
00030
00031 NEW_ALL_SUBJECT_AND_OBSERVER;
00032 REGISTER_ALL_ENTRY;
00033 SET_ALL_READY_AND_NOTIFY_ENTRY;
00034
00035 OpenPrimitives();
00036 NewCommandVectorData();
00037 OPENR::SetMotorPower(opowerON);
00038
00039 size_t memsize = HOLD_TIME_NUM_FRAMES*sizeof(OJointValue);
00040 logData = (OJointValue*)malloc(memsize);
00041 if (logData == 0) {
00042 OSYSLOG1((osyslogERROR, "PIDControl::DoInit() : malloc() failed."));
00043 }
00044
00045 return oSUCCESS;
00046 }
00047
00048 OStatus
00049 PIDControl::DoStart(const OSystemEvent& event)
00050 {
00051 OSYSDEBUG(("PIDControl::DoStart()\n"));
00052
00053 if (subject[sbjEffector]->IsReady() == true) {
00054 AdjustDiffJointValue();
00055 pidControlState = PCS_ADJUSTING_DIFF_JOINT_VALUE;
00056 } else {
00057 pidControlState = PCS_START;
00058 }
00059
00060 ENABLE_ALL_SUBJECT;
00061 ASSERT_READY_TO_ALL_OBSERVER;
00062
00063 return oSUCCESS;
00064 }
00065
00066 OStatus
00067 PIDControl::DoStop(const OSystemEvent& event)
00068 {
00069 OSYSDEBUG(("PIDControl::DoStop()\n"));
00070
00071 pidControlState = PCS_IDLE;
00072
00073 DISABLE_ALL_SUBJECT;
00074 DEASSERT_READY_TO_ALL_OBSERVER;
00075
00076 return oSUCCESS;
00077 }
00078
00079 OStatus
00080 PIDControl::DoDestroy(const OSystemEvent& event)
00081 {
00082 DELETE_ALL_SUBJECT_AND_OBSERVER;
00083 return oSUCCESS;
00084 }
00085
00086 void
00087 PIDControl::ReadyEffector(const OReadyEvent& event)
00088 {
00089 OSYSDEBUG(("PIDControl::Ready()\n"));
00090
00091 if (pidControlState == PCS_IDLE) {
00092
00093 OSYSDEBUG(("PCS_IDLE\n"));
00094 ;
00095
00096 } else if (pidControlState == PCS_START) {
00097
00098 OSYSDEBUG(("PCS_START\n"));
00099 AdjustDiffJointValue();
00100 pidControlState = PCS_ADJUSTING_DIFF_JOINT_VALUE;
00101
00102 } else if (pidControlState == PCS_ADJUSTING_DIFF_JOINT_VALUE) {
00103
00104 OSYSDEBUG(("PCS_ADJUSTING_DIFF_JOINT_VALUE\n"));
00105 SetJointGain();
00106 MovingResult r = MoveToBroadBase();
00107 pidControlState = PCS_MOVING_TO_BROADBASE;
00108
00109 } else if (pidControlState == PCS_MOVING_TO_BROADBASE) {
00110
00111 OSYSDEBUG(("PCS_MOVING_TO_BROADBASE\n"));
00112 MovingResult r = MoveToBroadBase();
00113 if (r == MOVING_FINISH) {
00114 pidControlState = PCS_MOVING_TO_SLEEPING;
00115 }
00116
00117 } else if (pidControlState == PCS_MOVING_TO_SLEEPING) {
00118
00119 OSYSDEBUG(("PCS_MOVING_TO_SLEEPING\n"));
00120 MovingResult r = MoveToSleeping();
00121 if (r == MOVING_FINISH) {
00122 pidControlState = PCS_DISABLE_JOINT_GAIN;
00123 }
00124
00125 } else if (pidControlState == PCS_DISABLE_JOINT_GAIN) {
00126
00127 OSYSDEBUG(("PCS_DISABLE_JOINT_GAIN\n"));
00128 DisableJointGainOfAllLegs();
00129 if (YesNo("PIDControl continue? (y/n) > ") != true) {
00130 OBootCondition bootCond(obcbPAUSE_SW);
00131 OPENR::Shutdown(bootCond);
00132 pidControlState = PCS_IDLE;
00133 return;
00134 }
00135 AdjustDiffJointValue();
00136 pidControlState = PCS_INPUT_PARAMETER;
00137
00138 } else if (pidControlState == PCS_INPUT_PARAMETER) {
00139
00140 OSYSDEBUG(("PCS_INPUT_PARAMETER\n"));
00141 SetJointGain();
00142 InputParameter();
00143 observer[obsSensor]->AssertReady();
00144 StepInput();
00145 pidControlState = PCS_STEP_INPUT;
00146
00147 } else if (pidControlState == PCS_STEP_INPUT) {
00148
00149 OSYSDEBUG(("PCS_INPUT_PARAMETER\n"));
00150 MovingResult r = StepInput();
00151 if (r == MOVING_FINISH) {
00152 SaveLogData();
00153 pidControlState = PCS_DISABLE_JOINT_GAIN;
00154 }
00155 }
00156 }
00157
00158 void
00159 PIDControl::NotifySensor(const ONotifyEvent& event)
00160 {
00161 OSensorFrameVectorData* sensorVec;
00162
00163 if (initSensorIndex == false) {
00164 sensorVec = (OSensorFrameVectorData*)event.Data(0);
00165 InitSensorIndex(sensorVec);
00166 initSensorIndex = true;
00167 observer[event.ObsIndex()]->DeassertReady();
00168 }
00169
00170 if (pidControlState == PCS_STEP_INPUT) {
00171
00172 OJointValue* log = &logData[pidControlInfo.sensorCounter];
00173 sensorVec = (OSensorFrameVectorData*)event.Data(0);
00174 int sidx = sensorIndex[pidControlInfo.jointIndex];
00175 OSensorFrameData* data = sensorVec->GetData(sidx);
00176
00177 memcpy((void*)log, (void*)data->frame,
00178 STEP_INPUT_NUM_FRAMES * sizeof(OJointValue));
00179
00180 if (pidControlInfo.sensorCounter < HOLD_TIME_NUM_FRAMES) {
00181 pidControlInfo.sensorCounter += STEP_INPUT_NUM_FRAMES;
00182 }
00183
00184 if (pidControlInfo.sensorCounter == HOLD_TIME_NUM_FRAMES) {
00185 observer[event.ObsIndex()]->DeassertReady();
00186 } else {
00187 observer[event.ObsIndex()]->AssertReady();
00188 }
00189 }
00190 }
00191
00192 void
00193 PIDControl::OpenPrimitives()
00194 {
00195 for (int i = 0; i < NUM_JOINTS; i++) {
00196 OStatus result = OPENR::OpenPrimitive(JOINT_LOCATOR[i], &jointID[i]);
00197 if (result != oSUCCESS) {
00198 OSYSLOG1((osyslogERROR, "%s : %s %d",
00199 "PIDControl::DoInit()",
00200 "OPENR::OpenPrimitive() FAILED", result));
00201 }
00202 }
00203 }
00204
00205 void
00206 PIDControl::NewCommandVectorData()
00207 {
00208 OStatus result;
00209 MemoryRegionID cmdVecDataID;
00210 OCommandVectorData* cmdVecData;
00211 OCommandInfo* info;
00212
00213 for (int i = 0; i < NUM_COMMAND_VECTOR; i++) {
00214
00215 result = OPENR::NewCommandVectorData(NUM_JOINTS,
00216 &cmdVecDataID, &cmdVecData);
00217 if (result != oSUCCESS) {
00218 OSYSLOG1((osyslogERROR, "%s : %s %d",
00219 "PIDControl::NewCommandVectorData()",
00220 "OPENR::NewCommandVectorData() FAILED", result));
00221 }
00222
00223 region[i] = new RCRegion(cmdVecData->vectorInfo.memRegionID,
00224 cmdVecData->vectorInfo.offset,
00225 (void*)cmdVecData,
00226 cmdVecData->vectorInfo.totalSize);
00227
00228 cmdVecData->SetNumData(NUM_JOINTS);
00229
00230 for (int j = 0; j < NUM_JOINTS; j++) {
00231 info = cmdVecData->GetInfo(j);
00232 info->Set(odataJOINT_COMMAND2, jointID[j], ocommandMAX_FRAMES);
00233 }
00234 }
00235 }
00236
00237 void
00238 PIDControl::SetJointGain()
00239 {
00240 OPENR::EnableJointGain(jointID[HEAD_TILT]);
00241 OPENR::SetJointGain(jointID[HEAD_TILT],
00242 TILT_PGAIN, TILT_IGAIN, TILT_DGAIN,
00243 PSHIFT, ISHIFT, DSHIFT);
00244
00245 OPENR::EnableJointGain(jointID[HEAD_PAN]);
00246 OPENR::SetJointGain(jointID[HEAD_PAN],
00247 PAN_PGAIN, PAN_IGAIN, PAN_DGAIN,
00248 PSHIFT, ISHIFT, DSHIFT);
00249
00250 OPENR::EnableJointGain(jointID[HEAD_ROLL]);
00251 OPENR::SetJointGain(jointID[HEAD_ROLL],
00252 ROLL_PGAIN, ROLL_IGAIN, ROLL_DGAIN,
00253 PSHIFT, ISHIFT, DSHIFT);
00254
00255 int base = RFLEG_J1;
00256 for (int i = 0; i < 4; i++) {
00257
00258 int j1 = base + 3 * i;
00259 int j2 = base + 3 * i + 1;
00260 int j3 = base + 3 * i + 2;
00261
00262 OPENR::EnableJointGain(jointID[j1]);
00263 OPENR::SetJointGain(jointID[j1],
00264 J1_PGAIN, J1_IGAIN, J1_DGAIN,
00265 PSHIFT, ISHIFT, DSHIFT);
00266
00267 OPENR::EnableJointGain(jointID[j2]);
00268 OPENR::SetJointGain(jointID[j2],
00269 J2_PGAIN, J2_IGAIN, J2_DGAIN,
00270 PSHIFT, ISHIFT, DSHIFT);
00271
00272 OPENR::EnableJointGain(jointID[j3]);
00273 OPENR::SetJointGain(jointID[j3],
00274 J3_PGAIN, J3_IGAIN, J3_DGAIN,
00275 PSHIFT, ISHIFT, DSHIFT);
00276 }
00277 }
00278
00279 MovingResult
00280 PIDControl::AdjustDiffJointValue()
00281 {
00282 RCRegion* rgn = FindFreeRegion();
00283 OCommandVectorData* cmdVecData = (OCommandVectorData*)rgn->Base();
00284 cmdVecData->SetNumData(NUM_JOINTS);
00285
00286 OJointValue current[NUM_JOINTS];
00287 for (int i = 0; i < NUM_JOINTS; i++) {
00288 OJointValue current;
00289 OPENR::GetJointValue(jointID[i], ¤t);
00290 SetJointValue(rgn, i,
00291 degrees(current.value/1000000.0),
00292 degrees(current.value/1000000.0));
00293 }
00294
00295 subject[sbjEffector]->SetData(rgn);
00296 subject[sbjEffector]->NotifyObservers();
00297
00298 return MOVING_FINISH;
00299 }
00300
00301 MovingResult
00302 PIDControl::MoveToBroadBase()
00303 {
00304 static int counter = -1;
00305 static double start[NUM_JOINTS];
00306 static double delta[NUM_JOINTS];
00307 double ndiv = (double)BROADBASE_MAX_COUNTER;
00308
00309 if (counter == -1) {
00310
00311 for (int i = 0; i < NUM_JOINTS; i++) {
00312 OJointValue current;
00313 OPENR::GetJointValue(jointID[i], ¤t);
00314 start[i] = degrees(current.value/1000000.0);
00315 delta[i] = (BROADBASE_ANGLE[i] - start[i]) / ndiv;
00316 }
00317
00318 counter = 0;
00319
00320 RCRegion* rgn = FindFreeRegion();
00321 for (int i = 0; i < NUM_JOINTS; i++) {
00322 SetJointValue(rgn, i, start[i], start[i] + delta[i]);
00323 start[i] += delta[i];
00324 }
00325
00326 subject[sbjEffector]->SetData(rgn);
00327 counter ++;
00328 }
00329
00330 RCRegion* rgn = FindFreeRegion();
00331 for (int i = 0; i < NUM_JOINTS; i++) {
00332 SetJointValue(rgn, i, start[i], start[i] + delta[i]);
00333 start[i] += delta[i];
00334 }
00335
00336 subject[sbjEffector]->SetData(rgn);
00337 subject[sbjEffector]->NotifyObservers();
00338
00339 counter++;
00340 return (counter == BROADBASE_MAX_COUNTER) ? MOVING_FINISH : MOVING_CONT;
00341 }
00342
00343 MovingResult
00344 PIDControl::MoveToSleeping()
00345 {
00346 static int counter = -1;
00347 static double start[NUM_JOINTS];
00348 static double delta[NUM_JOINTS];
00349 double ndiv = (double)SLEEPING_MAX_COUNTER;
00350
00351 if (counter == -1) {
00352
00353 for (int i = 0; i < NUM_JOINTS; i++) {
00354 start[i] = BROADBASE_ANGLE[i];
00355 delta[i] = (SLEEPING_ANGLE[i] - start[i]) / ndiv;
00356 }
00357
00358 counter = 0;
00359 }
00360
00361 RCRegion* rgn = FindFreeRegion();
00362 for (int i = 0; i < NUM_JOINTS; i++) {
00363 SetJointValue(rgn, i, start[i], start[i] + delta[i]);
00364 start[i] += delta[i];
00365 }
00366
00367 subject[sbjEffector]->SetData(rgn);
00368 subject[sbjEffector]->NotifyObservers();
00369
00370 counter++;
00371 return (counter == SLEEPING_MAX_COUNTER) ? MOVING_FINISH : MOVING_CONT;
00372 }
00373
00374 RCRegion*
00375 PIDControl::FindFreeRegion()
00376 {
00377 for (int i = 0; i < NUM_COMMAND_VECTOR; i++) {
00378 if (region[i]->NumberOfReference() == 1) return region[i];
00379 }
00380
00381 return 0;
00382 }
00383
00384 void
00385 PIDControl::SetJointValue(RCRegion* rgn, int idx, double start, double end)
00386 {
00387 OCommandVectorData* cmdVecData = (OCommandVectorData*)rgn->Base();
00388
00389 OCommandInfo* info = cmdVecData->GetInfo(idx);
00390 info->Set(odataJOINT_COMMAND2, jointID[idx], ocommandMAX_FRAMES);
00391
00392 OCommandData* data = cmdVecData->GetData(idx);
00393 OJointCommandValue2* jval = (OJointCommandValue2*)data->value;
00394
00395 double delta = end - start;
00396 for (int i = 0; i < ocommandMAX_FRAMES; i++) {
00397 double dval = start + (delta * i) / (double)ocommandMAX_FRAMES;
00398 jval[i].value = oradians(dval);
00399 }
00400 }
00401
00402 void
00403 PIDControl::SetJointValueForStepInput(RCRegion* rgn, int idx, double val)
00404 {
00405 OCommandVectorData* cmdVecData = (OCommandVectorData*)rgn->Base();
00406
00407 OCommandInfo* info = cmdVecData->GetInfo(0);
00408 info->Set(odataJOINT_COMMAND2, jointID[idx], STEP_INPUT_NUM_FRAMES);
00409
00410 OCommandData* data = cmdVecData->GetData(0);
00411 OJointCommandValue2* jval = (OJointCommandValue2*)data->value;
00412
00413 for (int i = 0; i < STEP_INPUT_NUM_FRAMES; i++) {
00414 jval[i].value = oradians(val);
00415 }
00416 }
00417
00418 void
00419 PIDControl::InitSensorIndex(OSensorFrameVectorData* sensorVec)
00420 {
00421 for (int i = 0; i < NUM_JOINTS; i++) {
00422 for (int j = 0; j < sensorVec->vectorInfo.numData; j++) {
00423 OSensorFrameInfo* info = sensorVec->GetInfo(j);
00424 if (info->primitiveID == jointID[i]) {
00425 sensorIndex[i] = j;
00426 OSYSDEBUG(("[%2d] %s\n", sensorIndex[i], JOINT_LOCATOR[i]));
00427 break;
00428 }
00429 }
00430 }
00431 }
00432
00433 void
00434 PIDControl::DisableJointGainOfAllLegs()
00435 {
00436 OPENR::DisableJointGain(jointID[RFLEG_J1]);
00437 OPENR::DisableJointGain(jointID[RFLEG_J2]);
00438 OPENR::DisableJointGain(jointID[RFLEG_J3]);
00439 OPENR::DisableJointGain(jointID[RRLEG_J1]);
00440 OPENR::DisableJointGain(jointID[RRLEG_J2]);
00441 OPENR::DisableJointGain(jointID[RRLEG_J3]);
00442 OPENR::DisableJointGain(jointID[LFLEG_J1]);
00443 OPENR::DisableJointGain(jointID[LFLEG_J2]);
00444 OPENR::DisableJointGain(jointID[LFLEG_J3]);
00445 OPENR::DisableJointGain(jointID[LRLEG_J1]);
00446 OPENR::DisableJointGain(jointID[LRLEG_J2]);
00447 OPENR::DisableJointGain(jointID[LRLEG_J3]);
00448 }
00449
00450 void
00451 PIDControl::InputParameter()
00452 {
00453 OSYSPRINT(("[ 0] RFLEG_J1\n"));
00454 OSYSPRINT(("[ 1] RFLEG_J2\n"));
00455 OSYSPRINT(("[ 2] RFLEG_J3\n"));
00456 OSYSPRINT(("[ 3] LFLEG_J1\n"));
00457 OSYSPRINT(("[ 4] LFLEG_J2\n"));
00458 OSYSPRINT(("[ 5] LFLEG_J3\n"));
00459 OSYSPRINT(("[ 6] RRLEG_J1\n"));
00460 OSYSPRINT(("[ 7] RRLEG_J2\n"));
00461 OSYSPRINT(("[ 8] RRLEG_J3\n"));
00462 OSYSPRINT(("[ 9] LRLEG_J1\n"));
00463 OSYSPRINT(("[10] LRLEG_J2\n"));
00464 OSYSPRINT(("[11] LRLEG_J3\n"));
00465 pidControlInfo.jointIndex = InputKey("jointIndex > ") + RFLEG_J1;
00466 pidControlInfo.pgain = InputKey("pgain > ");
00467 pidControlInfo.igain = InputKey("igain > ");
00468 pidControlInfo.dgain = InputKey("dgain > ");
00469 pidControlInfo.desiredValue = InputKey("desiredValue [deg] > ");
00470
00471 pidControlInfo.effectorCounter = 0;
00472 pidControlInfo.sensorCounter = 0;
00473
00474 OPENR::SetJointGain(jointID[pidControlInfo.jointIndex],
00475 pidControlInfo.pgain,
00476 pidControlInfo.igain,
00477 pidControlInfo.dgain,
00478 PSHIFT, ISHIFT, DSHIFT);
00479 }
00480
00481 MovingResult
00482 PIDControl::StepInput()
00483 {
00484 RCRegion* rgn = FindFreeRegion();
00485 OCommandVectorData* cmdVecData = (OCommandVectorData*)rgn->Base();
00486
00487 cmdVecData->SetNumData(1);
00488 SetJointValueForStepInput(rgn, pidControlInfo.jointIndex,
00489 (double)pidControlInfo.desiredValue);
00490
00491 subject[sbjEffector]->SetData(rgn);
00492 subject[sbjEffector]->NotifyObservers();
00493
00494 if (pidControlInfo.effectorCounter < HOLD_TIME_NUM_FRAMES) {
00495 pidControlInfo.effectorCounter += STEP_INPUT_NUM_FRAMES;
00496 }
00497
00498 if (pidControlInfo.effectorCounter == HOLD_TIME_NUM_FRAMES &&
00499 pidControlInfo.sensorCounter == HOLD_TIME_NUM_FRAMES) {
00500 return MOVING_FINISH;
00501 } else {
00502 return MOVING_CONT;
00503 }
00504 }
00505
00506 bool
00507 PIDControl::YesNo(const char* prompt)
00508 {
00509 char line[80];
00510
00511 while (1) {
00512 OSYSPRINT(("%s", prompt));
00513 gets(line);
00514 if (strcmp(line, "y") == 0) return true;
00515 if (strcmp(line, "n") == 0) return false;
00516 }
00517 }
00518
00519 int
00520 PIDControl::InputKey(const char* prompt)
00521 {
00522 OSYSPRINT(("%s", prompt));
00523 char line[80];
00524 gets(line);
00525 return strtol(line, (char**)NULL, 0);
00526 }
00527
00528 void
00529 PIDControl::SaveLogData()
00530 {
00531 char file[16];
00532 char path[128];
00533
00534 OSYSPRINT(("filename > "));
00535 gets(file);
00536 sprintf(path, "/MS/OPEN-R/MW/DATA/P/%s", file);
00537
00538 FILE* fp = fopen(path, "w");
00539 if (fp == 0) {
00540 OSYSLOG1((osyslogERROR, "fopen() : can't open %s", path));
00541 return;
00542 }
00543
00544 for (int i = 0; i < HOLD_TIME_NUM_FRAMES; i++) {
00545 fprintf(fp, "%f\t%f\t%d\n",
00546 degrees(logData[i].value / 1000000.0),
00547 degrees(logData[i].refValue / 1000000.0),
00548 logData[i].pwmDuty);
00549 }
00550
00551 fclose(fp);
00552 }