Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

WorldState.cc

Go to the documentation of this file.
00001 #include "WorldState.h"
00002 #include "Shared/get_time.h"
00003 #include "Events/EventRouter.h"
00004 #include "ERS210Info.h"
00005 #include "ERS220Info.h"
00006 #include "ERS7Info.h"
00007 #include "Shared/Config.h"
00008 #include "IPC/ProcessID.h"
00009 
00010 #ifdef PLATFORM_APERIOS
00011 #  include <OPENR/core_macro.h>
00012 #  include <OPENR/ObjcommTypes.h>
00013 #  include <OPENR/OPENR.h>
00014 #  include <OPENR/OPENRAPI.h>
00015 #  include <OPENR/OPENRMessages.h>
00016 #  include <OPENR/OPower.h>
00017 #else
00018 #  include "Motion/PostureEngine.h"
00019 #endif
00020 
00021 #define GETD(cpc) (((float)sensor.GetData(cpc)->frame[lastFrame].value) / 1.0E6f) //!< returns value from OPEN-R, converted from micro in int to base in float
00022 #define GETB(cpc) ((bool)sensor.GetData(cpc)->frame[lastFrame].value) //!< returns value from OPEN-R, as bool
00023 #define GETSENSOR(cpc) ((float)sensor.GetData(cpc)->frame[lastFrame].value) //!< return value from OPEN-R, as int
00024 #define GETSIG(cpc) ((word)sensor.GetData(cpc)->frame[lastFrame].signal) //!< returns signal from OPEN-R as word
00025 #define GETDUTY(cpc) ((float)((OJointValue*)&sensor.GetData(cpc)->frame[lastFrame])->pwmDuty/512.0f) //!< returns duty cycle from OPEN-R as float; -1 (full reverse) to 0 (idle) to 1 (full forward)
00026 
00027 const double WorldState::g=9.80665;
00028 const double WorldState::IROORDist = 900.0;
00029 
00030 #ifdef PLATFORM_APERIOS
00031 WorldState ** WorldState::stateLookupMap=NULL;
00032 #endif
00033 
00034 WorldState * state=NULL;
00035 
00036 WorldState::WorldState()
00037   : alwaysGenerateStatus(false), vel_x(0), vel_y(0), vel_a(0), vel_time(0),
00038     robotStatus(0), batteryStatus(0),
00039     lastSensorUpdateTime(0), frameNumber(1), framesProcessed(0),
00040     robotDesign(0), curtime(0)
00041 {
00042   for(unsigned int i=0; i< NumOutputs; i++)
00043     outputs[i]=0;
00044   for(unsigned int i=0; i< NumButtons; i++)
00045     buttons[i]=0;
00046   for(unsigned int i=0; i< NumSensors; i++)
00047     sensors[i]=0;
00048   for(unsigned int i=0; i< NumPIDJoints; i++)
00049     for(unsigned int j=0; j<3; j++)
00050       pids[i][j]=0;
00051   for(unsigned int i=0; i< NumPIDJoints; i++)
00052     pidduties[i]=0;
00053   memset(powerFlags,0,sizeof(unsigned int)*PowerSourceID::NumPowerSIDs);
00054   memset(button_times,0,sizeof(unsigned int)*NumButtons);
00055 
00056 #ifdef PLATFORM_APERIOS
00057   //Thanks Daishi:
00058   char robotDesignStr[orobotdesignNAME_MAX + 1];
00059   memset(robotDesignStr, 0, sizeof(robotDesignStr));
00060   if (OPENR::GetRobotDesign(robotDesignStr) != oSUCCESS) {
00061     cout << "OPENR::GetRobotDesign() failed." << endl;
00062   } else {
00063     if(strcmp(robotDesignStr,"ERS-210")==0)
00064       robotDesign=ERS210Mask;
00065     else if(strcmp(robotDesignStr,"ERS-220")==0)
00066       robotDesign=ERS220Mask;
00067     else if(strcmp(robotDesignStr,"ERS-7")==0)
00068       robotDesign=ERS7Mask;
00069     else {
00070       cout << "ERROR: Unrecognized model: "<<robotDesignStr<<"\nDoing the best I can by assuming ERS-7..."<<endl;
00071       robotDesign=ERS7Mask;
00072     }
00073   }
00074 #else
00075   //This is only compiled if we're targeting the local platform
00076   //In other words, if target model is an AIBO, simulation mode
00077 # if TGT_ERS220
00078   robotDesign=ERS220Mask;
00079 # elif TGT_ERS210
00080   robotDesign=ERS210Mask;
00081 # elif TGT_ERS2xx
00082 #   warning "TGT_ERS2xx can't be determined on non-Aperios - defaulting to TGT_ERS210"
00083   robotDesign=ERS210Mask;
00084 # elif TGT_ERS7
00085   robotDesign=ERS7Mask;
00086 # else
00087 #   warning "TGT_<model> undefined - defaulting to TGT_ERS7"
00088   robotDesign=ERS7Mask;
00089 # endif //model selection
00090 #endif
00091 }
00092 
00093 #ifdef PLATFORM_APERIOS
00094 
00095 /*! This will cause events to be posted */
00096 void WorldState::read(OSensorFrameVectorData& sensor, WorldState* lastState, EventRouter* er) {
00097   //always using GetInfo(0) to get "global" information for the vector, other infos contain metadata for individual data fields
00098   unsigned int newFrameNumber=sensor.GetInfo(0)->frameNumber;
00099   if(frameNumber>=newFrameNumber)
00100     return; //sensors have already been filled in
00101   
00102   curtime=get_time();
00103 
00104   std::vector<EventBase> evtBuf;
00105   unsigned int lastFrame=sensor.GetInfo(0)->numFrames-1;
00106 
00107   if(lastState!=NULL && lastState!=this) {
00108     alwaysGenerateStatus=lastState->alwaysGenerateStatus;
00109     //pid and velocity values will be copied at "completion"
00110     robotStatus=lastState->robotStatus;
00111     batteryStatus=lastState->batteryStatus;
00112     for(unsigned int i=0; i<PowerSourceID::NumPowerSIDs; i++)
00113       powerFlags[i]=lastState->powerFlags[i];
00114     
00115     //important part -- copy over button_times before calls to chkEvent
00116     for(unsigned int i=0; i<NumButtons; i++)
00117       button_times[i]=lastState->button_times[i];
00118   }
00119   
00120   if(robotDesign&ERS210Mask) {
00121     outputs[LFrLegOffset + RotatorOffset   ] = GETD(ERS210Info::CPCJointLFRotator);
00122     outputs[LFrLegOffset + ElevatorOffset  ] = GETD(ERS210Info::CPCJointLFElevator);
00123     outputs[LFrLegOffset + KneeOffset      ] = GETD(ERS210Info::CPCJointLFKnee);
00124     pidduties[LFrLegOffset + RotatorOffset ] = GETDUTY(ERS210Info::CPCJointLFRotator);
00125     pidduties[LFrLegOffset + ElevatorOffset] = GETDUTY(ERS210Info::CPCJointLFElevator);
00126     pidduties[LFrLegOffset + KneeOffset    ] = GETDUTY(ERS210Info::CPCJointLFKnee);
00127   
00128     outputs[RFrLegOffset + RotatorOffset   ] = GETD(ERS210Info::CPCJointRFRotator);
00129     outputs[RFrLegOffset + ElevatorOffset  ] = GETD(ERS210Info::CPCJointRFElevator);
00130     outputs[RFrLegOffset + KneeOffset      ] = GETD(ERS210Info::CPCJointRFKnee);
00131     pidduties[RFrLegOffset + RotatorOffset ] = GETDUTY(ERS210Info::CPCJointRFRotator);
00132     pidduties[RFrLegOffset + ElevatorOffset] = GETDUTY(ERS210Info::CPCJointRFElevator);
00133     pidduties[RFrLegOffset + KneeOffset    ] = GETDUTY(ERS210Info::CPCJointRFKnee);
00134 
00135     outputs[LBkLegOffset + RotatorOffset   ] = GETD(ERS210Info::CPCJointLHRotator);
00136     outputs[LBkLegOffset + ElevatorOffset  ] = GETD(ERS210Info::CPCJointLHElevator);
00137     outputs[LBkLegOffset + KneeOffset      ] = GETD(ERS210Info::CPCJointLHKnee);
00138     pidduties[LBkLegOffset + RotatorOffset ] = GETDUTY(ERS210Info::CPCJointLHRotator);
00139     pidduties[LBkLegOffset + ElevatorOffset] = GETDUTY(ERS210Info::CPCJointLHElevator);
00140     pidduties[LBkLegOffset + KneeOffset    ] = GETDUTY(ERS210Info::CPCJointLHKnee);
00141 
00142     outputs[RBkLegOffset + RotatorOffset   ] = GETD(ERS210Info::CPCJointRHRotator);
00143     outputs[RBkLegOffset + ElevatorOffset  ] = GETD(ERS210Info::CPCJointRHElevator);
00144     outputs[RBkLegOffset + KneeOffset      ] = GETD(ERS210Info::CPCJointRHKnee);
00145     pidduties[RBkLegOffset + RotatorOffset ] = GETDUTY(ERS210Info::CPCJointRHRotator);
00146     pidduties[RBkLegOffset + ElevatorOffset] = GETDUTY(ERS210Info::CPCJointRHElevator);
00147     pidduties[RBkLegOffset + KneeOffset    ] = GETDUTY(ERS210Info::CPCJointRHKnee);
00148 
00149     // Get head tilt,pan,roll joint angles
00150     outputs[HeadOffset+TiltOffset] = GETD(ERS210Info::CPCJointNeckTilt);
00151     outputs[HeadOffset+PanOffset ] = GETD(ERS210Info::CPCJointNeckPan);
00152     outputs[HeadOffset+RollOffset] = GETD(ERS210Info::CPCJointNeckRoll);
00153     pidduties[HeadOffset+TiltOffset] = GETDUTY(ERS210Info::CPCJointNeckTilt);
00154     pidduties[HeadOffset+PanOffset ] = GETDUTY(ERS210Info::CPCJointNeckPan);
00155     pidduties[HeadOffset+RollOffset] = GETDUTY(ERS210Info::CPCJointNeckRoll);
00156 
00157     outputs[ERS210Info::TailOffset+TiltOffset] = GETD(ERS210Info::CPCJointTailTilt);
00158     outputs[ERS210Info::TailOffset+PanOffset]  = GETD(ERS210Info::CPCJointTailPan);
00159     pidduties[ERS210Info::TailOffset+TiltOffset] = GETDUTY(ERS210Info::CPCJointTailTilt);
00160     pidduties[ERS210Info::TailOffset+PanOffset]  = GETDUTY(ERS210Info::CPCJointTailPan);
00161     
00162     outputs[ERS210Info::MouthOffset] = GETD(ERS210Info::CPCJointMouth);
00163     pidduties[ERS210Info::MouthOffset] = GETDUTY(ERS210Info::CPCJointMouth);
00164 
00165     if(lastState!=NULL && lastState!=this) {
00166       // Copy over new buttons
00167       buttons[ERS210Info::LFrPawOffset]=GETB(ERS210Info::CPCSensorLFPaw);
00168       buttons[ERS210Info::RFrPawOffset]=GETB(ERS210Info::CPCSensorRFPaw);
00169       buttons[ERS210Info::LBkPawOffset]=GETB(ERS210Info::CPCSensorLHPaw);
00170       buttons[ERS210Info::RBkPawOffset]=GETB(ERS210Info::CPCSensorRHPaw);
00171       
00172       buttons[ERS210Info::ChinButOffset]=GETB(ERS210Info::CPCSensorChinSwitch);
00173       buttons[ERS210Info::BackButOffset]=GETB(ERS210Info::CPCSensorBackSwitch);
00174       buttons[ERS210Info::HeadFrButOffset]=GETD(ERS210Info::CPCSensorHeadFrontPressure);
00175       buttons[ERS210Info::HeadBkButOffset]=GETD(ERS210Info::CPCSensorHeadBackPressure);
00176       
00177       //! process changes
00178       chkEvent(evtBuf,lastState);
00179     } else {
00180       // Get foot switches
00181       chkEvent(evtBuf,ERS210Info::LFrPawOffset,GETB(ERS210Info::CPCSensorLFPaw),buttonNames[ERS210Info::LFrPawOffset]);
00182       chkEvent(evtBuf,ERS210Info::RFrPawOffset,GETB(ERS210Info::CPCSensorRFPaw),buttonNames[ERS210Info::RFrPawOffset]);
00183       chkEvent(evtBuf,ERS210Info::LBkPawOffset,GETB(ERS210Info::CPCSensorLHPaw),buttonNames[ERS210Info::LBkPawOffset]);
00184       chkEvent(evtBuf,ERS210Info::RBkPawOffset,GETB(ERS210Info::CPCSensorRHPaw),buttonNames[ERS210Info::RBkPawOffset]);
00185 
00186       // Get buttons
00187       chkEvent(evtBuf,ERS210Info::ChinButOffset,  GETB(ERS210Info::CPCSensorChinSwitch),buttonNames[ERS210Info::ChinButOffset]);
00188       chkEvent(evtBuf,ERS210Info::BackButOffset,  GETB(ERS210Info::CPCSensorBackSwitch),buttonNames[ERS210Info::BackButOffset]);
00189       chkEvent(evtBuf,ERS210Info::HeadFrButOffset,GETD(ERS210Info::CPCSensorHeadFrontPressure),buttonNames[ERS210Info::HeadFrButOffset]);
00190       chkEvent(evtBuf,ERS210Info::HeadBkButOffset,GETD(ERS210Info::CPCSensorHeadBackPressure),buttonNames[ERS210Info::HeadBkButOffset]);
00191     }
00192 
00193     // Get IR distance sensor
00194     sensors[ERS210Info::IRDistOffset]=GETSENSOR(ERS210Info::CPCSensorPSD) / 1000.0f;
00195 
00196     // Get acceleration sensors
00197     sensors[BAccelOffset] = GETD(ERS210Info::CPCSensorAccelFB);
00198     sensors[LAccelOffset] = GETD(ERS210Info::CPCSensorAccelLR);
00199     sensors[DAccelOffset] = GETD(ERS210Info::CPCSensorAccelUD);
00200 
00201     sensors[ERS210Info::ThermoOffset] = GETD(ERS210Info::CPCSensorThermoSensor);
00202   }
00203 
00204   // (ERS-220 only)
00205   if(robotDesign&ERS220Mask) {
00206     outputs[LFrLegOffset + RotatorOffset   ] = GETD(ERS220Info::CPCJointLFRotator);
00207     outputs[LFrLegOffset + ElevatorOffset  ] = GETD(ERS220Info::CPCJointLFElevator);
00208     outputs[LFrLegOffset + KneeOffset      ] = GETD(ERS220Info::CPCJointLFKnee);
00209     pidduties[LFrLegOffset + RotatorOffset ] = GETDUTY(ERS220Info::CPCJointLFRotator);
00210     pidduties[LFrLegOffset + ElevatorOffset] = GETDUTY(ERS220Info::CPCJointLFElevator);
00211     pidduties[LFrLegOffset + KneeOffset    ] = GETDUTY(ERS220Info::CPCJointLFKnee);
00212   
00213     outputs[RFrLegOffset + RotatorOffset   ] = GETD(ERS220Info::CPCJointRFRotator);
00214     outputs[RFrLegOffset + ElevatorOffset  ] = GETD(ERS220Info::CPCJointRFElevator);
00215     outputs[RFrLegOffset + KneeOffset      ] = GETD(ERS220Info::CPCJointRFKnee);
00216     pidduties[RFrLegOffset + RotatorOffset ] = GETDUTY(ERS220Info::CPCJointRFRotator);
00217     pidduties[RFrLegOffset + ElevatorOffset] = GETDUTY(ERS220Info::CPCJointRFElevator);
00218     pidduties[RFrLegOffset + KneeOffset    ] = GETDUTY(ERS220Info::CPCJointRFKnee);
00219   
00220     outputs[LBkLegOffset + RotatorOffset   ] = GETD(ERS220Info::CPCJointLHRotator);
00221     outputs[LBkLegOffset + ElevatorOffset  ] = GETD(ERS220Info::CPCJointLHElevator);
00222     outputs[LBkLegOffset + KneeOffset      ] = GETD(ERS220Info::CPCJointLHKnee);
00223     pidduties[LBkLegOffset + RotatorOffset ] = GETDUTY(ERS220Info::CPCJointLHRotator);
00224     pidduties[LBkLegOffset + ElevatorOffset] = GETDUTY(ERS220Info::CPCJointLHElevator);
00225     pidduties[LBkLegOffset + KneeOffset    ] = GETDUTY(ERS220Info::CPCJointLHKnee);
00226 
00227     outputs[RBkLegOffset + RotatorOffset   ] = GETD(ERS220Info::CPCJointRHRotator);
00228     outputs[RBkLegOffset + ElevatorOffset  ] = GETD(ERS220Info::CPCJointRHElevator);
00229     outputs[RBkLegOffset + KneeOffset      ] = GETD(ERS220Info::CPCJointRHKnee);
00230     pidduties[RBkLegOffset + RotatorOffset ] = GETDUTY(ERS220Info::CPCJointRHRotator);
00231     pidduties[RBkLegOffset + ElevatorOffset] = GETDUTY(ERS220Info::CPCJointRHElevator);
00232     pidduties[RBkLegOffset + KneeOffset    ] = GETDUTY(ERS220Info::CPCJointRHKnee);
00233 
00234     // Get head tilt,pan,roll joint angles
00235     outputs[HeadOffset+TiltOffset] = GETD(ERS220Info::CPCJointNeckTilt);
00236     outputs[HeadOffset+PanOffset ] = GETD(ERS220Info::CPCJointNeckPan);
00237     outputs[HeadOffset+RollOffset] = GETD(ERS220Info::CPCJointNeckRoll);
00238     pidduties[HeadOffset+TiltOffset] = GETDUTY(ERS220Info::CPCJointNeckTilt);
00239     pidduties[HeadOffset+PanOffset ] = GETDUTY(ERS220Info::CPCJointNeckPan);
00240     pidduties[HeadOffset+RollOffset] = GETDUTY(ERS220Info::CPCJointNeckRoll);
00241 
00242     if(lastState!=NULL && lastState!=this) {
00243       // Copy over new buttons
00244       buttons[ERS220Info::LFrPawOffset]=GETB(ERS220Info::CPCSensorLFPaw);
00245       buttons[ERS220Info::RFrPawOffset]=GETB(ERS220Info::CPCSensorRFPaw);
00246       buttons[ERS220Info::LBkPawOffset]=GETB(ERS220Info::CPCSensorLHPaw);
00247       buttons[ERS220Info::RBkPawOffset]=GETB(ERS220Info::CPCSensorRHPaw);
00248       
00249       buttons[ERS220Info::ChinButOffset]=GETB(ERS220Info::CPCSensorChinSwitch);
00250       buttons[ERS220Info::BackButOffset]=GETB(ERS220Info::CPCSensorBackSwitch);
00251       buttons[ERS220Info::HeadFrButOffset]=GETD(ERS220Info::CPCSensorHeadFrontPressure);
00252       buttons[ERS220Info::HeadBkButOffset]=GETD(ERS220Info::CPCSensorHeadBackPressure);
00253       buttons[ERS220Info::TailLeftButOffset]=GETB(ERS220Info::CPCSensorTailLeftSwitch);
00254       buttons[ERS220Info::TailCenterButOffset]=GETB(ERS220Info::CPCSensorTailCenterSwitch);
00255       buttons[ERS220Info::TailRightButOffset]=GETB(ERS220Info::CPCSensorTailRightSwitch);
00256       
00257       //! process changes
00258       chkEvent(evtBuf,lastState);
00259     } else {
00260       // Get foot switches
00261       chkEvent(evtBuf,ERS220Info::LFrPawOffset,GETB(ERS220Info::CPCSensorLFPaw),buttonNames[ERS220Info::LFrPawOffset]);
00262       chkEvent(evtBuf,ERS220Info::RFrPawOffset,GETB(ERS220Info::CPCSensorRFPaw),buttonNames[ERS220Info::RFrPawOffset]);
00263       chkEvent(evtBuf,ERS220Info::LBkPawOffset,GETB(ERS220Info::CPCSensorLHPaw),buttonNames[ERS220Info::LBkPawOffset]);
00264       chkEvent(evtBuf,ERS220Info::RBkPawOffset,GETB(ERS220Info::CPCSensorRHPaw),buttonNames[ERS220Info::RBkPawOffset]);
00265 
00266       // Get buttons
00267       chkEvent(evtBuf,ERS220Info::ChinButOffset,  GETB(ERS220Info::CPCSensorChinSwitch),buttonNames[ERS220Info::ChinButOffset]);
00268       chkEvent(evtBuf,ERS220Info::BackButOffset,  GETB(ERS220Info::CPCSensorBackSwitch),buttonNames[ERS220Info::BackButOffset]);
00269       chkEvent(evtBuf,ERS220Info::HeadFrButOffset,GETD(ERS220Info::CPCSensorHeadFrontPressure),buttonNames[ERS220Info::HeadFrButOffset]);
00270       chkEvent(evtBuf,ERS220Info::HeadBkButOffset,GETD(ERS220Info::CPCSensorHeadBackPressure),buttonNames[ERS220Info::HeadBkButOffset]);
00271       chkEvent(evtBuf,ERS220Info::TailLeftButOffset, GETB(ERS220Info::CPCSensorTailLeftSwitch),  buttonNames[ERS220Info::TailLeftButOffset]);
00272       chkEvent(evtBuf,ERS220Info::TailCenterButOffset, GETB(ERS220Info::CPCSensorTailCenterSwitch),buttonNames[ERS220Info::TailCenterButOffset]);
00273       chkEvent(evtBuf,ERS220Info::TailRightButOffset, GETB(ERS220Info::CPCSensorTailRightSwitch), buttonNames[ERS220Info::TailRightButOffset]);
00274     }
00275 
00276     // Get IR distance sensor
00277     sensors[ERS220Info::IRDistOffset]=GETSENSOR(ERS220Info::CPCSensorPSD) / 1000.0f;
00278 
00279     // Get acceleration sensors
00280     sensors[BAccelOffset] = GETD(ERS220Info::CPCSensorAccelFB);
00281     sensors[LAccelOffset] = GETD(ERS220Info::CPCSensorAccelLR);
00282     sensors[DAccelOffset] = GETD(ERS220Info::CPCSensorAccelUD);
00283 
00284     sensors[ERS220Info::ThermoOffset] = GETD(ERS220Info::CPCSensorThermoSensor);
00285   }
00286 
00287   // (ERS-7 only)
00288   if(robotDesign&ERS7Mask) {
00289     outputs[LFrLegOffset + RotatorOffset   ] = GETD(ERS7Info::CPCJointLFRotator);
00290     outputs[LFrLegOffset + ElevatorOffset  ] = GETD(ERS7Info::CPCJointLFElevator);
00291     outputs[LFrLegOffset + KneeOffset      ] = GETD(ERS7Info::CPCJointLFKnee);
00292     pidduties[LFrLegOffset + RotatorOffset ] = GETDUTY(ERS7Info::CPCJointLFRotator);
00293     pidduties[LFrLegOffset + ElevatorOffset] = GETDUTY(ERS7Info::CPCJointLFElevator);
00294     pidduties[LFrLegOffset + KneeOffset    ] = GETDUTY(ERS7Info::CPCJointLFKnee);
00295   
00296     outputs[RFrLegOffset + RotatorOffset   ] = GETD(ERS7Info::CPCJointRFRotator);
00297     outputs[RFrLegOffset + ElevatorOffset  ] = GETD(ERS7Info::CPCJointRFElevator);
00298     outputs[RFrLegOffset + KneeOffset      ] = GETD(ERS7Info::CPCJointRFKnee);
00299     pidduties[RFrLegOffset + RotatorOffset ] = GETDUTY(ERS7Info::CPCJointRFRotator);
00300     pidduties[RFrLegOffset + ElevatorOffset] = GETDUTY(ERS7Info::CPCJointRFElevator);
00301     pidduties[RFrLegOffset + KneeOffset    ] = GETDUTY(ERS7Info::CPCJointRFKnee);
00302   
00303     outputs[LBkLegOffset + RotatorOffset   ] = GETD(ERS7Info::CPCJointLHRotator);
00304     outputs[LBkLegOffset + ElevatorOffset  ] = GETD(ERS7Info::CPCJointLHElevator);
00305     outputs[LBkLegOffset + KneeOffset      ] = GETD(ERS7Info::CPCJointLHKnee);
00306     pidduties[LBkLegOffset + RotatorOffset ] = GETDUTY(ERS7Info::CPCJointLHRotator);
00307     pidduties[LBkLegOffset + ElevatorOffset] = GETDUTY(ERS7Info::CPCJointLHElevator);
00308     pidduties[LBkLegOffset + KneeOffset    ] = GETDUTY(ERS7Info::CPCJointLHKnee);
00309 
00310     outputs[RBkLegOffset + RotatorOffset   ] = GETD(ERS7Info::CPCJointRHRotator);
00311     outputs[RBkLegOffset + ElevatorOffset  ] = GETD(ERS7Info::CPCJointRHElevator);
00312     outputs[RBkLegOffset + KneeOffset      ] = GETD(ERS7Info::CPCJointRHKnee);
00313     pidduties[RBkLegOffset + RotatorOffset ] = GETDUTY(ERS7Info::CPCJointRHRotator);
00314     pidduties[RBkLegOffset + ElevatorOffset] = GETDUTY(ERS7Info::CPCJointRHElevator);
00315     pidduties[RBkLegOffset + KneeOffset    ] = GETDUTY(ERS7Info::CPCJointRHKnee);
00316 
00317     // Get head tilt,pan,nod joint angles
00318     outputs[HeadOffset+TiltOffset] = GETD(ERS7Info::CPCJointNeckTilt);
00319     outputs[HeadOffset+PanOffset ] = GETD(ERS7Info::CPCJointNeckPan);
00320     outputs[HeadOffset+RollOffset] = GETD(ERS7Info::CPCJointNeckNod);
00321     pidduties[HeadOffset+TiltOffset] = GETDUTY(ERS7Info::CPCJointNeckTilt);
00322     pidduties[HeadOffset+PanOffset ] = GETDUTY(ERS7Info::CPCJointNeckPan);
00323     pidduties[HeadOffset+RollOffset] = GETDUTY(ERS7Info::CPCJointNeckNod);
00324 
00325     outputs[ERS7Info::TailOffset+TiltOffset] = GETD(ERS7Info::CPCJointTailTilt);
00326     outputs[ERS7Info::TailOffset+PanOffset]  = GETD(ERS7Info::CPCJointTailPan);
00327     pidduties[ERS7Info::TailOffset+TiltOffset] = GETDUTY(ERS7Info::CPCJointTailTilt);
00328     pidduties[ERS7Info::TailOffset+PanOffset]  = GETDUTY(ERS7Info::CPCJointTailPan);
00329     
00330     outputs[ERS7Info::MouthOffset] = GETD(ERS7Info::CPCJointMouth);
00331     pidduties[ERS7Info::MouthOffset] = GETDUTY(ERS7Info::CPCJointMouth);
00332 
00333     if(lastState!=NULL && lastState!=this) {
00334       // Copy over new buttons
00335       buttons[ERS7Info::LFrPawOffset]=GETB(ERS7Info::CPCSwitchLFPaw);
00336       buttons[ERS7Info::RFrPawOffset]=GETB(ERS7Info::CPCSwitchRFPaw);
00337       buttons[ERS7Info::LBkPawOffset]=GETB(ERS7Info::CPCSwitchLHPaw);
00338       buttons[ERS7Info::RBkPawOffset]=GETB(ERS7Info::CPCSwitchRHPaw);
00339       
00340       // the sensors are scaled to be relatively similar to the pressure values given by the head on the 210
00341       buttons[ ERS7Info::ChinButOffset]=GETSENSOR(ERS7Info::CPCSwitchChin);
00342       buttons[ ERS7Info::HeadButOffset]=GETSENSOR(ERS7Info::CPCSensorHead)/120;
00343       buttons[ ERS7Info::FrontBackButOffset]=GETSENSOR(ERS7Info::CPCSensorBackFront)/150;
00344       buttons[ ERS7Info::MiddleBackButOffset]=GETSENSOR(ERS7Info::CPCSensorBackMiddle)/150;
00345       buttons[ ERS7Info::RearBackButOffset]=GETSENSOR(ERS7Info::CPCSensorBackRear)/150;
00346       buttons[ ERS7Info::WirelessSwOffset]=GETSENSOR(ERS7Info::CPCSwitchWireless);
00347       
00348       //! process changes
00349       chkEvent(evtBuf,lastState);
00350     } else {
00351       // Get foot switches
00352       chkEvent(evtBuf,ERS7Info::LFrPawOffset,GETB(ERS7Info::CPCSwitchLFPaw),buttonNames[ERS7Info::LFrPawOffset]);
00353       chkEvent(evtBuf,ERS7Info::RFrPawOffset,GETB(ERS7Info::CPCSwitchRFPaw),buttonNames[ERS7Info::RFrPawOffset]);
00354       chkEvent(evtBuf,ERS7Info::LBkPawOffset,GETB(ERS7Info::CPCSwitchLHPaw),buttonNames[ERS7Info::LBkPawOffset]);
00355       chkEvent(evtBuf,ERS7Info::RBkPawOffset,GETB(ERS7Info::CPCSwitchRHPaw),buttonNames[ERS7Info::RBkPawOffset]);
00356 
00357       // Get buttons/switches
00358       // the sensors are scaled to be relatively similar to the pressure values given by the head on the 210
00359       chkEvent(evtBuf, ERS7Info::ChinButOffset,       GETSENSOR(ERS7Info::CPCSwitchChin),      buttonNames[ERS7Info::ChinButOffset]);
00360       chkEvent(evtBuf, ERS7Info::HeadButOffset,       GETSENSOR(ERS7Info::CPCSensorHead)/120,      buttonNames[ERS7Info::HeadButOffset]);
00361       chkEvent(evtBuf, ERS7Info::FrontBackButOffset,  GETSENSOR(ERS7Info::CPCSensorBackFront)/150, buttonNames[ERS7Info::FrontBackButOffset]);
00362       chkEvent(evtBuf, ERS7Info::MiddleBackButOffset, GETSENSOR(ERS7Info::CPCSensorBackMiddle)/150,buttonNames[ERS7Info::MiddleBackButOffset]);
00363       chkEvent(evtBuf, ERS7Info::RearBackButOffset,   GETSENSOR(ERS7Info::CPCSensorBackRear)/150,  buttonNames[ERS7Info::RearBackButOffset]);
00364       chkEvent(evtBuf, ERS7Info::WirelessSwOffset,GETSENSOR(ERS7Info::CPCSwitchWireless),  buttonNames[ERS7Info::WirelessSwOffset]);
00365     }
00366 
00367     // Get IR distance sensor
00368     sensors[ERS7Info::NearIRDistOffset] = GETSENSOR(ERS7Info::CPCSensorNearPSD) / 1000.0f;
00369     sensors[ERS7Info::FarIRDistOffset] = GETSENSOR(ERS7Info::CPCSensorFarPSD) / 1000.0f;
00370     sensors[ERS7Info::ChestIRDistOffset] = GETSENSOR(ERS7Info::CPCSensorChestPSD) / 1000.0f;
00371 
00372     // Get acceleration sensors
00373     sensors[BAccelOffset] = GETD(ERS7Info::CPCSensorAccelFB);
00374     sensors[LAccelOffset] = GETD(ERS7Info::CPCSensorAccelLR);
00375     sensors[DAccelOffset] = GETD(ERS7Info::CPCSensorAccelUD);
00376   }
00377 
00378   //unsigned int dif=curtime-(lastState==NULL ? lastSensorUpdateTime : lastState->lastSensorUpdateTime);
00379   lastSensorUpdateTime=curtime;
00380   frameNumber=newFrameNumber;
00381   framesProcessed=(lastState!=NULL?lastState->framesProcessed:framesProcessed)+1;
00382   for(unsigned int i=0; i<evtBuf.size(); i++)
00383     er->postEvent(evtBuf[i]);
00384   
00385   
00386   //Apply sensor calibrations (currently only joint positions - perhaps IR as well?)
00387   for(unsigned int i=0; i<NumPIDJoints; i++)
00388     outputs[PIDJointOffset+i]*=config->motion.calibration[i];
00389 
00390   //this version of read doesn't post the sensor update event -- the caller should do that
00391   //this event gets posted by MMCombo only if there's no back log on the interprocess event queue (don't want to stack these up for sensor frames missed by main)
00392   //er->postEvent(EventBase::sensorEGID,SensorSourceID::UpdatedSID,EventBase::statusETID,dif,"SensorSouceID::UpdatedSID",1);
00393 }
00394 
00395 /*! This will cause events to be posted */
00396 void WorldState::read(const OPowerStatus& power, EventRouter* er) {
00397   std::string actnames[PowerSourceID::NumPowerSIDs];
00398   std::string denames[PowerSourceID::NumPowerSIDs];
00399   unsigned int actmasks[PowerSourceID::NumPowerSIDs];
00400   memset(actmasks,0,sizeof(unsigned int)*PowerSourceID::NumPowerSIDs);
00401 
00402   //RobotStatus
00403   chkPowerEvent(PowerSourceID::PauseSID,          power.robotStatus,orsbPAUSE,                        "Pause",actnames,denames,actmasks);
00404   chkPowerEvent(PowerSourceID::MotorPowerSID,     power.robotStatus,orsbMOTOR_POWER,                  "MotorPower",actnames,denames,actmasks);
00405   chkPowerEvent(PowerSourceID::VibrationSID,      power.robotStatus,orsbVIBRATION_DETECT,             "Vibration",actnames,denames,actmasks);
00406   chkPowerEvent(PowerSourceID::ExternalPortSID,   power.robotStatus,orsbEX_PORT_CONNECTED,            "ExternalPort",actnames,denames,actmasks);
00407   chkPowerEvent(PowerSourceID::StationConnectSID, power.robotStatus,orsbSTATION_CONNECTED,            "StationConnect",actnames,denames,actmasks);
00408   chkPowerEvent(PowerSourceID::ExternalPowerSID,  power.robotStatus,orsbEX_POWER_CONNECTED,           "ExternalPower",actnames,denames,actmasks);
00409   chkPowerEvent(PowerSourceID::BatteryConnectSID, power.robotStatus,orsbBATTERY_CONNECTED,            "BatteryConnect",actnames,denames,actmasks);
00410   chkPowerEvent(PowerSourceID::ChargingSID,       power.robotStatus,orsbBATTERY_CHARGING,             "BatteryCharging",actnames,denames,actmasks);
00411   chkPowerEvent(PowerSourceID::BatteryFullSID,    power.robotStatus,orsbBATTERY_CAPACITY_FULL,        "BatteryFull",actnames,denames,actmasks);
00412   chkPowerEvent(PowerSourceID::LowPowerWarnSID,   power.robotStatus,orsbBATTERY_CAPACITY_LOW,         "BatteryLow",actnames,denames,actmasks);
00413   chkPowerEvent(PowerSourceID::OverChargedSID,    power.robotStatus,orsbBATTERY_OVER_CURRENT,         "BatteryOverCurrent",actnames,denames,actmasks);
00414   chkPowerEvent(PowerSourceID::OverheatingSID,    power.robotStatus,orsbBATTERY_OVER_TEMP_DISCHARGING,"BatteryOverTempDischarge",actnames,denames,actmasks);
00415   chkPowerEvent(PowerSourceID::OverheatingSID,    power.robotStatus,orsbBATTERY_OVER_TEMP_CHARGING,   "BatteryOverTempCharge",actnames,denames,actmasks);
00416   chkPowerEvent(PowerSourceID::ErrorSID,          power.robotStatus,orsbBATTERY_ERROR_OF_CHARGING,    "BatteryChargeError",actnames,denames,actmasks);
00417   chkPowerEvent(PowerSourceID::ErrorSID,          power.robotStatus,orsbERROR_OF_PLUNGER,             "PlungerError",actnames,denames,actmasks);
00418   chkPowerEvent(PowerSourceID::PowerGoodSID,      power.robotStatus,orsbOPEN_R_POWER_GOOD,            "PowerGood",actnames,denames,actmasks);
00419   chkPowerEvent(PowerSourceID::ErrorSID,          power.robotStatus,orsbERROR_OF_FAN,                 "FanError",actnames,denames,actmasks);
00420   chkPowerEvent(PowerSourceID::DataFromStationSID,power.robotStatus,orsbDATA_STREAM_FROM_STATION,     "DataFromStation",actnames,denames,actmasks);
00421   chkPowerEvent(PowerSourceID::RegisterUpdateSID, power.robotStatus,orsbREGISTER_UPDATED_BY_STATION,  "RegisterUpdate",actnames,denames,actmasks);
00422   chkPowerEvent(PowerSourceID::ErrorSID,          power.robotStatus,orsbRTC_ERROR,                    "RTCError",actnames,denames,actmasks);
00423   chkPowerEvent(PowerSourceID::RTCSID,            power.robotStatus,orsbRTC_OVERFLOW,                 "RTCOverflow",actnames,denames,actmasks);
00424   chkPowerEvent(PowerSourceID::RTCSID,            power.robotStatus,orsbRTC_RESET,                    "RTCReset",actnames,denames,actmasks);
00425   chkPowerEvent(PowerSourceID::RTCSID,            power.robotStatus,orsbRTC_SET,                      "RTCSet",actnames,denames,actmasks);
00426   chkPowerEvent(PowerSourceID::SpecialModeSID,    power.robotStatus,orsbSPECIAL_MODE,                 "SpecialMode",actnames,denames,actmasks);
00427   chkPowerEvent(PowerSourceID::BMNDebugModeSID,   power.robotStatus,orsbBMN_DEBUG_MODE,               "BMNDebugMode",actnames,denames,actmasks);
00428   chkPowerEvent(PowerSourceID::ChargerStatusSID,  power.robotStatus,orsbCHARGER_STATUS,               "ChargerStatus",actnames,denames,actmasks);
00429   chkPowerEvent(PowerSourceID::PlungerSID,        power.robotStatus,orsbPLUNGER,                      "Plunger",actnames,denames,actmasks);
00430   chkPowerEvent(PowerSourceID::SuspendedSID,      power.robotStatus,orsbSUSPENDED,                    "Suspended",actnames,denames,actmasks);
00431 
00432   //BatteryStatus
00433   chkPowerEvent(PowerSourceID::ErrorSID,        power.batteryStatus,obsbERROR_CODE_MASK,             "BatteryError",actnames,denames,actmasks);
00434   chkPowerEvent(PowerSourceID::BatteryEmptySID, power.batteryStatus,obsbFULLY_DISCHARGED,            "FullyDischarged",actnames,denames,actmasks);
00435   chkPowerEvent(PowerSourceID::BatteryFullSID,  power.batteryStatus,obsbFULLY_CHARGED,               "FullyCharged",actnames,denames,actmasks);
00436   chkPowerEvent(PowerSourceID::DischargingSID,  power.batteryStatus,obsbDISCHARGING,                 "Discharging",actnames,denames,actmasks);
00437   chkPowerEvent(PowerSourceID::BatteryInitSID,  power.batteryStatus,obsbINITIALIZED,                 "BatteryInit",actnames,denames,actmasks);
00438   chkPowerEvent(PowerSourceID::LowPowerWarnSID, power.batteryStatus,obsbREMAINING_TIME_ALARM,        "RemainingTimeAlarm",actnames,denames,actmasks);
00439   chkPowerEvent(PowerSourceID::LowPowerWarnSID, power.batteryStatus,obsbREMAINING_CAPACITY_ALARM,    "RemainingCapacityAlarm",actnames,denames,actmasks);
00440   chkPowerEvent(PowerSourceID::TermDischargeSID,power.batteryStatus,obsbTERMINATED_DISCHARGING_ALARM,"TermDischargeAlarm",actnames,denames,actmasks);
00441   chkPowerEvent(PowerSourceID::OverheatingSID,  power.batteryStatus,obsbOVER_TEMP_ALARM,             "OverTempAlarm",actnames,denames,actmasks);
00442   chkPowerEvent(PowerSourceID::TermChargeSID,   power.batteryStatus,obsbTERMINATED_CHARGING_ALARM,   "TermChargeAlarm",actnames,denames,actmasks);
00443   chkPowerEvent(PowerSourceID::OverChargedSID,  power.batteryStatus,obsbOVER_CHARGED_ALARM,          "OverChargeAlarm",actnames,denames,actmasks);
00444   
00445   sensors[PowerRemainOffset] = power.remainingCapacity/100.0;
00446   sensors[PowerThermoOffset] = power.temperature/100.0;
00447   sensors[PowerCapacityOffset] = power.fullyChargedCapacity;
00448   sensors[PowerVoltageOffset] = power.voltage/1000.0;
00449   sensors[PowerCurrentOffset] = power.current;
00450 
00451   //only generate status events when a change happens
00452   for(unsigned int i=0; i<PowerSourceID::NumPowerSIDs; i++) {
00453     if(actmasks[i]) { //now on
00454       if(!powerFlags[i]) //was off: activation
00455         er->postEvent(EventBase::powerEGID,i,EventBase::activateETID,0,actnames[i],1);
00456       else if(actmasks[i]!=powerFlags[i]) //already on - change? : status
00457         er->postEvent(EventBase::powerEGID,i,EventBase::statusETID,0,actnames[i],1);
00458     } else { // now off
00459       if(powerFlags[i]) //was on: deactivation
00460         er->postEvent(EventBase::powerEGID,i,EventBase::deactivateETID,0,denames[i],0);
00461     }
00462     powerFlags[i]=actmasks[i];
00463   }
00464 
00465   er->postEvent(EventBase::powerEGID,PowerSourceID::UpdatedSID,EventBase::statusETID,0,"PowerSourceID::UpdatedSID",1);
00466 }
00467 
00468 #else  //PLATFORM_LOCAL
00469 
00470 /*! This version of read() doesn't post the sensor update event -- the caller should do that
00471  *  (this variant is used by the simulator, different parts fill in different sections, the last one should trigger the event)
00472  *
00473  *  This function assumes that the pose (and any associated sensor readings)
00474  *  are for the current model robot, and that any calibration has already 
00475  *  been applied (so the values can be used unchanged)
00476  */
00477 void WorldState::read(const PostureEngine& pose, WorldState* lastState, EventRouter* er) {
00478   curtime=get_time();
00479   std::vector<EventBase> evtBuf;
00480   WorldState* ext=pose.getLoadedSensors();
00481 
00482   unsigned int newFrameNumber=(lastState!=NULL?lastState->frameNumber:frameNumber)+NumFrames;
00483 
00484   for(unsigned int i=0; i<NumOutputs; i++)
00485     if(pose(i).weight>0)
00486       outputs[i]=pose(i).value;
00487 
00488   if(frameNumber>=newFrameNumber)
00489     return; //sensors have already been filled in
00490   
00491   if(lastState!=NULL && lastState!=this) {
00492     alwaysGenerateStatus=lastState->alwaysGenerateStatus;
00493     //pid and velocity values will be copied at "completion"
00494     robotStatus=lastState->robotStatus;
00495     batteryStatus=lastState->batteryStatus;
00496     for(unsigned int i=0; i<PowerSourceID::NumPowerSIDs; i++)
00497       powerFlags[i]=lastState->powerFlags[i];
00498 
00499     //important part -- copy over button_times before calls to chkEvent
00500     for(unsigned int i=0; i<NumButtons; i++)
00501       button_times[i]=lastState->button_times[i];
00502   }
00503   
00504   if(ext!=NULL) {
00505     if(ext==this) {
00506       chkEvent(evtBuf,lastState);
00507     } else {
00508       if(lastState!=NULL && lastState!=this) {
00509         for(unsigned int i=0; i<NumButtons; i++)
00510           buttons[i]=ext->buttons[i];
00511         chkEvent(evtBuf,lastState);
00512       } else {
00513         for(unsigned int i=0; i<NumButtons; i++)
00514           chkEvent(evtBuf,i,ext->buttons[i],buttonNames[i]);
00515       }
00516       for(unsigned int i=0; i<NumSensors; i++)
00517         sensors[i]=ext->sensors[i];
00518       for(unsigned int i=0; i<NumPIDJoints; i++)
00519         pidduties[i]=ext->pidduties[i];
00520     }
00521   } else if(lastState!=NULL && lastState!=this) {
00522     // no loaded sensors at all -- copy over previous values
00523     for(unsigned int i=0; i<NumButtons; i++)
00524       buttons[i]=lastState->buttons[i];
00525     for(unsigned int i=0; i<NumSensors; i++)
00526       sensors[i]=lastState->sensors[i];
00527     for(unsigned int i=0; i<NumPIDJoints; i++)
00528       pidduties[i]=lastState->pidduties[i];
00529   }
00530 
00531   //unsigned int dif=curtime-(lastState==NULL ? lastSensorUpdateTime : lastState->lastSensorUpdateTime);
00532   lastSensorUpdateTime=curtime;
00533   if(newFrameNumber!=-1U)
00534     frameNumber=newFrameNumber;
00535   framesProcessed=(lastState!=NULL?lastState->framesProcessed:framesProcessed)+1;
00536   for(unsigned int i=0; i<evtBuf.size(); i++)
00537     er->postEvent(evtBuf[i]);
00538   
00539   //this version of read doesn't post the sensor update event -- the caller should do that
00540   // (this variant is used by the simulator, different parts fill in different sections, the last one should trigger the event)
00541   //er->postEvent(EventBase::sensorEGID,SensorSourceID::UpdatedSID,EventBase::statusETID,dif,"SensorSourceID::UpdatedSID",1);
00542 }
00543 
00544 #endif //platform-specific sensor updating
00545 
00546 void WorldState::chkEvent(std::vector<EventBase>& evtBuf, unsigned int sid, float newval, const char* name) {
00547   if(newval>=0.1) { //now on
00548     if(buttons[sid]<0.1) { //was off: activation
00549       cout << ProcessID::getIDStr() << " post activate" << endl;
00550       evtBuf.push_back(EventBase(EventBase::buttonEGID,sid,EventBase::activateETID,0,name,newval));
00551       button_times[sid]=curtime;
00552     } else if(alwaysGenerateStatus || buttons[sid]!=newval) { //already on - always or change? : status
00553       unsigned int dur=curtime-button_times[sid];
00554       cout << ProcessID::getIDStr() << " post status" << endl;
00555       evtBuf.push_back(EventBase(EventBase::buttonEGID,sid,EventBase::statusETID,dur,name,newval));
00556     }
00557   } else { //now off
00558     if(buttons[sid]>=0.1) { //was on: deactivation
00559       unsigned int dur=curtime-button_times[sid];
00560       button_times[sid]=0;
00561       cout << ProcessID::getIDStr() << " post deactivate" << endl;
00562       evtBuf.push_back(EventBase(EventBase::buttonEGID,sid,EventBase::deactivateETID,dur,name,0));
00563     }
00564   }
00565   //update value
00566   buttons[sid]=newval;
00567 }
00568 
00569 void WorldState::chkEvent(std::vector<EventBase>& evtBuf, WorldState* lastState) {
00570   // posture already loaded data into this instance of WorldState
00571   // variation on chkEvent -- instead, we already hold the latest data, need to compare against lastState
00572   for(unsigned int sid=0; sid<NumButtons; sid++) {
00573     if(buttons[sid]>=0.1) { //now on
00574       if(lastState->buttons[sid]<0.1) { //was off: activation
00575         evtBuf.push_back(EventBase(EventBase::buttonEGID,sid,EventBase::activateETID,0,buttonNames[sid],buttons[sid]));
00576         button_times[sid]=curtime;
00577       } else if(alwaysGenerateStatus || lastState->buttons[sid]!=buttons[sid]) { //already on - always or change? : status
00578         unsigned int dur=curtime-button_times[sid];
00579         evtBuf.push_back(EventBase(EventBase::buttonEGID,sid,EventBase::statusETID,dur,buttonNames[sid],buttons[sid]));
00580       }
00581     } else { //now off
00582       if(lastState->buttons[sid]>=0.1) { //was on: deactivation
00583         unsigned int dur=curtime-button_times[sid];
00584         button_times[sid]=0;
00585         evtBuf.push_back(EventBase(EventBase::buttonEGID,sid,EventBase::deactivateETID,dur,buttonNames[sid],0));
00586       }
00587     }
00588   }
00589 }
00590 
00591 /*! @file
00592  * @brief Implements WorldState, maintains information about the robot's environment, namely sensors and power status
00593  * @author ejt (Creator)
00594  *
00595  * $Author: ejt $
00596  * $Name: tekkotsu-3_0 $
00597  * $Revision: 1.40 $
00598  * $State: Exp $
00599  * $Date: 2006/09/29 16:56:09 $
00600  */

Tekkotsu v3.0
Generated Wed Oct 4 00:03:47 2006 by Doxygen 1.4.7