BeeStemI.C

00001 #include "Robots/SeaBeeIII/BeeStemI.H"
00002 #include "Util/Timer.H"
00003 #include "Robots/SeaBeeIII/XBox360RemoteControlI.H"
00004 
00005 // ######################################################################
00006 BeeStemI::BeeStemI(int id, OptionManager& mgr, const std::string& descrName, const std::string& tagName) :
00007         RobotBrainComponent(mgr, descrName, tagName), itsStem(new BeeStem3(mgr, "BeeStem3", "BeeStem3", "/dev/ttyUSB0")),
00008         itsUpdateHeading(0),
00009         itsUpdateDepth(0),
00010         itsUpdateSpeed(0),
00011         itsLastUpdateHeading(0),
00012         itsLastUpdateDepth(0),
00013         itsLastUpdateSpeed(0),
00014         mShooterState(ShooterState::Idle),
00015         mDropperState(DropperState::AllIdle),
00016         mFiringDeviceID(FiringDeviceID::Null)
00017 {
00018         addSubComponent(itsStem);
00019         //  addSubComponent(itsKillSwitch);
00020 
00021         //itsKillSwitch->configure("/dev/ttyUSB1",57600);
00022         itsEvolveSleepTime = 0;
00023         mFlags.initFlag = false;
00024         //itsJSValues.resize(8);
00025         itsButValues.resize(20);
00026         // init trigger values
00027         itsJSMappings[XBox360RemoteControl::Keys::Actions::SURFACE] = -100;
00028         itsJSMappings[XBox360RemoteControl::Keys::Actions::DIVE] = -100;
00029         //itsJSValues[4] = -100; //this only works if those axes are properly mapped
00030         //itsJSValues[5] = -100;
00031 }
00032 
00033 // ######################################################################
00034 BeeStemI::~BeeStemI()
00035 {
00036 }
00037 
00038 // ######################################################################
00039 void BeeStemI::initPose()
00040 {
00041         mFlags.initFlag = true;
00042 
00043         itsStemMutex.lock();
00044         itsStem->setPID(0, HEADING_K, HEADING_P, HEADING_I, HEADING_D);
00045         itsStem->setPID(1, DEPTH_K, DEPTH_P, DEPTH_I, DEPTH_D);
00046 
00047         int accelX, accelY, accelZ;
00048         int compassHeading, compassPitch, compassRoll;
00049         int internalPressure, externalPressure;
00050         int headingK, headingP, headingD, headingI, headingOutput;
00051         int depthK, depthP, depthD, depthI, depthOutput;
00052         char killSwitch;
00053 
00054         bool successful = itsStem->getSensors(accelX, accelY, accelZ, compassHeading, compassPitch, compassRoll, internalPressure, externalPressure, itsDesiredHeading, itsDesiredDepth, itsDesiredSpeed, headingK, headingP, headingD, headingI, headingOutput, depthK, depthP, depthD, depthI, depthOutput, killSwitch);
00055 
00056         if (successful)
00057         {
00058                 itsUpdateHeading = compassHeading;
00059                 itsLastUpdateHeading = itsUpdateHeading;
00060                 itsStem->setDesiredHeading(compassHeading);
00061                 itsUpdateDepth = externalPressure;
00062                 itsLastUpdateDepth = itsUpdateDepth;
00063                 itsStem->setDesiredDepth(externalPressure);
00064         }
00065 
00066         itsStemMutex.unlock();
00067 }
00068 
00069 void BeeStemI::registerTopics()
00070 {
00071         LINFO("Registering BeeStem Message");
00072         this->registerPublisher("BeeStemMessageTopic");
00073         registerSubscription("BeeStemMotorControllerMessageTopic");
00074         registerSubscription("XBox360RemoteControlMessageTopic");
00075         registerSubscription("BeeStemConfigTopic");
00076 }
00077 
00078 void BeeStemI::setValuesFromJoystick()
00079 {
00080         int rightVal = itsJSMappings[XBox360RemoteControl::Keys::Actions::SPEED] * -1;//itsJSValues[1]*-1;
00081         int leftVal = itsJSMappings[XBox360RemoteControl::Keys::Actions::SPEED];//itsJSValues[1];
00082 
00083         itsStem->setThruster(BeeStem3::MotorControllerIDs::FWD_RIGHT_THRUSTER, rightVal);
00084         itsStem->setThruster(BeeStem3::MotorControllerIDs::FWD_LEFT_THRUSTER, leftVal);
00085 
00086         //  itsJSValues[5], itsJSValues[4]
00087         //cout << itsJSMappings[XBox360RemoteControlI::Keys::Axes::Actions::SURFACE] << endl;
00088         //cout << itsJSMappings[XBox360RemoteControlI::Keys::Axes::Actions::DIVE] << endl;
00089         int depthVal = int((float(itsJSMappings[XBox360RemoteControl::Keys::Actions::SURFACE]) + 100.0) / 2.0 - (float(itsJSMappings[XBox360RemoteControl::Keys::Actions::DIVE]) + 100.0) / 2.0);
00090         //cout << depthVal << endl;
00091         //cout << "-----" << endl;
00092 
00093         int depthValRight = depthVal;
00094         int depthValLeft = depthVal;
00095 
00096         //   if(itsButValues[5])
00097         //     {
00098         //       depthValRight = 75;
00099         //       depthValLeft = -75;
00100         //     }
00101         //   else if(itsButValues[4])
00102         //     {
00103         //       depthValRight = -75;
00104         //       depthValLeft = 75;
00105         //     }
00106 
00107         itsStem->setThruster(BeeStem3::MotorControllerIDs::DEPTH_RIGHT_THRUSTER, depthValRight);
00108         itsStem->setThruster(BeeStem3::MotorControllerIDs::DEPTH_LEFT_THRUSTER, depthValLeft);
00109 
00110         //itsJSValues[2], itsJSValues[0]
00111         int frontVal = itsJSMappings[XBox360RemoteControl::Keys::Actions::HEADING] + itsJSMappings[XBox360RemoteControl::Keys::Actions::STRAFE] * -1;
00112         int backVal = itsJSMappings[XBox360RemoteControl::Keys::Actions::HEADING] * -1 + itsJSMappings[XBox360RemoteControl::Keys::Actions::STRAFE] * -1;
00113 
00114         itsStem->setThruster(BeeStem3::MotorControllerIDs::STRAFE_FRONT_THRUSTER, frontVal);
00115         itsStem->setThruster(BeeStem3::MotorControllerIDs::STRAFE_BACK_THRUSTER, backVal);
00116 }
00117 
00118 void BeeStemI::evolve()
00119 {
00120         if (!mFlags.initFlag)
00121                 initPose();
00122 
00123         if(mFlags.needsUpdateFromJoystick)
00124         {
00125                 setValuesFromJoystick();
00126                 mFlags.needsUpdateFromJoystick = false;
00127         }
00128 
00129         /****************
00130         ** arm devices **
00131         ****************/
00132 
00133         //first, put all devices at last idle state
00134         mShooterState = mShooterState == ShooterState::Armed ? ShooterState::Idle : mShooterState;
00135         mDropperState = mDropperState == DropperState::Stage1Armed ? DropperState::AllIdle : mDropperState;
00136         mDropperState = mDropperState == DropperState::Stage2Armed ? DropperState::Stage1Idle : mDropperState;
00137 
00138         //then, arm the currently selected device
00139         switch (mFiringDeviceID)
00140         {
00141         case FiringDeviceID::Shooter:
00142                 mShooterState = mShooterState == ShooterState::Idle ? ShooterState::Armed : mShooterState;
00143                 break;
00144         case FiringDeviceID::DropperStage1:
00145                 mDropperState = mDropperState == DropperState::AllIdle ? DropperState::Stage1Armed : mDropperState;
00146                 break;
00147         case FiringDeviceID::DropperStage2:
00148                 mDropperState = mDropperState == DropperState::Stage1Idle ? DropperState::Stage2Armed : mDropperState;
00149                 break;
00150         }
00151 
00152         /*******************************
00153         ** set firing mode on devices **
00154         *******************************/
00155         if(abs(itsJSMappings[XBox360RemoteControl::Keys::Actions::FIRE_DEV]) > 0) //fire key pressed
00156         {
00157                 if (mShooterState == ShooterState::Armed)
00158                 {
00159                         cout << "Shooter set to fire!" << endl;
00160                         mShooterState = ShooterState::Firing;
00161                 }
00162                 else if(mDropperState == DropperState::Stage1Armed)
00163                 {
00164                         cout << "Dropper stage1 set to drop!" << endl;
00165                         mDropperState = DropperState::Stage1Dropping;
00166                 }
00167                 else if(mDropperState == DropperState::Stage2Armed)
00168                 {
00169                         cout << "Dropper stage2 set to drop!" << endl;
00170                         mDropperState = DropperState::Stage2Dropping;
00171                 }
00172         }
00173         else if(abs(itsJSMappings[XBox360RemoteControl::Keys::Actions::FIRE_DEV]) == 0) //fire key released
00174         {
00175                 if (mShooterState == ShooterState::Reset)
00176                 {
00177                         cout << "Shooter reset" << endl;
00178                         mShooterState = ShooterState::Idle;
00179                 }
00180                 else if(mDropperState == DropperState::Stage1Reset)
00181                 {
00182                         cout << "Dropper stage1 reset" << endl;
00183                         mDropperState = DropperState::Stage1Idle;
00184                         /* //uncomment to auto-advance between stage1 and stage2
00185                          *
00186                          * mFiringDeviceID = FiringDeviceID::DropperStage2
00187                          */
00188                 }
00189                 else if(mDropperState == DropperState::Stage2Reset)
00190                 {
00191                         cout << "Dropper stage2 reset" << endl;
00192                         mDropperState = DropperState::AllIdle;
00193                 }
00194         }
00195 
00196         /*****************************************
00197         ** fire devices, then reset firing mode **
00198         *****************************************/
00199         if (mShooterState == ShooterState::Firing)
00200         {
00201                 fireDevice(FiringDeviceID::Shooter);
00202                 mShooterState = ShooterState::Reset;
00203         }
00204         else if(mDropperState == DropperState::Stage1Dropping)
00205         {
00206                 fireDevice(FiringDeviceID::DropperStage1);
00207                 mDropperState = DropperState::Stage1Reset;
00208         }
00209         else if(mDropperState == DropperState::Stage2Dropping)
00210         {
00211                 fireDevice(FiringDeviceID::DropperStage2);
00212                 mDropperState = DropperState::Stage2Reset;
00213         }
00214 
00215         //done
00216 
00217         int accelX, accelY, accelZ;
00218         int compassHeading, compassPitch, compassRoll;
00219         int internalPressure, externalPressure;
00220         int headingK, headingP, headingD, headingI, headingOutput;
00221         int depthK, depthP, depthD, depthI, depthOutput;
00222         char killSwitch;
00223         //  int thruster1,  thruster2,  thruster3,  thruster4,  thruster5,  thruster6;
00224 
00225         itsStemMutex.lock();
00226         bool successful = itsStem->getSensors(accelX, accelY, accelZ, compassHeading, compassPitch, compassRoll, internalPressure, externalPressure, itsDesiredHeading, itsDesiredDepth, itsDesiredSpeed, headingK, headingP, headingD, headingI, headingOutput, depthK, depthP, depthD, depthI, depthOutput, killSwitch);
00227 
00228         itsUpdateMutex.lock();
00229         int tempHeading = itsUpdateHeading;
00230         int tempDepth = itsUpdateDepth;
00231         int tempSpeed = itsUpdateSpeed;
00232         itsUpdateMutex.unlock();
00233 
00234         if (itsLastUpdateHeading != tempHeading)
00235         {
00236                 itsLastUpdateHeading = tempHeading;
00237                 itsStem->setDesiredHeading(tempHeading);
00238         }
00239         if (itsLastUpdateDepth != tempDepth)
00240         {
00241                 itsLastUpdateDepth = tempDepth;
00242                 itsStem->setDesiredDepth(tempDepth);
00243         }
00244         if (itsLastUpdateSpeed != tempSpeed)
00245         {
00246                 itsLastUpdateSpeed = tempSpeed;
00247                 itsStem->setDesiredSpeed(tempSpeed);
00248         }
00249 
00250         itsStemMutex.unlock();
00251         if (successful)
00252         {
00253 
00254                 RobotSimEvents::BeeStemMessagePtr msg = new RobotSimEvents::BeeStemMessage;
00255 
00256                 msg->accelX = accelX;
00257                 msg->accelY = accelY;
00258                 msg->accelZ = accelZ;
00259                 msg->compassHeading = compassHeading;
00260                 msg->compassPitch = compassPitch;
00261                 msg->compassRoll = compassRoll;
00262                 msg->internalPressure = internalPressure;
00263                 msg->externalPressure = externalPressure;
00264                 msg->desiredHeading = itsDesiredHeading;
00265                 msg->desiredDepth = itsDesiredDepth;
00266                 msg->desiredSpeed = itsDesiredSpeed;
00267                 msg->headingK = headingK;
00268                 msg->headingP = headingP;
00269                 msg->headingD = headingD;
00270                 msg->headingI = headingI;
00271                 msg->headingOutput = headingOutput;
00272                 msg->depthK = depthK;
00273                 msg->depthP = depthP;
00274                 msg->depthD = depthD;
00275                 msg->depthI = depthI;
00276                 msg->depthOutput = depthOutput;
00277                 msg->killSwitch = killSwitch;
00278 
00279                 this->publish("BeeStemMessageTopic", msg);
00280 
00281                 //       char* str = new char[32];
00282                 //       sprintf(str, "\n%04d", externalPressure);
00283 
00284                 //       itsKillSwitch->write(str,32);
00285 
00286                 //       delete str;
00287         }
00288         else if (!successful)
00289                 LINFO("Error reading from BeeStem");
00290 
00291 }
00292 
00293 void BeeStemI::fireDevice(int deviceID)
00294 {
00295         switch(deviceID)
00296         {
00297         case FiringDeviceID::Shooter:
00298                 cout << "Firing torpedo!" << endl;
00299                 itsStem->setThruster(BeeStem3::MotorControllerIDs::SHOOTER, 95);
00300                 usleep(50 * 1000);
00301                 itsStem->setThruster(BeeStem3::MotorControllerIDs::SHOOTER, 0);
00302                 mShooterState = ShooterState::Reset;
00303                 break;
00304         case FiringDeviceID::DropperStage1:
00305                 cout << "Dropping first marker!" << endl;
00306                 itsStem->setThruster(BeeStem3::MotorControllerIDs::DROPPER_STAGE1, 95);
00307                 usleep(50 * 1000);
00308                 itsStem->setThruster(BeeStem3::MotorControllerIDs::DROPPER_STAGE1, 0);
00309                 mDropperState = DropperState::Stage1Reset;
00310                 break;
00311         case FiringDeviceID::DropperStage2:
00312                 cout << "Dropping second marker!" << endl;
00313                 itsStem->setThruster(BeeStem3::MotorControllerIDs::DROPPER_STAGE2, 95);
00314                 usleep(50 * 1000);
00315                 itsStem->setThruster(BeeStem3::MotorControllerIDs::DROPPER_STAGE2, 0);
00316                 mDropperState = DropperState::Stage2Reset;
00317                 break;
00318         }
00319 }
00320 
00321 // ######################################################################
00322 void BeeStemI::updateMessage(const RobotSimEvents::EventMessagePtr& eMsg, const Ice::Current&)
00323 {
00324         // Get a XBox360RemoteControl Message
00325         if (eMsg->ice_isA("::RobotSimEvents::JoyStickControlMessage"))
00326         {
00327                 RobotSimEvents::JoyStickControlMessagePtr msg = RobotSimEvents::JoyStickControlMessagePtr::dynamicCast(eMsg);
00328                 LINFO("Got message %d %s %d",msg->axis,msg->axisName.c_str(), msg->axisVal);
00329 
00330                 itsJSMappings[XBox360RemoteControl::Keys::Actions::toInt[msg->axisName]] = msg->axisVal;
00331 
00332                 static bool deviceCycleBtnWaitingReset = false; //prevent it from cycling really f-ing fast through devices
00333                 if(XBox360RemoteControl::Keys::Actions::toInt[msg->axisName] == XBox360RemoteControl::Keys::Actions::ARM_NEXT_DEV)
00334                 {
00335                         if(msg->axisVal > 0 && !deviceCycleBtnWaitingReset)
00336                         {
00337                                 mFiringDeviceID = mFiringDeviceID >= FiringDeviceID::MAX ? FiringDeviceID::Null : mFiringDeviceID + 1;
00338                                 deviceCycleBtnWaitingReset = true;
00339                         }
00340                         else if(msg->axisVal < 0 && !deviceCycleBtnWaitingReset)
00341                         {
00342                                 mFiringDeviceID = mFiringDeviceID <= FiringDeviceID::Null ? FiringDeviceID::MAX : mFiringDeviceID - 1;
00343                                 deviceCycleBtnWaitingReset = true;
00344                         }
00345                         else if(msg->axisVal == 0 && deviceCycleBtnWaitingReset)
00346                         {
00347                                 deviceCycleBtnWaitingReset = false;
00348                                 printf(mFiringDeviceID == FiringDeviceID::Null ? "All devices set to be disarmed\n" : "Device %d set to be armed\n", mFiringDeviceID);
00349                         }
00350                 }
00351 
00352                 if (msg->button >= 0)
00353                 {
00354                         itsButValues[msg->button] = msg->butVal;
00355                 }
00356 
00357                 mFlags.needsUpdateFromJoystick = true;
00358         }
00359         else if (eMsg->ice_isA("::RobotSimEvents::BeeStemMotorControllerMessage"))
00360         {
00361                 RobotSimEvents::BeeStemMotorControllerMessagePtr msg = RobotSimEvents::BeeStemMotorControllerMessagePtr::dynamicCast(eMsg);
00362                 //cout << "setting motor values..." << endl;
00363                 for (unsigned int i = 0; i < msg->values.size(); i++)
00364                 {
00365                         // printf("%d|%d : ", i, msg->values[i]);
00366                         if(msg->mask[i] == 1)
00367                                 itsStem->setThruster(i, msg->values[i]);
00368                 }
00369                 //cout << endl;
00370         }
00371         // Get a BeeStemConfig Message
00372         else if (eMsg->ice_isA("::RobotSimEvents::BeeStemConfigMessage"))
00373         {
00374                 RobotSimEvents::BeeStemConfigMessagePtr msg = RobotSimEvents::BeeStemConfigMessagePtr::dynamicCast(eMsg);
00375 
00376                 //      int h,d,s;
00377                 if (msg->deviceToFire && msg->deviceToFire != FiringDeviceID::Null) //so...yeah we can't fire a device and update PID at the same time, NBD
00378                 {
00379                         fireDevice(msg->deviceToFire);
00380                 }
00381                 else if (msg->enablePID == 1)
00382                 {
00383                         itsStemMutex.lock();
00384                         if (msg->enableVal == 1)
00385                                 itsStem->setPID(3, msg->headingK, msg->headingP, msg->headingI, msg->headingD);
00386                         else
00387                                 itsStem->setPID(2, msg->headingK, msg->headingP, msg->headingI, msg->headingD);
00388                         itsStemMutex.unlock();
00389                 }
00390                 else if (msg->updateHeadingPID == 0 && msg->updateDepthPID == 0)
00391                 {
00392                         itsUpdateMutex.lock();
00393 
00394                         LINFO("Update Pose: %d\n",msg->updateDesiredValue);
00395                         if (msg->updateDesiredValue == 1)
00396                                 itsUpdateHeading = msg->desiredHeading;
00397                         else if (msg->updateDesiredValue == 2)
00398                                 itsUpdateDepth = msg->desiredDepth;
00399                         else if (msg->updateDesiredValue == 3)
00400                                 itsUpdateSpeed = msg->desiredSpeed;
00401 
00402                         itsUpdateMutex.unlock();
00403                 }
00404                 else if (msg->updateDepthPID == 1)
00405                 {
00406                         itsStemMutex.lock();
00407                         itsStem->setPID(0, msg->depthK, msg->depthP, msg->depthI, msg->depthD);
00408                         itsStemMutex.unlock();
00409                 }
00410                 else if (msg->updateHeadingPID == 1)
00411                 {
00412                         itsStemMutex.lock();
00413                         itsStem->setPID(1, msg->headingK, msg->headingP, msg->headingI, msg->headingD);
00414                         itsStemMutex.unlock();
00415                 }
00416         }
00417 }
00418 
00419 void BeeStemI::getMotorControllerMsg(RobotSimEvents::BeeStemMotorControllerMessagePtr & msg, int mc0, int mc1, int mc2, int mc3, int mc4, int mc5, int mc6, int mc7, int mc8)
00420 {
00421         vector<int> values;
00422         values.resize(BeeStem3::NUM_MOTOR_CONTROLLERS);
00423         values[BeeStem3::MotorControllerIDs::FWD_LEFT_THRUSTER] = mc0;
00424         values[BeeStem3::MotorControllerIDs::FWD_RIGHT_THRUSTER] = mc1;
00425         values[BeeStem3::MotorControllerIDs::STRAFE_BACK_THRUSTER] = mc2;
00426         values[BeeStem3::MotorControllerIDs::STRAFE_FRONT_THRUSTER] = mc3;
00427         values[BeeStem3::MotorControllerIDs::DEPTH_LEFT_THRUSTER] = mc4;
00428         values[BeeStem3::MotorControllerIDs::DEPTH_RIGHT_THRUSTER] = mc5;
00429         values[BeeStem3::MotorControllerIDs::SHOOTER] = mc6;
00430         values[BeeStem3::MotorControllerIDs::DROPPER_STAGE1] = mc7;
00431         values[BeeStem3::MotorControllerIDs::DROPPER_STAGE2] = mc8;
00432         msg->values = values;
00433 }
00434 
Generated on Sun May 8 08:41:32 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3