SeaBee.C

Go to the documentation of this file.
00001 /*!@file BeoSub/SeaBee.C An autonomous submarine with one ballast*/
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/BeoSub/SeaBee.C $
00035 // $Id: SeaBee.C 8521 2007-06-28 17:45:49Z rjpeters $
00036 //
00037 
00038 #include "BeoSub/SeaBee.H"
00039 #include "Devices/HMR3300.H"
00040 //#include "BeoSub/BeoSubBallast.H"
00041 #include "BeoSub/BeoSubIMU.H"
00042 #include "Util/MathFunctions.H"
00043 #include "Devices/FrameGrabberFactory.H"
00044 
00045 // ######################################################################
00046 //! Class definition for BeoSubListener
00047 /*! This is the listener class that is attached to each BeoChip in the
00048   ballast tube of the submarine. This class is just a
00049   pass-through to the function dispatchBeoChipEvent() of class
00050   SeaBee. */
00051 class BeoSubListener : public BeoChipListener
00052 {
00053 public:
00054   //! Constructor
00055   BeoSubListener(SeaBee *sub) : itsBeoSub(sub)  { }
00056 
00057   //! destructor
00058   virtual ~BeoSubListener()  { }
00059 
00060   //! get an event
00061   virtual void event(const BeoChipEventType t, const int valint,
00062                      const float valfloat)
00063   {
00064     //LDEBUG("Event: %d val = %d, fval = %f", int(t), valint, valfloat);
00065     itsBeoSub->dispatchBeoChipEvent(t, valint, valfloat);
00066   }
00067 
00068 private:
00069   SeaBee *itsBeoSub;        //!< pointer to our master
00070 };
00071 
00072 
00073 
00074 
00075 // ######################################################################
00076 SeaBee::SeaBee(OptionManager& mgr) :
00077   BeoSub(mgr),
00078   //  itsIMU(new BeoSubIMU(mgr)),
00079   // itsLeftThrusterServoNum("BeoSubLeftThrusterServoNum", this, 3),
00080   //itsRightThrusterServoNum("BeoSubRightThrusterServoNum", this, 2),
00081   //itsHMR3300(new HMR3300(mgr)),
00082   itsBeo(new BeoChip(mgr, "BeoChip", "BeoChip"))
00083 //  itsFballast(new BeoSubBallast(mgr, "Front Ballast", "FrontBallast")),
00084 //  itsRballast(new BeoSubBallast(mgr, "Rear Ballast", "RearBallast")),
00085 //  itsCameraFront(makeIEEE1394grabber(mgr, "Front Camera", "FrontCamera")),
00086 //  itsCameraDown(makeIEEE1394grabber(mgr, "Down Camera", "DownCamera")),
00087 //  itsCameraUp(makeIEEE1394grabber(mgr, "Up Camera", "UpCamera")),
00088 //   itsDepthSensor(30, 0.99999F),
00089 //   itsHeadingSensor(3, 0.99999F),
00090 //   itsPitchSensor(3, 0.99999F),
00091 //   itsDepthPID(0.001F, 0.0F, 0.1F, 3.0F, 3.0F),
00092 //   itsHeadingPID(0.002F, 0.0F, 0.03F, Angle(170.0), Angle(170.0)),
00093 //   itsPitchPID(0.001F, 0.0F, 0.1F, Angle(170.0), Angle(170.0)),
00094 //   itsRotVelPID(0.3, 0.0001, 0, -500, 500),
00095 //   itsDepthPIDon(false),
00096 //   itsHeadingPIDon(false),
00097 //   itsPitchPIDon(false),
00098 //   itsRotVelPIDon(false),
00099 //   itsKillSwitchUsed(false),
00100 //   itsDiveSetting(0.0F),
00101 //   itsPitchSetting(0.0F),
00102 //   itsLastHeadingTime(0.0),
00103 //   itsLastPitchTime(0.0),
00104 //   itsLastDepthTime(0.0),
00105 // #ifdef HAVE_LINUX_PARPORT_H
00106 //   lp0(new ParPort(mgr)),
00107 //   markerdropper(lp0),
00108 // #endif
00109 //   killSwitchDebounceCounter(0)
00110 
00111 //   itsLeftHThrusterServoNum("BeoSubLeftHThrusterServoNum", this, 4),
00112 //   itsRightHThrusterServoNum("BeoSubRightHThrusterServoNum", this, 5),
00113 //   itsBeo(new BeoChip(mgr, "BeoChip", "BeoChip")),
00114 //   itsDiveSetting(0.0F)
00115 {
00116 
00117 
00118         //GRAB image from camera to be tested
00119                 //gb->setModelParamVal("FrameGrabberFPS", 15.0F);
00120 
00121 
00122 // itsCameraFront->setModelParamVal("FrameGrabberSubChan", 0);
00123 // itsCameraFront->setModelParamVal("FrameGrabberBrightness", 128);
00124 // itsCameraFront->setModelParamVal("FrameGrabberHue", 180);
00125 // itsCameraFront->setModelParamVal("FrameGrabberNbuf", 2);
00126 
00127 /*
00128 itsCameraDown->setModelParamVal("FrameGrabberSubChan", 0);
00129 itsCameraDown->setModelParamVal("FrameGrabberBrightness", 128);
00130 itsCameraDown->setModelParamVal("FrameGrabberHue", 180);
00131 itsCameraDown->setModelParamVal("FrameGrabberNbuf", 2);
00132 
00133 itsCameraUp->setModelParamVal("FrameGrabberSubChan", 0);
00134 itsCameraUp->setModelParamVal("FrameGrabberBrightness", 128);
00135 itsCameraUp->setModelParamVal("FrameGrabberHue", 180);
00136 itsCameraUp->setModelParamVal("FrameGrabberNbuf", 2);
00137 */
00138 
00139   // register our babies as subcomponents:
00140 
00141 //   addSubComponent(itsBeo);
00142 
00143 //   // reset the BeoChip:
00144 //   LINFO("Resetting the BeoChip...");
00145 //   itsBeo->reset(MC_RECURSE);
00146 //   usleep(200000);
00147 
00148 //   // connect our listener to our beochip:
00149 //   rutz::shared_ptr<BeoChipListener> b(new BeoSubListener(this));
00150 //   itsBeo->setListener(b);
00151 
00152 //   // connect our listener to our compass:
00153 //   rutz::shared_ptr<HMR3300Listener> bl(new HMRlistener(this));
00154 //   itsHMR3300->setListener(bl);
00155 
00156 //   rutz::shared_ptr<BeoSubIMUListener> imu(new IMUListener(this));
00157 //   itsIMU->setListener(imu);
00158 
00159 //   // hook up BeoChips to Ballasts:
00160 // //  itsFballast->setBeoChip(itsBeo);
00161 // //  itsRballast->setBeoChip(itsBeo);
00162 
00163 //   // disable RTS/CTS flow control on our BeoChips:
00164 //   itsBeo->setModelParamVal("BeoChipUseRTSCTS", false);
00165 
00166 //   // select default serial ports for everybody:
00167 //   itsBeo->setModelParamString("BeoChipDeviceName", "/dev/ttyS1");
00168 
00169   //mgr.loadConfig("camconfig.pmap");
00170 }
00171 
00172 // ######################################################################
00173 SeaBee::~SeaBee()
00174 {  }
00175 
00176 void SeaBee::test() {
00177 for (int i=0; i < 5; i++) {
00178         printf("Running Servo %d\n", i);
00179         itsBeo->setServoRaw(i, 255);
00180         sleep(2);
00181         itsBeo->setServoRaw(i, 127);
00182         sleep(2);
00183         itsBeo->setServoRaw(i, 0);
00184         sleep(2);
00185         itsBeo->setServoRaw(i, 127);
00186 }
00187 
00188 
00189 Raster::waitForKey();
00190 
00191 float x;
00192 while(true) {
00193 
00194         x = itsBeo->getAnalog(0);
00195         printf("Pressure Sensor value: %f\n", x);
00196         }
00197 }
00198 
00199 // ######################################################################
00200 void SeaBee::start1()
00201 {
00202   // don't forget to call start1() on our base class!
00203   BeoSub::start1();
00204 }
00205 
00206 // ######################################################################
00207 void SeaBee::start2()
00208 {
00209   // turn on the analog port capture for the pressure sensor, do not
00210   // capture pulses:
00211   /* itsBeo->captureAnalog(0, true);
00212   itsBeo->captureAnalog(1, false);
00213   itsBeo->capturePulse(0, false);
00214   itsBeo->capturePulse(1, false);
00215   */
00216 
00217   // set all servos to neutral:
00218   for (int i = 0; i < 8; i ++) itsBeo->setServo(i, 0.0F);
00219 
00220   // turn on KBD capture for our ballasts:
00221   //  itsBeo->captureKeyboard(true);
00222   // itsBeo->debounceKeyboard(false);
00223 
00224 
00225   // turn the PIDs on: NOTE: first we should dive some...
00226 
00227   itsDiveSetting = 0.5F;
00228 
00229   // display sign of life:
00230   itsBeo->lcdClear();
00231   itsBeo->lcdPrintf(3, 0, " iLab and USC rock! ");
00232 
00233   // we currently don't have a start2() in our base class, but if we
00234   // add one we should call it here.
00235 }
00236 
00237 void SeaBee::stop1() {
00238         //Turn off all PID's
00239 
00240         setTransVel(0.0);
00241 
00242         //empty both balasts and  surface!
00243  //       setBallasts(0.0F, 0.0F, true);
00244 
00245 }
00246 
00247 // ######################################################################
00248 void SeaBee::advanceRel(const float relDist, const bool stop)
00249 {
00250   float d = relDist * 2.0F;
00251   // turn our heading PID off as it may interfere with our commands of
00252   // the thrusters:
00253   //  bool hpid = itsHeadingPIDon;
00254   // useHeadingPID(false);
00255 
00256   // just pulse the thrusters:
00257   if (fabsf(d) < 1.0F)
00258     {
00259         setTransVel(d);
00260       sleep(1);
00261       if (stop)
00262         {
00263         setTransVel(-d);
00264           usleep(350000);
00265         }
00266     }
00267   else
00268     {
00269       float forward = 1.0F, reverse = -1.0F;
00270       if (d < 0.0F) { forward = -forward; reverse = -reverse; }
00271 
00272       // thrust at full forward:
00273       setTransVel(forward);
00274 
00275       // for a time that is proportional to distance. Note: we will
00276       // reach steady-state speed after about 1sec:
00277       usleep(int(fabsf(d) * 1000000));
00278 
00279       if (stop)
00280         {
00281           // now, to stop, thrust full reverse:
00282           setTransVel(reverse);
00283 
00284           // for one second:
00285           sleep(1);
00286         }
00287     }
00288 
00289   // stop
00290   setTransVel(0);
00291 
00292   itsGlobalPosition.x += relDist * cos(itsGlobalHeading.getRadians());
00293   itsGlobalPosition.y += relDist * sin(itsGlobalHeading.getRadians());
00294 
00295   // useHeadingPID(hpid);
00296 }
00297 
00298 void SeaBee::updateThrusters() {
00299   float left = TransVelCommand;// + RotVelCommand;
00300   float right = TransVelCommand;// - RotVelCommand;
00301 
00302         if (left > 1) left = 1;
00303         else if (left < -1) left = -1;
00304 
00305         if (right > 1) right = 1;
00306         else if (right < -1) right = -1;
00307 
00308         thrust(left, right);
00309 }
00310 
00311 
00312 void SeaBee::setTransVel(const float desired) {
00313         //desiredTransVel = desired;
00314         TransVelCommand = desired; /* open loop for now */
00315         updateThrusters();
00316 }
00317 
00318 
00319 // ######################################################################
00320 void SeaBee::updateDepth(const float depth)
00321 {
00322   /*
00323   float left = TransVelCommand;// + RotVelCommand;
00324   float right = TransVelCommand;// - RotVelCommand;
00325 
00326         if (left > 1) left = 1;
00327         else if (left < -1) left = -1;
00328 
00329         if (right > 1) right = 1;
00330         else if (right < -1) right = -1;
00331 
00332         thrust(left, right);
00333   */
00334 
00335 
00336   // note the time at which the data was received:
00337   /*  double t = itsMasterClock.getSecs();
00338 
00339   pthread_mutex_lock(&itsLock);
00340 
00341   // update our depth sensor:
00342   itsDepthSensor.newMeasurement(depth);
00343 
00344   // inject these values into our current attitude:
00345   itsCurrentAttitude.depth = itsDepthSensor.getValue();
00346   itsCurrentAttitude.pressureTime = t;
00347   const float tdepth = itsTargetAttitude.depth;
00348 
00349   // also update our depth PID and adjust ballasts:
00350   if (itsDepthPIDon && t >= itsLastDepthTime + 0.5)
00351     {
00352       // feed the PID controller:
00353       const float dcmd = itsDepthPID.update(tdepth, itsDepthSensor.getValue());
00354 
00355       // update and limit our dive setting:
00356       itsDiveSetting += dcmd;
00357       if (itsDiveSetting < 0.0F) itsDiveSetting = 0.0F;
00358       else if (itsDiveSetting > 1.0F) itsDiveSetting = 1.0F;
00359 
00360       // adjust the ballasts: itsDiveSetting provides the mean, while
00361       // itsPitchSetting provides the deviation:
00362       float f = itsDiveSetting - itsPitchSetting;
00363       float r = itsDiveSetting + itsPitchSetting;
00364       if (f < 0.0F) f = 0.0F; else if (f > 1.0F) f = 1.0F;
00365       if (r < 0.0F) r = 0.0F; else if (r > 1.0F) r = 1.0F;
00366 //      setBallasts(f, r);
00367 
00368       // remember when we did all this:
00369       itsLastDepthTime = t;
00370 
00371       LINFO("dcmd = %f at t=%f", dcmd, t);
00372     }
00373 
00374   pthread_mutex_unlock(&itsLock);
00375   */
00376 
00377 }
00378 
00379 // ######################################################################
00380 void SeaBee::thrust(const float leftval, const float rightval)
00381 {
00382         // note: if the value is out of range, the BeoChip will clamp it.
00383         // That's why we read it back from the BeoChip before displaying it:
00384 //         itsBeo->setServo(itsLeftHThrusterServoNum.getVal(), leftval);
00385 //         itsThrustLeftH = itsBeo->getServo(itsLeftHThrusterServoNum.getVal());
00386 
00387 //         itsBeo->setServo(itsRightHThrusterServoNum.getVal(), rightval);
00388 //         itsThrustRightH = itsBeo->getServo(itsRightHThrusterServoNum.getVal());
00389 
00390         //LINFO("Th=%-1.2f/%-1.2f", itsThrustLeft, itsThrustRight);
00391 }
00392 
00393 void SeaBee::dive(const float leftval, const float rightval)
00394 {
00395         // note: if the value is out of range, the BeoChip will clamp it.
00396         // That's why we read it back from the BeoChip before displaying it:
00397 //         itsBeo->setServo(itsLeftVThrusterServoNum.getVal(), leftval);
00398 //         itsThrustLeftV = itsBeo->getServo(itsLeftVThrusterServoNum.getVal());
00399 
00400 //         itsBeo->setServo(itsRightVThrusterServoNum.getVal(), rightval);
00401 //         itsThrustRightV = itsBeo->getServo(itsRightVThrusterServoNum.getVal());
00402 
00403         //LINFO("Th=%-1.2f/%-1.2f", itsThrustLeft, itsThrustRight);
00404 }
00405 
00406 // ######################################################################
00407 void SeaBee::getThrusters(float& leftval, float& rightval) const
00408 { leftval = itsThrustLeftH; rightval = itsThrustRightH; }
00409 
00410 
00411 
00412 // ######################################################################
00413 void SeaBee::getDiveThrusters(float& leftval, float& rightval) const
00414 { leftval = itsThrustLeftV; rightval = itsThrustRightV; }
00415 
00416 // ######################################################################
00417 void SeaBee::dispatchBeoChipEvent(const BeoChipEventType t,
00418                                   const int valint,
00419                                   const float valfloat)
00420 {
00421   // what is this event about and whom is it for?
00422   switch(t)
00423     {
00424     case NONE: // ##############################
00425       LERROR("Unexpected BeoChip NONE event!");
00426       break;
00427 
00428     case PWM0: // ##############################
00429       LERROR("Unexpected BeoChip PWM0 event!");
00430       break;
00431 
00432     case PWM1: // ##############################
00433       LERROR("Unexpected BeoChip PWM1 event!");
00434       break;
00435 
00436     case KBD: // ##############################
00437       LDEBUG("Keyboard: new value %d", valint);
00438       // current diagram is:
00439       // #0 = front full/empty switch
00440       // #1 = front gear encoder
00441       // #2 = rear full/empty switch
00442       // #3 = rear gear encoder
00443       // #4 = kill switch
00444 
00445       // let both ballast units know:
00446   //    itsFballast->input(valint);
00447    //   itsRballast->input(valint);
00448 
00449       //check if kill switch is activated
00450       //disabled due to kill-switch/start-switch multi-use - khooyp
00451       //if (valint & 0x10 != 0 && itsKillSwitchUsed) killSwitch();
00452       break;
00453 
00454     case ADC0: // ##############################
00455       {
00456         //LINFO("ADC0 new value = %d", valint);
00457         // the ADC0 is connected to the pressure sensor. Convert to
00458         // meters, with positive going down (so the deeper we are, the
00459         // larger the positive reading). Then update the depth reading:
00460 
00461         // A reading of 255 corresponds to 2.5V, given our 2.5V
00462         // reference voltage on the BeoChip's ADC lines:
00463         float depth = (float(valint) * 2.5F) / 255.0F;  // in volts
00464 
00465         // I here assume that the sensor is an ASDX100A24R: NOTE: a
00466         // 220nF cap is required on the supply line.
00467 
00468         // the sensor has a 0.5V offset (i.e., outputs 0.5V when
00469         // pressure is 0):
00470         depth -= 0.5F;
00471 
00472         // An ASDX100A24R has a resolution of 0.040V/psi:
00473         depth /= 0.040F; // now in psi
00474 
00475         // convert from PSI to meters: at the surface, we have 14.7
00476         // psi (= 1 atmosphere); then it's about 0.44 psi/foot, i.e.,
00477         // 1.443 psi/m:
00478         depth = (depth - 14.275F) / 1.443F;
00479 
00480         // NOTE: convention in the rest of the code is positive depth
00481         // the more we go down:
00482         updateDepth(depth);
00483       }
00484       break;
00485 
00486     case ADC1: // ##############################
00487       LERROR("Unexpected BeoChip ADC1 event!");
00488       break;
00489 
00490     case RESET: // ##############################
00491       LERROR("BeoChip RESET!");
00492       break;
00493 
00494     case ECHOREP: // ##############################
00495       LINFO("BeoChip Echo reply.");
00496       break;
00497 
00498     case INOVERFLOW: // ##############################
00499       LERROR("BeoChip input overflow!");
00500       break;
00501 
00502     case SERIALERROR: // ##############################
00503       LERROR("BeoChip serial error!");
00504       break;
00505 
00506     case OUTOVERFLOW: // ##############################
00507       LERROR("BeoChip output overflow!");
00508       break;
00509 
00510     default: // ##############################
00511       LERROR("BeoChip unknown event %d!", int(t));
00512       break;
00513     }
00514 
00515 
00516 }
00517 
00518 void SeaBee::turnOpen(Angle ang, bool b) {
00519 
00520 
00521 }
00522 
00523 void SeaBee::dropMarker(bool b) {
00524 
00525 }
00526 
00527 Image<PixRGB <byte> > SeaBee::grabImage(BeoSubCamera bsc) const {
00528   return *(new Image<PixRGB <byte> >);
00529 
00530 }
00531 // ######################################################################
00532 /* So things look consistent in everyone's emacs... */
00533 /* Local Variables: */
00534 /* indent-tabs-mode: nil */
00535 /* End: */
Generated on Sun May 8 08:04:33 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3