PIDControl.cc

Go to the documentation of this file.
00001 //
00002 // Copyright 2002,2004 Sony Corporation 
00003 //
00004 // Permission to use, copy, modify, and redistribute this software for
00005 // non-commercial use is hereby granted.
00006 //
00007 // This software is provided "as is" without warranty of any kind,
00008 // either expressed or implied, including but not limited to the
00009 // implied warranties of fitness for a particular purpose.
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         ; // do nothing
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], &current);
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], &current);
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 }

Generated on Sun Dec 2 23:04:30 2007 for openSDK by  doxygen 1.3.9.1