BeoSub.C

Go to the documentation of this file.
00001 /*!@file BeoSub/BeoSub.C An autonomous submarine */
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/BeoSub.C $
00035 // $Id: BeoSub.C 14376 2011-01-11 02:44:34Z pez $
00036 //
00037 
00038 #include "BeoSub/BeoSub.H"
00039 
00040 #include "BeoSub/BeoSub-defs.H"
00041 #include "BeoSub/BeoSubOpts.H"
00042 #include "BeoSub/CannyModel.H"
00043 #include "Devices/FrameGrabberFactory.H"
00044 #include "Channels/RawVisualCortex.H"
00045 #include "SIFT/VisualObjectDB.H"
00046 #include "SIFT/VisualObjectMatch.H"
00047 
00048 #define DEBUG
00049 
00050 // ######################################################################
00051 BeoSub::BeoSub(OptionManager& mgr, const std::string& descrName,
00052                const std::string& tagName) :
00053   ModelComponent(mgr, descrName, tagName),
00054 
00055   itsFrontVODBfname(&OPT_FrontVODBfname, this),
00056   itsFrontVODB(new VisualObjectDB()),
00057   itsDownVODBfname(&OPT_DownVODBfname, this),
00058   itsDownVODB(new VisualObjectDB()),
00059   itsUpVODBfname(&OPT_UpVODBfname, this),
00060   itsUpVODB(new VisualObjectDB()),
00061   itsMasterClock(1000000), itsCkPt(0), itsCurrentAttitude(),
00062   itsGlobalHeading(0),
00063   itsTargetAttitude(),
00064   itsVisualCortex(new RawVisualCortex(mgr)),
00065   itsFrontDBfname("/home/tmp/u/beosub/front.db"),
00066   itsFrontDB(new BeoSubDB()),
00067   itsDownDBfname("/home/tmp/u/beosub/down.db"),
00068   itsDownDB(new BeoSubDB()),
00069   itsUpDBfname("/home/tmp/u/beosub/up.db"),
00070   itsUpDB(new BeoSubDB()),
00071   itsShapeDetector(new BeoSubCanny(mgr)),
00072   itsTaskDecoder(new BeoSubTaskDecoder(mgr)),
00073   itsColorTracker(new ColorTracker(mgr)),
00074   itsColorTracker2(new ColorTracker(mgr)),
00075   decoderIsRed(true),
00076   taskAdone(false),
00077   taskBdone(false),
00078   taskCdone(false)
00079   //itscurrentblabla
00080 {
00081   pthread_mutex_init(&itsLock, NULL);
00082   addSubComponent(itsVisualCortex);
00083   addSubComponent(itsShapeDetector);
00084 
00085   //set up default tasks order. Change if decoding is successful!
00086   itsTasks.push_back('A');
00087   itsTasks.push_back('B');
00088   itsTasks.push_back('C');
00089   itsTasksIter = itsTasks.begin();
00090 
00091   taskAposition.x = 15; taskAposition.y = 20;
00092   taskBposition.x = 5; taskBposition.y = 50;
00093   taskCposition.x = 10; taskCposition.y = 100;
00094   itsGlobalPosition.x = -19; itsGlobalPosition.y = -8;
00095   itsGlobalHeading = 60;
00096   // mgr.loadConfig("camconfig.pmap");
00097 }
00098 
00099 // ######################################################################
00100 BeoSub::~BeoSub()
00101 {
00102   pthread_mutex_destroy(&itsLock);
00103 }
00104 
00105 // ######################################################################
00106 void BeoSub::start1()
00107 {
00108 
00109   // load our visual object databases:
00110   itsFrontVODB->loadFrom(itsFrontVODBfname.getVal());
00111   itsDownVODB->loadFrom(itsDownVODBfname.getVal());
00112   itsUpVODB->loadFrom(itsUpVODBfname.getVal());
00113 
00114   // Pre-build the KDTrees on our visual object databases so that we
00115   // don't waste time on that later:
00116   if (itsFrontVODB->numObjects()) itsFrontVODB->buildKDTree();
00117   if (itsDownVODB->numObjects()) itsDownVODB->buildKDTree();
00118   if (itsUpVODB->numObjects()) itsUpVODB->buildKDTree();
00119 
00120   // load our position and sensor databases (assumes already initialized)
00121   itsFrontDB->loadDatabase(itsFrontDBfname);
00122   itsDownDB->loadDatabase(itsDownDBfname);
00123   itsUpDB->loadDatabase(itsUpDBfname);
00124 
00125   // get a hold of our special objects:
00126   itsVOtaskAdown = itsDownVODB->getObject("taskAdown");
00127   itsVOtaskAfront = itsFrontVODB->getObject("taskAfront");
00128   itsVOtaskBdown = itsDownVODB->getObject("taskBdown");
00129   itsVOtaskBfront = itsFrontVODB->getObject("taskBfront");
00130   itsVOtaskCdown = itsDownVODB->getObject("taskCdown");
00131   itsVOtaskCfront = itsFrontVODB->getObject("taskCfront");
00132   itsVOtaskCup = itsUpVODB->getObject("taskCtop");
00133   itsVOtaskGdown = itsDownVODB->getObject("taskGdown");
00134   itsVOtaskGfront = itsFrontVODB->getObject("taskGfront");
00135   itsVOtaskGup = itsUpVODB->getObject("taskGtop");
00136   itsVOtaskDfront = itsFrontVODB->getObject("taskDfront");
00137 
00138 }
00139 
00140 // ######################################################################
00141 bool BeoSub::targetReached(const float tol) const
00142 {
00143   // NOTE: we ignore pitch and roll
00144   bool ret = true;
00145   pthread_mutex_lock(const_cast<pthread_mutex_t *>(&itsLock));
00146 
00147   if (fabsf(itsCurrentAttitude.depth - itsTargetAttitude.depth) > tol * 0.2F)
00148     ret = false;
00149 
00150   Angle diff = itsCurrentAttitude.heading - itsTargetAttitude.heading;
00151   if (diff.getVal() < - tol * 10.0F || diff.getVal() > tol * 10.0F)
00152     ret = false;
00153 
00154   pthread_mutex_unlock(const_cast<pthread_mutex_t *>(&itsLock));
00155 
00156   return ret;
00157 }
00158 
00159 // ######################################################################
00160 void BeoSub::turnAbs(const Angle finalHeading, const bool blocking)
00161 {
00162   pthread_mutex_lock(&itsLock);
00163   itsTargetAttitude.heading = finalHeading;
00164   const Angle diff = finalHeading - itsCurrentAttitude.heading;
00165   pthread_mutex_unlock(&itsLock);
00166   if (blocking) waitMove(fabs(diff.getVal() * 0.5) + 30.0);
00167 }
00168 
00169 // ######################################################################
00170 void BeoSub::pitchAbs(const Angle finalPitch, const bool blocking)
00171 {
00172   pthread_mutex_lock(&itsLock);
00173   itsTargetAttitude.pitch = finalPitch;
00174   const Angle diff = finalPitch - itsCurrentAttitude.pitch;
00175   pthread_mutex_unlock(&itsLock);
00176   if (blocking) waitMove(fabs(diff.getVal() * 0.5) + 30.0);
00177 }
00178 
00179 // ######################################################################
00180 void BeoSub::turnRel(const Angle relHeading, const bool blocking)
00181 {
00182   /*
00183   pthread_mutex_lock(&itsLock);
00184   itsTargetAttitude.heading += relHeading;
00185   pthread_mutex_unlock(&itsLock);
00186   if (blocking) waitMove(fabs(relHeading.getVal() * 0.5) + 30.0);
00187   */
00188   //ANDRE -- NOTE: GlobalHeading value
00189   itsGlobalHeading = itsGlobalHeading + relHeading;
00190   turnOpen(relHeading, blocking);
00191 }
00192 
00193 // ######################################################################
00194 void BeoSub::diveAbs(const float finalDepth, const bool blocking)
00195 {
00196   pthread_mutex_lock(&itsLock);
00197   itsTargetAttitude.depth = finalDepth;
00198   pthread_mutex_unlock(&itsLock);
00199   if (blocking)
00200     waitMove(fabs(finalDepth - itsCurrentAttitude.depth) * 5.0 + 30.0);
00201 }
00202 
00203 // ######################################################################
00204 void BeoSub::diveRel(const float relDepth, const bool blocking)
00205 {
00206   pthread_mutex_lock(&itsLock);
00207   itsTargetAttitude.depth += relDepth;
00208   pthread_mutex_unlock(&itsLock);
00209   if (blocking) waitMove(fabs(relDepth) * 5.0 + 30.0);
00210 }
00211 
00212 // ######################################################################
00213 //NOTE: This will work with open turn as an open strafe. FIX?
00214 void BeoSub::strafeRel(const float relDist)
00215 {
00216   // assume we are immobile. First, turn by some angle, then go
00217   // backwards, then turn back, then forward. The first turn (only)
00218   // should have rst true. All calls should have blocking to true.
00219   double alpha = relDist * 30.0; // turn by 30deg if 1m strafe
00220   if (alpha > 80.0) alpha = 80.0; else if (alpha < -80.0) alpha = -80.0;
00221   if (fabs(alpha) < 1.0)
00222     { LERROR("Strafe too small -- IGNORED"); return; }
00223 
00224   // more precisely, if we are going to turn by alpha and want to
00225   // strafe by reldist, we should turn by alpha then go backwards by
00226   // relDist/sin(alpha), then turn back by -alpha, finally advance by
00227   // relDist/tan(alpha). Let's do it:
00228   turnRel(Angle(alpha), true);
00229   advanceRel(-fabs(relDist / sin(alpha * M_PI / 180.0)));
00230   turnRel(Angle(alpha), true);
00231   advanceRel(fabs(relDist / tan(alpha * M_PI / 180.0)));
00232 }
00233 
00234 // ######################################################################
00235 void BeoSub::waitMove(const double timeout)
00236 {
00237   // Wait until the desired attitude has been reached. Note: in the
00238   // base class, this will never happen since we have no actuation. In
00239   // derived classes there should be some function running in a thread
00240   // that will activate the various actuators so as to try to reduce
00241   // the difference between itsTargetAttitude and itsCurrentAttitude:
00242 
00243   double startt = itsMasterClock.getSecs();
00244   while(targetReached() == false &&
00245         itsMasterClock.getSecs() - startt < timeout) usleep(200000);
00246 
00247   if (targetReached() == false)
00248     LERROR("Timeout occurred on move -- IGNORED");
00249 }
00250 
00251 // ######################################################################
00252 double BeoSub::getTime() const
00253 { return itsMasterClock.getSecs(); }
00254 
00255 // ######################################################################
00256 Attitude BeoSub::getCurrentAttitude() const
00257 {
00258   pthread_mutex_lock(const_cast<pthread_mutex_t *>(&itsLock));
00259   Attitude att = itsCurrentAttitude;
00260   pthread_mutex_unlock(const_cast<pthread_mutex_t *>(&itsLock));
00261   return att;
00262 }
00263 
00264 // ######################################################################
00265 Attitude BeoSub::getTargetAttitude() const
00266 {
00267   pthread_mutex_lock(const_cast<pthread_mutex_t *>(&itsLock));
00268   Attitude att = itsTargetAttitude;
00269   pthread_mutex_unlock(const_cast<pthread_mutex_t *>(&itsLock));
00270   return att;
00271 }
00272 
00273 // ######################################################################
00274 Angle BeoSub::getHeading() const
00275 { return getCurrentAttitude().heading; }
00276 
00277 // ######################################################################
00278 Angle BeoSub::getPitch() const
00279 { return getCurrentAttitude().pitch; }
00280 
00281 // ######################################################################
00282 Angle BeoSub::getRoll() const
00283 { return getCurrentAttitude().roll; }
00284 
00285 // ######################################################################
00286 void BeoSub::getCompass(Angle& heading, Angle& pitch, Angle& roll) const
00287 {
00288   Attitude att = getCurrentAttitude();
00289   heading = att.heading; pitch = att.pitch; roll = att.roll;
00290 }
00291 
00292 // ######################################################################
00293 float BeoSub::getDepth() const
00294 { return getCurrentAttitude().depth; }
00295 
00296 // ######################################################################
00297 const char* beoSubCameraName(const BeoSubCamera cam)
00298 {
00299   if (cam == BEOSUBCAMFRONT) return "Front";
00300   if (cam == BEOSUBCAMDOWN) return "Down";
00301   if (cam == BEOSUBCAMUP) return "Up";
00302   LERROR("Unknown BeoSubCamera value %d", int(cam));
00303   return "Unknown";
00304 }
00305 
00306 // ######################################################################
00307 Image<float> BeoSub::getSaliencyMap(const enum BeoSubCamera cam) const
00308 {
00309   Image< PixRGB<byte> > img = grabImage(cam);
00310   itsVisualCortex->input(InputFrame::fromRgb
00311                          (&img, itsMasterClock.getSimTime()));
00312   return itsVisualCortex->getOutput();
00313 }
00314 
00315 // ######################################################################
00316 bool BeoSub::recognizeSIFT(const enum BeoSubCamera cam,
00317                            MappingData& data, Angle& myHeading) const
00318 {
00319   // grab an image from the specified camera:
00320   Image< PixRGB<byte> > im = grabImage(cam);
00321 
00322   // create visual object and extract keypoints:
00323   rutz::shared_ptr<VisualObject> vo(new VisualObject("Captured Image", "", im));
00324 
00325   // get the matches:
00326   std::vector< rutz::shared_ptr<VisualObjectMatch> > matches;
00327   switch(cam)
00328     {
00329     case BEOSUBCAMFRONT:
00330       itsFrontVODB->getObjectMatches(vo, matches, VOMA_KDTREEBBF);
00331       break;
00332     case BEOSUBCAMDOWN:
00333       itsDownVODB->getObjectMatches(vo, matches, VOMA_KDTREEBBF);
00334       break;
00335     case BEOSUBCAMUP:
00336       itsUpVODB->getObjectMatches(vo, matches, VOMA_KDTREEBBF);
00337       break;
00338     default:
00339       LERROR("Wrong camera -- IGNORED");
00340     }
00341 
00342   // if we got nothing, stop here:
00343   if (matches.size() == 0U) return false;
00344 
00345   // check that we have a good affine:
00346   if (matches[0]->checkSIFTaffine() == false) return false;
00347 
00348   // compute our current heading based on the heading associated with
00349   // the matching picture and the rotation derived from the affine:
00350   SIFTaffine aff = matches[0]->getSIFTaffine();
00351   float theta, sx, sy, str;
00352   aff.decompose(theta, sx, sy, str);
00353 
00354   // our best match is the first in the list of matches. Get its
00355   // associated image name so that we can look it up in the
00356   // appropriate BeoSubDB:
00357   std::string name = matches[0]->getVoTest()->getImageFname();
00358 
00359   // now this has a .png extension while the BeoSubDB uses .txt; let's
00360   // change that:
00361   name.replace(name.length()-3, 3, "txt");
00362 
00363   // query the appropriate metadata database:
00364   switch(cam)
00365     {
00366     case BEOSUBCAMFRONT:
00367       data = itsFrontDB->getMappingData(name);
00368       break;
00369     case BEOSUBCAMDOWN:
00370       data = itsDownDB->getMappingData(name);
00371       break;
00372     case BEOSUBCAMUP:
00373       data = itsUpDB->getMappingData(name);
00374       break;
00375     default:
00376       LERROR("Wrong camera -- IGNORED");
00377     }
00378 
00379   // get our heading from the mapping data and the sift affine:
00380   myHeading = data.itsHeading;
00381   myHeading += theta;
00382 
00383   return true;
00384 }
00385 
00386 // ######################################################################
00387 bool BeoSub::matchSIFT(const enum BeoSubCamera cam,
00388                        const rutz::shared_ptr<VisualObject>& obj) const
00389 {
00390   // grab an image from the specified camera:
00391   Image< PixRGB<byte> > im = grabImage(cam);
00392 
00393   // create visual object and extract keypoints:
00394   rutz::shared_ptr<VisualObject> vo(new VisualObject("Captured Image", "", im));
00395 
00396   // get the matches:
00397   VisualObjectMatch vom(obj, vo, VOMA_SIMPLE);
00398   vom.prune();
00399   if (vom.checkSIFTaffine() == false) return false;
00400 
00401   if (vom.getScore() >= 0.5F) return true;
00402   return false;
00403 }
00404 
00405 // ######################################################################
00406 bool BeoSub::affineSIFT(const enum BeoSubCamera cam, rutz::shared_ptr<VisualObject> goal)
00407 {
00408   float x = 160.0F, y = 120.0F;            // center of ref image
00409   const float cu = 160.0F, cv = 120.0F;  // center of test image
00410   const float factor = (5.0F - getDepth()) * 0.05F; //NOTE: rough estimate
00411   int counter = 0;
00412   while(++counter < 10)
00413     {
00414       rutz::shared_ptr<VisualObject>
00415         current(new VisualObject("current", "", grabImage(cam)));
00416       VisualObjectMatch match(goal, current, VOMA_KDTREEBBF);
00417       match.prune();
00418       if (match.size() == 0U)
00419         {
00420           LINFO("No matches found... giving up");
00421           return false;
00422         }
00423     LINFO("Found %u matches", match.size());
00424     SIFTaffine aff = match.getSIFTaffine();
00425     float u, v; aff.transform(x, y, u, v);
00426     if (fabsf(u - cu) < 10.0F)
00427       {
00428         LINFO("Good enough! -- DONE");
00429         return true;
00430       }
00431 
00432     if (cam == BEOSUBCAMDOWN)
00433       {
00434         // this camera is mounted rotated 90deg
00435         if (v < cv) { LINFO("turning left"); turnRel(-10.0F, true); }
00436         else { LINFO("turning right"); turnRel(10.0F, true); }
00437         advanceRel((u - cu) * factor);
00438       }
00439     else
00440       {
00441         if (u < cu) { LINFO("turning left"); turnRel(-10.0F, true); }
00442         else { LINFO("turning right"); turnRel(10.0F, true); }
00443       }
00444     }
00445   // counter timeout:
00446   return false;
00447 }
00448 
00449 // ######################################################################
00450 
00451 bool BeoSub::findShape(rutz::shared_ptr<ShapeModel>& shapeArg, const char* colorArg, const enum BeoSubCamera camArg) const
00452 {
00453 
00454   Image< PixRGB<byte> > im = grabImage(camArg);
00455   int numDims = shapeArg->getNumDims();
00456   double* dims = (double*)calloc(numDims+1, sizeof(double));
00457   dims = shapeArg->getDimensions();
00458 
00459   itsShapeDetector->setupCanny(colorArg, im, false);//declare detector
00460 
00461   bool shapeFound = false;
00462 
00463   //give shape detector 5 chances to work, using different starting dimensions each time
00464 
00465   //Middle
00466   dims[1] = 150.0;
00467   dims[2] = 120.0;
00468   shapeArg->setDimensions(dims);
00469   shapeFound = itsShapeDetector->runCanny(shapeArg);
00470   if(!shapeFound){ //Upper left
00471     dims[1] = 60.0; //Xcenter
00472     dims[2] = 180.0; //Ycenter
00473     shapeArg->setDimensions(dims);
00474     shapeFound = itsShapeDetector->runCanny(shapeArg);
00475   }
00476   if(!shapeFound){ //Upper right
00477     dims[1] = 260.0; //Xcenter
00478     dims[2] = 180.0; //Ycenter
00479     shapeArg->setDimensions(dims);
00480     shapeFound = itsShapeDetector->runCanny(shapeArg);
00481   }
00482   if(!shapeFound){ //Lower left
00483     dims[1] = 60.0; //Xcenter
00484     dims[2] = 60.0; //Ycenter
00485     shapeArg->setDimensions(dims);
00486     shapeFound = itsShapeDetector->runCanny(shapeArg);
00487   }
00488   if(!shapeFound){ //Lower right
00489     dims[1] = 260.0; //Xcenter
00490     dims[2] = 60.0; //Ycenter
00491     shapeArg->setDimensions(dims);
00492     shapeFound = itsShapeDetector->runCanny(shapeArg);
00493   }
00494 
00495   if(!shapeFound){
00496     return false;
00497   }
00498   return true;
00499 }
00500 
00501 // ######################################################################
00502 bool BeoSub::centerColor(const char* colorArg, const enum BeoSubCamera camArg, float& thresholdMass){
00503   Image< PixRGB<byte> > im;
00504   float x = 0.0, y = 0.0, mass = 0.0;
00505   float threshold = thresholdMass;
00506   float delta = 0;
00507   int lossCount = 0;
00508   bool checking = false;
00509   float xL = (160.0 - (threshold));
00510   float xR = (160.0 + (threshold));
00511   float yU = (120.0 - (threshold));
00512   float yD = (120.0 + (threshold));
00513   bool xOff = true, yOff = true;
00514 
00515   if(camArg == BEOSUBCAMFRONT){
00516     while(xOff){
00517       im = grabImage(camArg);
00518       itsColorTracker->setupTracker(colorArg, im, false);
00519       checking = itsColorTracker->runTracker(threshold, x, y, mass);
00520       if( checking && (x >= xL && x <= xR)){
00521         //Light centered in x plane. Now center in y
00522         xOff = false;
00523         lossCount = 0;
00524       }
00525       else if(checking){
00526         printf("Fcam turn\n");
00527         delta = x - 160.0; //delta = x_found - x_center
00528         //TURN left or right, in greater or lesser amounts depending on position
00529         turnRel(delta/2, true); //delta/2 based off of 160degree POV and 320pxl x axis
00530         lossCount = 0;
00531       }
00532       else{
00533         //Color lost. Use counter to allow for a few noisy losses, then fail
00534         lossCount++;
00535         if(lossCount >4){
00536           return false;
00537         }
00538       }
00539     }
00540     /*    while(yOff){
00541       im = grabImage(camArg);
00542       itsColorTracker->setupTracker(colorArg, im, false);
00543       checking = itsColorTracker->runTracker(threshold, x, y, mass);
00544       if( checking && (y >= yU && y <= yD)){
00545         //Light centered in y plane. Stop.
00546         yOff = false;
00547         lossCount = 0;
00548       }
00549       else if(checking){
00550         delta = y - 120.0; //delta = x_found - x_center
00551         //DIVE or surface, in greater or lesser amounts depending on th position of the light
00552         printf("Dcam turn\n");
00553         //NOTE: a constant like 2.07 would need testing, since with TASK A,
00554         //there is no cloear way to distinguish between pixel distance and
00555         //difference of depth between the SUB and the Object. FIX????
00556         float dZ = (30/(mass/10)) * tan(delta/2.07); //amt based off of 116degree POV and 240pxl y axis, as well as dist = (30/(mass/10))
00557         diveRel(dZ, true);
00558         lossCount = 0;
00559       }
00560       else{
00561         //Color lost. Use counter to allow for a few noisy losses, then fail
00562         lossCount++;
00563         if(lossCount >3){
00564           return false;
00565         }
00566       }
00567       }*/
00568     thresholdMass = mass;
00569     //STOP
00570     return true;
00571   }
00572 
00573   //NOTE!: Down camera may need a change in axes if we do not reorient it! FIX!!
00574   else if(camArg == BEOSUBCAMDOWN || camArg == BEOSUBCAMUP){
00575     while(xOff){
00576       im = grabImage(camArg);
00577       itsColorTracker->setupTracker(colorArg, im, false);
00578       checking = itsColorTracker->runTracker(threshold, x, y, mass);
00579       if( checking && ( ((x >= xL && x <= xR) && camArg == BEOSUBCAMUP) || ((y >= yU && y <= yD) && camArg == BEOSUBCAMDOWN) ) ){
00580         //Light centered in x plane. Now center in y
00581         xOff = false;
00582         lossCount = 0;
00583       }
00584       else if(checking){
00585         //TURN left or right, in greater or lesser amounts depending on position
00586         if(camArg == BEOSUBCAMDOWN){
00587           turnRel(((y-120)/2.07), true); //delta/2 based off of 160degree POV and 320pxl x axis
00588 
00589         }
00590         else{
00591           turnRel(((x-160)/2), true);
00592         }
00593         lossCount = 0;
00594       }
00595       else{
00596         //Color lost. Use counter to allow for a few noisy losses, then fail
00597         lossCount++;
00598         if(lossCount >3){
00599           return false;
00600         }
00601       }
00602     }
00603     while(yOff){
00604       im = grabImage(camArg);
00605       itsColorTracker->setupTracker(colorArg, im, false);
00606       checking = itsColorTracker->runTracker(threshold, x, y, mass);
00607       if( checking && (((y >= yU && y <= yD) && camArg == BEOSUBCAMUP) || ((x >= xR && x <= xL) && camArg == BEOSUBCAMDOWN))){
00608         //Light centered in y plane. Stop.
00609         yOff = false;
00610         lossCount = 0;
00611       }
00612       else if(checking){
00613         //ADVANCE, in greater or lesser amounts depending on the position
00614         if(camArg == BEOSUBCAMUP){
00615           float dY = (30/(mass/10)) * tan((y-120)/2.07);
00616           advanceRel(dY);
00617         }
00618         else{
00619           float dY = (30/(mass/10)) * tan((x-160)/2);
00620           advanceRel(dY);
00621         }
00622         lossCount = 0;
00623       }
00624       else{
00625         //Color lost. Use counter to allow for a few noisy losses, then fail
00626         lossCount++;
00627         if(lossCount >3){
00628           return false;
00629         }
00630       }
00631     }
00632 
00633     return true;
00634   }
00635   return false; //to make compiler happy
00636 }
00637 
00638 // ######################################################################
00639 bool BeoSub::approachArea(std::string name, const enum BeoSubCamera cam, float stepDist){
00640   switch(cam){
00641   case(BEOSUBCAMUP):{
00642     MappingData goal = itsUpDB->getMappingData(name);
00643   }
00644   case(BEOSUBCAMFRONT):{
00645     MappingData goal = itsFrontDB->getMappingData(name);
00646   }
00647   case(BEOSUBCAMDOWN):{
00648     MappingData goal = itsDownDB->getMappingData(name);
00649   }
00650 
00651   }
00652   //return approachArea(itsCurrentArea, goal, stepDist);
00653 
00654   return true;
00655 
00656 }
00657 
00658 // ######################################################################
00659 bool BeoSub::approachArea(MappingData goalArea, MappingData currentArea, float stepDist){
00660   Attitude targetAtt;
00661   float targetDist = 0.0, expectedDist = 0.0;
00662   MappingData contData;
00663   itsDownDB->getDirections(currentArea, goalArea, targetAtt, targetDist);
00664   expectedDist = targetDist;
00665   while(targetDist >= stepDist){
00666     turnRel(targetAtt.heading, true);
00667     diveAbs(targetAtt.depth, true);//NOTE: should these both be true?
00668     //approach in steps the size of stepDist
00669     advanceRel(stepDist);
00670     expectedDist -= stepDist;
00671     if(expectedDist <= -15.0){//NOTE: needs calibrating! FIX!
00672       //fail
00673       return false;
00674     }
00675     Angle mh;
00676     //get new currentArea
00677     if(recognizeSIFT(BEOSUBCAMDOWN, contData, mh)){
00678       itsDownDB->getDirections(contData, goalArea, targetAtt, targetDist);
00679     }
00680     else if(recognizeSIFT(BEOSUBCAMFRONT, contData, mh)){
00681       itsFrontDB->getDirections(contData, goalArea, targetAtt, targetDist);
00682     }
00683     else{//continue in expected path
00684       targetDist -= stepDist;//NOTE: may be bad! FIX?
00685     }
00686   }
00687   //finish off approach
00688   turnRel(targetAtt.heading, true);
00689   diveAbs(targetAtt.depth, true);
00690   advanceRel(targetDist);
00691   //double-check where we are using mapping, and if OK, return true
00692 
00693 
00694   Image< PixRGB<byte> > im = grabImage(BEOSUBCAMDOWN);
00695   /* rotate the image grabbed from down cameraby 90 counterclockwise*/
00696 
00697 
00698   rutz::shared_ptr<VisualObject> vo(new VisualObject("Captured Image", "", im));
00699   std::vector< rutz::shared_ptr<VisualObjectMatch> > matches;
00700   itsDownVODB->getObjectMatches(vo, matches, VOMA_KDTREEBBF);
00701   if (matches.size() == 0U){
00702     itsFrontVODB->getObjectMatches(vo, matches, VOMA_KDTREEBBF);
00703     if(matches.size() == 0U) return false;
00704   }//If we cannot recognize where we are, return that we are not sure. NOTE: this false should likely be different than the false above, sinc eit is a better result. FIX? NOTE: perhaps we should keep track of the # of times we estimated a step?
00705   for(uint i = 0; i <= matches.size(); i++){
00706     if(!strcmp((matches[0]->getVoTest()->getImageFname()).c_str(), goalArea.itsImgFilename.c_str())){//if we have found a match...
00707       return true; //success!
00708     }
00709   }
00710   return false; //again, we may want to distinguish different "failures"
00711 }
00712 
00713 // ######################################################################
00714 bool BeoSub::Decode(){
00715         //Decode from the order of tasks to the order of the bins!!!
00716   ImageSet< PixRGB<byte> > inStream;
00717   Image< PixRGB<byte> > img;
00718   int NAVG = 20; Timer tim; uint64 t[NAVG]; int frame = 0; //NOTE: what is this NAVG?
00719   float avg2 = 0.0;
00720   //Grab a series of images
00721   for(int i = 0; i < 100; i++){
00722     tim.reset();
00723 
00724     img = grabImage(BEOSUBCAMFRONT);
00725     inStream.push_back(img);
00726 
00727     uint64 t0 = tim.get();  // to measure display time
00728     t[frame % NAVG] = tim.get();
00729     t0 = t[frame % NAVG] - t0;
00730     // compute framerate over the last NAVG frames:
00731     if (frame % NAVG == 0 && frame > 0)
00732       {
00733         uint64 avg = 0ULL; for (int i = 0; i < NAVG; i ++) avg += t[i];
00734         avg2 = 1000.0F / float(avg) * float(NAVG);
00735       }
00736     frame ++;
00737   }
00738   bool foundRed = true;
00739   itsTaskDecoder->setupDecoder("Red", false);
00740   itsTaskDecoder->runDecoder(inStream, avg2);
00741   float hertz = itsTaskDecoder->calculateHz();
00742   if(hertz <= .5){
00743     //red not detected. Try green
00744     foundRed = false;
00745     itsTaskDecoder->setupDecoder("Green", false);
00746     itsTaskDecoder->runDecoder(inStream, avg2);
00747     hertz = itsTaskDecoder->calculateHz();
00748     if(hertz <= .5){//fail
00749       return false;
00750     }
00751   }
00752   itsTasks.clear();
00753   if(foundRed){//RED
00754     decoderIsRed = true;
00755     if(hertz <= 2.8){//AT 2Hz
00756       itsTasks.push_back('B');
00757       itsTasks.push_back('A');
00758       itsTasks.push_back('C');
00759     }
00760     else{//AT 5Hz
00761       itsTasks.push_back('A');
00762       itsTasks.push_back('C');
00763       itsTasks.push_back('B');
00764     }
00765   }
00766   else{//GREEN
00767     decoderIsRed = false;
00768     if(hertz <= 2.8){//AT 2Hz
00769       itsTasks.push_back('C');
00770       itsTasks.push_back('A');
00771       itsTasks.push_back('B');
00772     }
00773     else{//AT 5Hz
00774       itsTasks.push_back('B');
00775       itsTasks.push_back('C');
00776       itsTasks.push_back('A');
00777     }
00778   }
00779   itsTasksIter = itsTasks.begin();
00780   return true;
00781 }
00782 
00783 // ######################################################################
00784 bool BeoSub::TaskGate(){
00785   //  int counter = 0;
00786   //turn towards gate (assumes starting on launch platform)
00787   //NOTE: LAUNCHTOGATE will have to be found onsite! FIX!
00788   //turnAbs(LAUNCHTOGATE);
00789   //NOTE: perhaps try to recognize gate here to confirm? may also want to recognize light (which may be easier)
00790   //NOTE: may need to approach here
00791   /*
00792   while(!Decode() && (counter < 10)){
00793     //while the decode light is not found, strafe left until seen. NOTE that this may or may not work
00794     strafeRel(-0.5);
00795     counter++;
00796   }
00797   if(counter >= 10){
00798     return false;
00799   }
00800   float thresh = 20.0;
00801   //center decoder in camera
00802   if(decoderIsRed){
00803     centerColor("Red", BEOSUBCAMFRONT, thresh);//perhaps should use thresh?
00804   }
00805   else{
00806     centerColor("Green", BEOSUBCAMFRONT, thresh);
00807   }
00808   advanceRel(20.0);//NOTE: this value should be far enough to completely clear the gate
00809   return true;//somewhat bunk
00810   */
00811   int counter = 0;
00812   while(!matchSIFT(BEOSUBCAMFRONT, itsVOtaskDfront) && counter <= 10){
00813     turnOpen(10.0);
00814     counter++;
00815   }
00816   if(counter > 10){
00817     return false;
00818   }
00819   diveAbs(2.0);
00820   return true;
00821 }
00822 
00823 // ######################################################################
00824 
00825 
00826 bool BeoSub::TaskScheduler(int TaskOrder)   //Schedule the order of the three tasks
00827 {
00828 
00829 //pre-task A
00830         //Assmue we get thru the gate, and recognize the light box
00831         //looking for red light
00832 
00833         //approaching red light
00834 
00835 //task A
00836         if(TaskA()) //if Task A is done, then go to task B normally
00837         {
00838         //looking for yellow pipeline
00839 
00840         //approaching yellow pipeline
00841 
00842         }// end of if
00843         else                //if task A fails, then use emergancy to find task B
00844         {
00845 
00846         }//end of else
00847 
00848 
00849 //task B
00850         if(TaskB())        //emergancy for task B
00851         {
00852                 //well done, go to task C
00853 
00854         }//end of if
00855         else
00856         {
00857                 //not done, do task B again? or go to task C
00858 
00859         }//end of else
00860 
00861 
00862 //task C
00863         if(TaskC())
00864         {
00865 
00866         }
00867         else
00868         {
00869 
00870         }
00871 
00872 //post-task C
00873 
00874 
00875         //done
00876         return true;
00877 
00878 }//end of TaskScheduler
00879 
00880 //=======================Begins TaskA==============================
00881 bool BeoSub::TaskA(){//NOTE: assumes that sub has already approached task A and dove to the correct depth, as well as turned to a predicted heading
00882     //LOOK FOR THE LIGHT
00883   /*    float x = 0.0;
00884     float y = 0.0;
00885     float mass = 0;
00886     float close = 30.0;
00887     bool notDone = true;
00888     int state = 0;
00889   */
00890     /*
00891       while sift not found, spiral search slowly
00892       once found, center using sift affine
00893       dive
00894 
00895     */
00896     if(!affineSIFT(BEOSUBCAMDOWN, itsVOtaskAdown)){//approach
00897       if(!affineSIFT(BEOSUBCAMFRONT, itsVOtaskAfront)){
00898         float dist = sqrt(((taskAposition.x - itsGlobalPosition.x)*(taskAposition.x - itsGlobalPosition.x)) + ((taskAposition.y - itsGlobalPosition.y)*(taskAposition.y - itsGlobalPosition.y)));
00899         Angle turn = acos(taskAposition.y/dist);
00900         Angle down = 180;
00901         turn = down - turn;
00902         turn = turn - itsGlobalHeading;
00903         turnOpen(turn);
00904         advanceRel(dist);
00905       }
00906     }
00907     /*
00908     while(notDone){
00909         switch(state){
00910         case 0: //LOOK FOR LIGHT
00911           {
00912             //while we don't see the light...
00913             turnRel(10.0, true);//NOTE: 10 perhaps too big. FIX!
00914             itsColorTracker->setupTracker("Red", grabImage(BEOSUBCAMFRONT), false); //reset using most recent image
00915             if(itsColorTracker->runTracker(5.0, x, y, mass)){
00916               if(mass >= close){
00917                 state = 3;
00918               }
00919               else{
00920                 state = 1;
00921               }
00922               break;
00923             }
00924           }
00925         case 1: //CENTER LIGHT IN CAMERA
00926           {
00927             if(centerColor("Red", BEOSUBCAMFRONT, mass)){
00928               if(mass >= close){
00929                 //NOTE: check for correct depth vs. decoder depth?
00930                 state = 3;
00931               }
00932               else{
00933                 state = 2;
00934               }
00935             }
00936             else{
00937               state = 0;
00938             }
00939           }
00940         case 2: //APPROACH THE LIGHT (really ghetto right now)
00941             {
00942               advanceRel(1.0);//NOTE: should be some number based off of the mass! FIX!
00943             }
00944         case 3: //RAM THE LIGHT!
00945             //go forward at full speed, but allow color tracker to continue running
00946             itsColorTracker->setupTracker("Red", grabImage(BEOSUBCAMFRONT), false);
00947             if(itsColorTracker->runTracker(40.0, x, y, mass)){
00948               advanceRel(12.0, false);
00949               advanceRel(-1.0, false); //to stop
00950             }
00951             else{
00952                 //light is assumd to have ben hit. stop ramming and continue to next stage
00953                 notDone = false;
00954                 break;
00955             }
00956         }
00957     }
00958     */
00959     taskAdone = true;
00960     return true;
00961 }
00962 
00963 //Look around for the red light
00964 bool BeoSub::LookForRedLight()
00965 {
00966   //front camera
00967   //dive close to the pipe
00968 
00969   ModelManager camManager("ColorTracker Tester");
00970 
00971   nub::soft_ref<FrameIstream>
00972     gb(makeIEEE1394grabber(camManager, "colorcam", "cocam"));
00973 
00974   camManager.addSubComponent(gb);
00975 
00976   camManager.start();
00977 
00978   // instantiate a model manager for the color tracker module:
00979   ModelManager manager("ColorTracker Tester");
00980 
00981   // Instantiate our various ModelComponents:
00982   nub::soft_ref<ColorTracker> test(new ColorTracker(manager));
00983   manager.addSubComponent(test);
00984 
00985   manager.start();
00986 
00987   Image< PixRGB<byte> > Img;
00988   float x = 320/2, y=240/2;
00989   float mass;
00990   bool found;
00991 
00992   //  float width;
00993 
00994   rutz::shared_ptr<XWindow> wini;
00995 
00996   //turn around until I find orange
00997   //#################control#################
00998 
00999 #ifndef DEBUG
01000   turnRel(Angle(15.0)); //turn
01001 #else
01002   printf("DEBUG!!!!!!!!!!!!!!!!!!!!!!!\n");
01003   printf("i'm doing the first turing!\n");
01004 #endif
01005 
01006   //Note: should check if it turned 360 degrees without finding anything
01007   //now just use a counter for test
01008 
01009   int turnCounter=0;
01010 
01011 #ifndef DEBUG
01012   Angle initHeading = getHeading();
01013   Angle currHeading;
01014   Angle epsHeading = Angle(5.0);
01015 #else
01016 #endif
01017 
01018   while(1)
01019   {
01020 #ifndef DEBUG
01021     turnRel(5);
01022 #else
01023     printf("turning right to find the red light!\n");
01024 #endif
01025 
01026     Img = gb->readRGB();
01027 
01028 #ifndef DEBUG
01029     test->setupTracker("Red", grabImage(BEOSUBCAMFRONT), true);
01030 #else
01031     test->setupTracker("Red", Img /*grabImage(BEOSUBCAMFRONT)*/, true);
01032 #endif
01033 
01034     found = test->runTracker(25.0, x, y, mass);
01035     if (found)
01036     {
01037 #ifdef DEBUG
01038       turnRel(0.01); //stop turning
01039 #else
01040       printf("i see the red light!");
01041 #endif
01042       break;
01043     }
01044 
01045     //test if we have turned for 360 degrees
01046     //if so, go randomly or go according to the mapping info
01047     //now we're just using a counter
01048 #ifndef DEBUG
01049     currHeading = getHeading();
01050     if(fabs(currHeading.getVal() - initHeading.getVal()) <= - (epsHeading.getVal()))
01051       {
01052         //if we are trying too many times, just give up
01053         if(turnCounter++ > 10)
01054           {
01055             return false;
01056           }
01057         //make a random turn and go (-180, 180)
01058         else
01059           {
01060             int rndTurn = rand()*180;
01061             Angle rndHeading = Angle(360-rndTurn);
01062             turnRel(rndHeading);
01063             advanceRel(10.0);
01064           }
01065       }
01066 #else
01067     if(turnCounter++ > 1000)
01068       {
01069         printf("never see the red light, i give up!");
01070         return false;
01071       }
01072 #endif
01073 
01074   }//end of while
01075 
01076   return true;
01077 }
01078 
01079 //Center the red light and ready to go
01080 bool BeoSub::CenterRedLight()
01081 {
01082   return false;
01083 }
01084 
01085 //Approach the red light until close enough
01086 bool BeoSub::ApproachRedLight()
01087 {
01088   ModelManager camManager("ColorTracker Tester");
01089 
01090   nub::soft_ref<FrameIstream>
01091     gb(makeIEEE1394grabber(camManager, "colorcam", "cocam"));
01092 
01093   camManager.addSubComponent(gb);
01094 
01095   camManager.start();
01096 
01097   // instantiate a model manager for the color tracker module:
01098   ModelManager manager("ColorTracker Tester");
01099 
01100   // Instantiate our various ModelComponents:
01101   nub::soft_ref<ColorTracker> test(new ColorTracker(manager));
01102   manager.addSubComponent(test);
01103 
01104   manager.start();
01105 
01106   Image< PixRGB<byte> > Img;
01107   float x = 320/2, y=240/2;
01108 
01109   //arbitary area of mass, need to calibrate!!!!
01110   float mass=10.0;
01111   bool found;
01112 
01113   float width;
01114 
01115   rutz::shared_ptr<XWindow> wini;
01116   //approach the orange
01117   bool redInFront = false; //can I see the pipe in front of me
01118 
01119   //we're trying to see the red light
01120   //in both the bottom and front cameras (this is kinda idealistic)
01121   while(1)
01122     {
01123       Img = gb->readRGB();
01124       //chase after red in the front cam
01125 #ifndef DEBUG
01126       test->setupTracker("Red", grabImage(BEOSUBCAMFRONT), true);
01127 #else
01128       test->setupTracker("Red", Img, true);
01129 #endif
01130       redInFront = test->runTracker(25.0, x, y, mass);
01131 #ifndef DEBUG
01132       test->setupTracker("Red", grabImage(BEOSUBCAMDOWN), true);
01133 #else
01134       test->setupTracker("Red", Img, true);
01135 #endif
01136       test->runTracker(25.0, x, y, mass);
01137 
01138 #ifndef DEBUG
01139       advanceRel(1.5);
01140 #else
01141       printf("i'm going forward!\n");
01142 #endif
01143 
01144       width = Img.getWidth();
01145       //make sure that positive is up-right
01146       x = x - width/2;
01147 
01148       if (redInFront)
01149         { //if seen in the front camera
01150           printf("i see the red light in the front!\n");
01151           if (fabs(x) < 10)
01152             { //turn left or right
01153 #ifndef DEBUG
01154               advanceRel(1.5);
01155 #else
01156               printf("now going forward to the pipe!\n");
01157 #endif
01158             }
01159           else
01160             {
01161               if(x>0)
01162                 {
01163 
01164 #ifndef DEBUG
01165                   turnRel(Angle(5));
01166 #else
01167                   printf("turning right to the red light!\n");
01168 #endif
01169                 }
01170               else
01171                 {
01172 #ifndef DEBUG
01173                   turnRel(Angle(-5));
01174 #else
01175                   printf("turning left to the red light!\n");
01176 #endif
01177                 }
01178             }//end of if abs of x
01179         }//end of if red in front
01180        else
01181          { //dive until you see red in front again
01182 
01183            printf("now i lost the red light, diving to get it!\n");
01184            while(1)
01185              {
01186                Img = gb->readRGB();
01187 #ifndef DEBUG
01188                test->setupTracker("Red", grabImage(BEOSUBCAMFRONT), true);
01189 #else
01190                test->setupTracker("Red", Img /*grabImage(BEOSUBCAMFRONT)*/, true);
01191 #endif
01192                redInFront = test->runTracker(25.0, x, y, mass);
01193 
01194                //need a timer/counter, if the red never shows in the front,
01195                //we probably are lost, or hit the bottom of the pool!
01196                if (redInFront)
01197                  {
01198                    printf("got it after dive, now going!\n");
01199                    break;
01200                  }
01201 #ifndef DEBUG
01202                diveRel(.3);
01203 #else
01204                printf("i'm diving for the red light!!!\n");
01205 #endif
01206 
01207              }//end of while
01208 
01209          }//end of else red light in front
01210 
01211       //when a significant amount of red is in the bottom camera
01212       //we are now above the red light, and ready to push!
01213 #ifndef DEBUG
01214        test->setupTracker("Red", grabImage(BEOSUBCAMDOWN), true);
01215 #else
01216        test->setupTracker("Red", Img /*grabImage(BEOSUBCAMDOWN)*/, true);
01217 #endif
01218        found = test->runTracker(25.0, x, y, mass);
01219 
01220        printf("testing if the red light shows in my bottom camera\n");
01221        if (found == true)
01222          {
01223            //see orange in the bottom camera
01224            printf("ok, finally i'm above the red light!\n");
01225            return true;
01226          }
01227        printf("never see the red light under me, keep going!\n");
01228 
01229     }//end of the while(1) loop
01230 
01231   return false;
01232 }
01233 
01234 //Push the red light to finish task A
01235 bool BeoSub::PushRedLight()
01236 {
01237   //l: length of the light bar
01238   //alpha: the min angle to push
01239   //pushDist = l * sin(alpha)
01240   //diveDist = pushDist * tan(alpha)
01241   float minAngle = 30; //degrees
01242   float barLength = 10.0;
01243   float pushDist = barLength * sin(minAngle);
01244   //float diveDist = pushDist * tan(minAngle);
01245 
01246   //total advanced distant counter
01247   float advDist = 0.0;
01248   //total dived distant counter
01249   float divDist = 0.0;
01250   ModelManager camManager("ColorTracker Tester");
01251 
01252   nub::soft_ref<FrameIstream>
01253     gb(makeIEEE1394grabber(camManager, "colorcam", "cocam"));
01254 
01255   camManager.addSubComponent(gb);
01256 
01257   camManager.start();
01258 
01259   // instantiate a model manager for the color tracker module:
01260   ModelManager manager("ColorTracker Tester");
01261 
01262   // Instantiate our various ModelComponents:
01263   nub::soft_ref<ColorTracker> test(new ColorTracker(manager));
01264   manager.addSubComponent(test);
01265 
01266   manager.start();
01267 
01268   Image< PixRGB<byte> > Img;
01269   float x = 320/2, y=240/2;
01270 
01271   //arbitary area of mass, need to calibrate!!!!
01272   float mass = 10.0;
01273   float width;
01274 
01275   rutz::shared_ptr<XWindow> wini;
01276   //approach the red light
01277   bool redInFront = false; //can I see the pipe in front of me
01278   bool redInBottom = false;
01279 
01280   //we're trying to see orange in both the bottom and front cameras (this is kinda idealistic)
01281   while(1)
01282     {
01283       Img = gb->readRGB();
01284       //chase after orange in the front cam
01285 #ifndef DEBUG
01286       test->setupTracker("Red", grabImage(BEOSUBCAMFRONT), true);
01287 #else
01288       test->setupTracker("Red", Img, true);
01289 #endif
01290       redInFront = test->runTracker(25.0, x, y, mass);
01291 #ifndef DEBUG
01292       test->setupTracker("Red", grabImage(BEOSUBCAMDOWN), true);
01293 #else
01294       test->setupTracker("Red", Img, true);
01295 #endif
01296       redInBottom = test->runTracker(25.0, x, y, mass);
01297 
01298       width = Img.getWidth();
01299       //make sure that positive is up-right
01300       x = x - width/2;
01301 
01302       if (redInBottom)
01303         {
01304           //if seen in the bottom camera
01305           //dive until never see in the bottom camera
01306           //but still sees it in the front camera
01307 #ifndef DEBUG
01308           diveRel(.3);
01309 #else
01310           printf("now diving to push the red light!\n");
01311 #endif
01312         }
01313       else if(redInFront)
01314         {
01315           //now we are at the right pos to push
01316           //GO!
01317           printf("i see the red light in the front!\n");
01318           if (fabs(x) < 10)
01319             { //turn left or right
01320 #ifndef DEBUG
01321               advanceRel(1.5);
01322               advDist += 1.5;
01323               diveRel(1.5 * tan(minAngle));
01324               divDist += 1.5 * tan(minAngle);
01325 #else
01326               printf("now going forward to the pipe!\n");
01327 #endif
01328             }
01329           else
01330             {
01331               if(x>0)
01332                 {
01333 #ifndef DEBUG
01334                   turnRel(Angle(5));
01335 #else
01336                   printf("turning right to the red light!\n");
01337 #endif
01338                 }
01339               else
01340                 {
01341 #ifndef DEBUG
01342                   turnRel(Angle(-5));
01343 #else
01344                   printf("turning left to the red light!\n");
01345 #endif
01346                 }
01347             }//end of if abs of x
01348 
01349           if(advDist > pushDist)
01350             {
01351               //we are done!
01352               //now go up and leave the red light
01353 #ifndef DEBUG
01354               //go up and release the red
01355               //we are both free!
01356               diveRel(- divDist - 5.0);
01357 #else
01358               printf("Job done! Going up to leave the red light!\n");
01359               printf("up dist: %f", divDist);
01360 #endif
01361               return true;
01362             }
01363 
01364         }//end of if red in front
01365        else
01366          {
01367            //we lost the red light
01368            //should we do it again???
01369            printf("No, lost the red light\n");
01370 
01371            return false;
01372          }
01373     }//end of while(1)
01374 
01375  return false;
01376 }
01377 
01378 //====================End TaskA=========================
01379 
01380 //====================Begins TaskB==========================
01381 bool BeoSub::TaskB(){
01382   //NOTE: The bottom camera axes are not correct! Will NEED to FIX the indiscrepancy in code below!
01383   //ADD: Orange line flollwing state. AffineXfrm correction,  marker dropping
01384 
01385   //int stage = 0;
01386   //int counter = 0;
01387   bool TaskBDone = false; //has it dropped the marker into the target bin yet?
01388   //bool foundDown = false; bool foundFront = false;
01389   //float x, y, mass, x2, y2, mass2;
01390   //float usedX, usedY, usedMass;
01391   Image< PixRGB<byte> > image;
01392 
01393   /***********************new code ********************************/
01394   //Assume the order is A to B to C
01395   //So we get from A to B
01396 
01397   //  const int HatchNull = 0;
01398   // const int HatchNo = 1;
01399   //  const int HatchShort = 2;
01400   // const int Hatch45 = 3;
01401   //const int HatchLong = 4;
01402 
01403   unsigned int BinCounter = 0;
01404    unsigned int ApproachCounter = 0;
01405 
01406   //get random order of the bins
01407    //  int TaskBBin = HatchNo;
01408 
01409   //  int CurrentPos = 0;
01410   /*
01411   ApproachPipeLine();
01412   while(BinCounter<1) {
01413     bool recbin = FollowPipeLine();
01414     if (recbin) {
01415       CenterBin();
01416       DropMarker();
01417       BinCounter++;
01418     }
01419 
01420   FollowPipeLine();
01421   TaskBDone = true;
01422   }
01423   */
01424    //   bool recognize = false;
01425 
01426    const unsigned int binNum = 1;
01427 
01428    bool testBin=false;
01429 
01430    while((BinCounter < binNum) && (!TaskBDone))
01431      {
01432        //!!!maybe need to change: looking for pipe and approaching pipe
01433        if(ApproachPipeLine())
01434          {
01435            ApproachCounter = 0;
01436 
01437            //TRUE if found bin at the end of follow pipeline
01438            if( (testBin = FollowPipeLine()) )
01439             {
01440               //recognize the 4 bins
01441               //need to change to really recognize
01442               printf("TaskB: found a bin at the end of the pipeline! Now checking if the bin is the one we want\n");
01443 
01444               //if(RecognizeBin()==tastBin)
01445               if(testBin == true)        //if the bin is the recognized one, drop the marke, else just pass it
01446                 {
01447                   printf("TaskB: found the bin we want! Now going to center the bin\n");
01448 
01449                   if(CenterBin())
01450                     {
01451                       printf("TaskB: we have centered the bin! Now we're going to drop the marker!\n");
01452 
01453                       if(DropMarker())
01454                         {
01455                           printf("TaskB: good, we dropped the marker!\n");
01456                           TaskBDone = true;
01457                           BinCounter++;
01458                         }//end ofif drop marker
01459                       else
01460                         {
01461                           //failed to drop the marker
01462                           //drop again?
01463                           printf("TaskB: failed to drop the marker!!!\n");
01464                           return false;
01465                         }//end of drop marker
01466 
01467                     }//end of if center bin
01468                   else
01469                     {
01470                       printf("TaskB: well, we failed to center the bin!\n");
01471                       //fail to center the bin
01472                       //center again?
01473                       return false;
01474                     }//end of center bin
01475 
01476                 }//end of if test bin
01477               else
01478                 {
01479                   printf("TaskB: it's not the bin we want! Just go thru it!\n");
01480 
01481                   if(PassBin())
01482                     {
01483                       printf("TaskB: Ok, we passed the bin! Now follow the pipe to the next bin!\n");
01484                     }//end of if pass bin
01485                   else
01486                     {
01487                       printf("TaskB: well, we failed the pass the bin!");
01488                       //failed to pass the bin
01489                       //find the pipeline directly?
01490                       return false;
01491 
01492                     }//end of pass bin
01493 
01494                   BinCounter++;
01495 
01496                 }//end of test bin
01497 
01498             }//end of if follow
01499           else if(TaskBDone)
01500             {
01501               printf("TaskB: Well, we lost track of the pipe, but the task is done!\n");
01502 
01503               //if(BinCounter<4)
01504               if(BinCounter < 1)        //we miss some bins, but we are done
01505                 {
01506                   return true;
01507                 }
01508               else                        //We are done, go out of the task B zone
01509                 {
01510                   return true;
01511                 }
01512 
01513             }//end of else if
01514 
01515           else        //there is something wrong that we are out of the task B zone
01516             {
01517               printf("TaskB: We lost track of the pipe!\n");
01518               //go back and check again
01519               return false;
01520             }//end of else follow
01521 
01522          }//end of if approach
01523 
01524         else        //failed to approach, try again?
01525           {
01526             printf("TaskB: Failed to approach to the pipe at try %i\n", ApproachCounter);
01527             if(++ApproachCounter>5) //we give up trying
01528               {
01529                 printf("TaskB: Never find the pipe! Give up!\n");
01530                 return false;
01531               }
01532 
01533           }//end else approach
01534 
01535      }//end of while
01536 
01537    printf("TaskB: i'm not suppose to come here, but task is done!\n");
01538    return true;
01539 
01540    /**************************************old code****************************************/
01541   //while(notDone){
01542   //  switch(stage){
01543   //  case 0: //FINE-TUNE MAPPING MATCH. Accepts image filename and fine-tunes current result to param image
01544   //    {
01545   //      rutz::shared_ptr<VisualObject> goal = itsDownVODB->getObject("TaskB");
01546   //      if(affineSIFT(BEOSUBCAMDOWN, goal)){//approach
01547   //        stage = 3;
01548   //        break;
01549   //      }
01550   //      else{//look for pipes
01551   //        stage = 5;
01552   //        break;
01553   //      }
01554   //    }
01555   //  case 3: //MARKER DROPPER 1ST AND ONLY STAGE
01556   //    {
01557   //      for(int i = 0; i < 6; i++) {
01558   //        dropMarker();
01559   //      }
01560   //      return true;
01561   //      // call dropMarker()
01562   //    }
01563   //  case 5: //APPROACH ORANGE PIPES
01564   //    {
01565 
01566   //      if(taskCdone){//If we came from taskC direction...
01567   //        MappingData BtoC = itsDownDB->getMappingData("TaskBtoC.txt");
01568   //        MappingData current; Angle myHeading;
01569   //        if(!recognizeSIFT(BEOSUBCAMDOWN, current, myHeading)){//Try to recognize where we are (max 8 tries right now)
01570   //          counter++;
01571   //          //Ghetto circle search. FIX!
01572   //          advanceRel(-1.5);
01573   //          turnRel(20.0);
01574   //        }
01575   //        if(counter >= 8){//If we are lost, fail
01576   //          return false;
01577   //        }
01578   //        else{//approach task A to B pipes
01579   //          /*
01580   //          if(approachArea(BEOSUBCAMDOWN, BtoC, 3.0)){
01581   //            stage = 7;
01582   //            counter = 0;
01583   //            break;
01584   //          }
01585   //          */
01586   //          counter++;
01587   //        }
01588   //      }
01589   //      else if(taskAdone){//If we came from TaskA direction...
01590   //        MappingData BtoA = itsDownDB->getMappingData("TaskBtoA.txt");
01591   //        MappingData current; Angle myHeading;
01592   //        if(!recognizeSIFT(BEOSUBCAMDOWN, current, myHeading)){//Try to recognize where we are (max 8 tries right now)
01593   //          counter++;
01594   //          //Ghetto circle search. FIX!
01595   //          advanceRel(-3.5);
01596   //          turnRel(20.0);
01597   //        }
01598   //        if(counter >= 8){//If we are lost, fail
01599   //          return false;
01600   //        }
01601   //        else{//approach task A to B pipes
01602   //          /*
01603   //                      if(approachArea(BEOSUBCAMDOWN, BtoA, 3.0)){
01604   //                      stage = 7;
01605   //                      counter = 0;
01606   //                      break;
01607   //                      }
01608   //          */
01609   //          counter++;
01610   //        }
01611   //      }
01612   //    }
01613   //  case 7://PIPE FOLLOWING
01614   //    {
01615   //      float x = 0.0, y = 0.0, mass = 0.0;
01616   //      int counter = 0;
01617   //      itsColorTracker2->setupTracker("Orange", grabImage(BEOSUBCAMDOWN), false);
01618 
01619   //      while(itsColorTracker2->runTracker(10.0, x, y, mass) && counter < 12){
01620   //        ++counter;
01621   //        //NOTE: Down cam weirdness! FIX!!
01622   //        if(y < 120){//on left...
01623   //          turnRel(-10.0);
01624   //        }
01625   //        else{//on right...
01626   //          turnRel(10.0);
01627   //        }
01628 
01629   //        /****/ //FIX
01630 
01631   //        advanceRel(1.5);//follow
01632 
01633   //        itsColorTracker->setupTracker("White", grabImage(BEOSUBCAMDOWN), false);
01634   //        if(itsColorTracker->runTracker(500.0, x, y, mass)) {
01635   //          stage = 3;
01636   //          break;
01637   //        }
01638 
01639   //      }
01640   //           //itsColorTracker2->setupTracker("Orange", grabImage(BEOSUBCAMDOWN), false);
01641   //      stage = 3;
01642   //           //done following, try to find box
01643   //        // stage = 0; ///?????
01644   //      break;
01645   //    }
01646   //  }
01647   //}//end of while
01648 
01649   //return false;
01650 }
01651 
01652 bool BeoSub::ApproachPipeLine()
01653 {
01654   //front camera
01655   //dive close to the pipe
01656 
01657   ModelManager camManager("ColorTracker Tester");
01658 
01659   nub::soft_ref<FrameIstream>
01660   gb(makeIEEE1394grabber(camManager, "colorcam", "cocam"));
01661 
01662   camManager.addSubComponent(gb);
01663 
01664   camManager.start();
01665 
01666   // instantiate a model manager for the color tracker module:
01667   ModelManager manager("ColorTracker Tester");
01668 
01669   // Instantiate our various ModelComponents:
01670   nub::soft_ref<ColorTracker> test(new ColorTracker(manager));
01671   manager.addSubComponent(test);
01672 
01673   manager.start();
01674 
01675   Image< PixRGB<byte> > Img;
01676   float x = 320/2, y=240/2;
01677   //arbitary area of mass, need to calibrate!!!!
01678   float mass = 10.0;
01679   bool found;
01680 
01681   float width;
01682 
01683   rutz::shared_ptr<XWindow> wini;
01684 
01685   //turn around until I find orange
01686   //#################control#################
01687 
01688 #ifndef DEBUG
01689   turnRel(Angle(15.0)); //turn
01690 #else
01691   printf("DEBUG!!!!!!!!!!!!!!!!!!!!!!!\n");
01692   printf("i'm doing the first turing!\n");
01693 #endif
01694 
01695   //Note: should check if it turned 360 degrees without finding anything
01696   //now just use a counter for test
01697 
01698   int turnCounter=0;
01699 
01700 #ifndef DEBUG
01701   Angle initHeading = getHeading();
01702   Angle currHeading;
01703   Angle epsHeading = Angle(5.0);
01704 #else
01705 #endif
01706 
01707   while(1)
01708   {
01709 #ifndef DEBUG
01710     turnRel(5);
01711 #else
01712     printf("turning right to find the pipe!\n");
01713 #endif
01714 
01715     Img = gb->readRGB();
01716 
01717 #ifndef DEBUG
01718     test->setupTracker("Orange", grabImage(BEOSUBCAMFRONT), true);
01719 #else
01720     test->setupTracker("Orange", Img /*grabImage(BEOSUBCAMFRONT)*/, true);
01721 #endif
01722 
01723     found = test->runTracker(25.0, x, y, mass);
01724     if (found)
01725     {
01726 #ifdef DEBUG
01727       turnRel(0.01); //stop turning
01728 #else
01729       printf("i see the pipe!");
01730 #endif
01731       break;
01732     }
01733 
01734     //test if we have turned for 360 degrees
01735     //if so, go randomly or go according to the mapping info
01736     //now we're just using a counter
01737 #ifndef DEBUG
01738     currHeading = getHeading();
01739     if(fabs(currHeading.getVal() - initHeading.getVal()) <= - (epsHeading.getVal()))
01740       {
01741         //if we are trying too many times, just give up
01742         if(turnCounter++ > 10)
01743           {
01744             return false;
01745           }
01746         //make a random turn and go (-180, 180)
01747         else
01748           {
01749             int rndTurn = rand()*180;
01750             Angle rndHeading = Angle(360-rndTurn);
01751             turnRel(rndHeading);
01752             advanceRel(10.0);
01753           }
01754       }
01755 #else
01756     if(turnCounter++ > 1000)
01757       {
01758         printf("never see a pipe, i give up!");
01759         return false;
01760       }
01761 #endif
01762 
01763   }//end of while
01764 
01765   //approach the orange
01766   bool pipeInFront = false; //can I see the pipe in front of me
01767 
01768   //we're trying to see orange in both the bottom and front cameras (this is kinda idealistic)
01769   while(1)
01770     {
01771       Img = gb->readRGB();
01772       //chase after orange in the front cam
01773 #ifndef DEBUG
01774       test->setupTracker("Orange", grabImage(BEOSUBCAMFRONT), true);
01775 #else
01776       test->setupTracker("Orange", Img, true);
01777 #endif
01778       pipeInFront = test->runTracker(25.0, x, y, mass);
01779 #ifndef DEBUG
01780       test->setupTracker("Orange", grabImage(BEOSUBCAMDOWN), true);
01781 #else
01782       test->setupTracker("Orange", Img, true);
01783 #endif
01784       test->runTracker(25.0, x, y, mass);
01785 
01786 #ifndef DEBUG
01787       advanceRel(1.5);
01788 #else
01789       printf("i'm going forward!\n");
01790 #endif
01791 
01792       width = Img.getWidth();
01793       //make sure that positive is up-right
01794       x = x - width/2;
01795 
01796       if (pipeInFront)
01797         { //if seen in the front camera
01798           printf("i see the pipe in the front!\n");
01799           if (fabs(x) < 10)
01800             { //turn left or right
01801 #ifndef DEBUG
01802               advanceRel(1.5);
01803 #else
01804               printf("now going forward to the pipe!\n");
01805 #endif
01806             }
01807           else
01808             {
01809               if(x>0)
01810                 {
01811 
01812 #ifndef DEBUG
01813                   turnRel(Angle(5));
01814 #else
01815                   printf("turning right to the pipe!\n");
01816 #endif
01817                 }
01818               else
01819                 {
01820 #ifndef DEBUG
01821                   turnRel(Angle(-5));
01822 #else
01823                   printf("turning left to the pipe!\n");
01824 #endif
01825                 }
01826             }//end of if abs of x
01827         }//end of if pipe in front
01828        else
01829          { //dive until you see orange in front again
01830 
01831            printf("now i lost the pipe, diving to get it!\n");
01832            while(1)
01833              {
01834                Img = gb->readRGB();
01835 #ifndef DEBUG
01836                test->setupTracker("Orange", grabImage(BEOSUBCAMFRONT), true);
01837 #else
01838                test->setupTracker("Orange", Img /*grabImage(BEOSUBCAMFRONT)*/, true);
01839 #endif
01840                pipeInFront = test->runTracker(25.0, x, y, mass);
01841 
01842                //need a timer/counter, if the pipe never shows in the front,
01843                //we probably are lost, or hit the bottom of the pool!
01844                if (pipeInFront)
01845                  {
01846                    printf("got it after dive, now going!\n");
01847                    break;
01848                  }
01849 #ifndef DEBUG
01850                diveRel(.3);
01851 #else
01852                printf("i'm diving for the orange!!!\n");
01853 #endif
01854 
01855              }//end of while
01856 
01857          }//end of else pipe in front
01858 
01859       //stop when a significant amount of orange is in the bottom camera
01860 #ifndef DEBUG
01861        test->setupTracker("Orange", grabImage(BEOSUBCAMDOWN), true);
01862 #else
01863        test->setupTracker("Orange", Img /*grabImage(BEOSUBCAMDOWN)*/, true);
01864 #endif
01865        found = test->runTracker(25.0, x, y, mass);
01866 
01867        printf("testing if the pipe shows in my bottom camera\n");
01868        if (found == true)
01869          {
01870            //see orange in the bottom camera
01871            printf("ok, finally i'm above the pipe!\n");
01872            return true;
01873          }
01874        printf("never see the pipe under me, keep going!\n");
01875 
01876   }//end of while
01877 
01878   //never should come here!!!
01879   return false;
01880 
01881 /********** Assume we start from A to B then to C
01882         if(taskCdone){//If we came from taskC direction...
01883           MappingData BtoC = itsDownDB->getMappingData("TaskBtoC.txt");
01884           MappingData current; Angle myHeading;
01885           if(!recognizeSIFT(BEOSUBCAMDOWN, current, myHeading)){//Try to recognize where we are (max 8 tries right now)
01886             counter++;
01887             //Ghetto circle search. FIX!
01888             advanceRel(-1.5);
01889             turnRel(20.0);
01890           }
01891           if(counter >= 8){//If we are lost, fail
01892             return false;
01893           }
01894           else{//approach task A to B pipes
01895 
01896           //  if(approachArea(BEOSUBCAMDOWN, BtoC, 3.0)){
01897           //    stage = 7;
01898           //    counter = 0;
01899            //   break;
01900           //  }
01901 
01902             //counter++;
01903           //}
01904         //}*/
01905 
01906     //printf("x:%f, y:%f, mass:%f\n",x,y, mass);
01907 
01908 
01909 
01910             // Should be data AtoB???
01911   //            MappingData BtoA = itsDownDB->getMappingData("TaskBtoA.txt");
01912 
01913   //          MappingData current;//=???
01914   //                Angle myHeading;//=???
01915 
01916       //Recognize my current position in the mapping, and then go toward the pipeline position
01917 
01918   //  if(!recognizeSIFT(BEOSUBCAMDOWN, current, myHeading)){//Try to recognize where we are (max 8 tries right now)
01919          //counter++;
01920          //Ghetto circle search. FIX!
01921 
01922          //need to calculate the 'distance' between current and goal (BtoA)
01923          //then drive the sub there
01924          //when to stop???
01925 
01926          //advanceRel(-3.5);
01927          //turnRel(20.0);
01928   //  }
01929 
01930           //if(counter >= 8){//If we are lost, fail
01931           //  return false;
01932           //}
01933           //else{//approach task A to B pipes
01934           //  /*
01935           //              if(approachArea(BEOSUBCAMDOWN, BtoA, 3.0)){
01936           //              stage = 7;
01937           //              counter = 0;
01938           //              break;
01939           //              }
01940           //  */
01941           // tesl counter++;
01942           //}
01943 
01944 
01945       return true;
01946 }//end of ApproachPipeLine
01947 
01948 
01949 bool BeoSub::FollowPipeLine()        //if the end is the bin, then return true, else, return false
01950 {
01951   ModelManager camManager("ColorTracker Tester");
01952 
01953   nub::soft_ref<FrameIstream>
01954     gb(makeIEEE1394grabber(camManager, "colorcam", "cocam"));
01955 
01956   camManager.addSubComponent(gb);
01957 
01958   camManager.start();
01959 
01960   // instantiate a model manager for the color tracker module:
01961   ModelManager manager("ColorTracker Tester");
01962 
01963   // Instantiate our various ModelComponents:
01964   nub::soft_ref<ColorTracker> test(new ColorTracker(manager));
01965   manager.addSubComponent(test);
01966   manager.start();
01967 
01968   Image< PixRGB<byte> > Img;
01969   float x = 320/2, y=240/2;
01970   //arbitary area of mass, need to calibrate!!!!
01971   float mass = 10.0;
01972 
01973   float width;
01974   float height;
01975   rutz::shared_ptr<XWindow> wini;
01976 
01977   while(1){
01978     //Get image to be matched
01979     //TO TEST FROM CAMERA
01980       Img = gb->readRGB();
01981 
01982       test->setupTracker("Orange", Img /*grabImage(BEOSUBCAMDOWN)*/, true);
01983       test->runTracker(25.0, x, y, mass);
01984 
01985       // wini->drawImage(Img);
01986       width = Img.getWidth();
01987 
01988       //make sure that positive is up-right
01989       x = x - width/2;
01990 
01991       height = Img.getHeight();
01992       y = height/2 - y;
01993 
01994 #ifndef DEBUG
01995 #else
01996        printf("X: %f, WIDTH: %f\n", x, width);
01997        printf("Y: %f, HEIGHT: %f\n", y, height);
01998 #endif
01999       //test the area of the yellow pipe,
02000       //if it's small enough, it's the end;
02001       //otherwise, go straight
02002 
02003        if( mass > 1000 )
02004          {  //go straight
02005 #ifndef DEBUG
02006            advanceRel(1.5);
02007 #else
02008            printf("i'm going forward!\n");
02009 #endif
02010          }
02011        else //it's either the end of the pipeline or there's a break for a box
02012          {
02013            printf("Break in pipeline\n");
02014 
02015            //test if the end is a bin or not
02016            //1 for black bin, other for white bin
02017            //bool rec = TestBin(1);
02018            bool rec=TestBin(gb,1);
02019            if (rec)
02020              {
02021                printf("FOUND BIN\n");
02022              }
02023            // return TestBin();
02024            return rec;
02025          }
02026 
02027        //PID control of the tracking,!!! now just x-tracking
02028 
02029        if(fabs(x)<=20)
02030          {//go straight
02031 #ifndef DEBUG
02032            advanceRel(1.5);
02033 #else
02034              printf("Go Straight %f\n", fabs(x));
02035 #endif
02036          }
02037        else
02038          {
02039            if (y == 0.0)
02040              {
02041                y+=0.01;
02042              }  //prevent divide by zero error
02043 
02044            printf("turn: %f %f\n",atan(x/y)*180/M_PI, M_PI);
02045 
02046            if (atan(x/y)*180/M_PI > 0)
02047              {
02048                printf("Turn Right %f\n", fabs(x));
02049              }
02050            else
02051              {
02052                printf("Turn Left %f\n", fabs(x));
02053              }
02054 #ifndef DEBUG
02055             turnRel(Angle(atan(x/y) * 180/M_PI));
02056 #else
02057             printf("i'm turing to the center of the orange!\n");
02058 #endif
02059          }
02060 
02061        //!!!need to check if overturned 180 degrees
02062   }//end of while
02063 
02064   //should never come here
02065   return false;
02066 
02067   /*//should x,y,mass be pointer?
02068           float x = 0.0, y = 0.0, mass = 0.0;
02069   //do we need a counter?
02070   int counter = 0;
02071   itsColorTracker2->setupTracker("Orange", grabImage(BEOSUBCAMDOWN), false);
02072 
02073                                                                                                                                                                         //referance???
02074   while(itsColorTracker2->runTracker(10.0, x, y, mass) && counter < 12){
02075 
02076      //if current pos is (0,0)
02077      //color tracker returned pos is (x,y)
02078      //should the sub turn to (x,y)
02079 
02080      //float eps=0.01;
02081      //if (x == 0.0){
02082      //          x += eps;
02083      //}
02084      //
02085      //if (y == 0.0){
02086      //          y += eps;
02087      //}
02088      //float Angle = tan(y/x);
02089      //float Dist = sqrt(x*x + y*y);
02090 
02091      //turn Angle and goto Dist???
02092 
02093      //++counter;
02094      //NOTE: Down cam weirdness! FIX!!
02095      //if(y < 120){//on left...
02096      // turnRel(-10.0);
02097      //}
02098      //else{//on right...
02099      //  turnRel(10.0);
02100      //}
02101 
02102       //FIX
02103 
02104      //advanceRel(1.5);//follow
02105 
02106                  //test if goes to the bins
02107      itsColorTracker->setupTracker("White", grabImage(BEOSUBCAMDOWN), false);
02108      if(itsColorTracker->runTracker(500.0, x, y, mass)) {
02109        //stage = 3;
02110        break;
02111      }//end of if itsColorTracker
02112 
02113    }//end of if itsColor Tracker2
02114              //itsColorTracker2->setupTracker("Orange", grabImage(BEOSUBCAMDOWN), false);
02115         //stage = 3;
02116              //done following, try to find box
02117           // stage = 0; ///?????
02118           */
02119         //break;
02120 }//end of FollowPipeLine
02121 
02122 int BeoSub::RecognizeBin()
02123 {
02124   //recognize the pattern the bins
02125   //return the id of the bin
02126 
02127   return 0;
02128 }
02129 
02130 
02131 bool BeoSub::TestBin(nub::soft_ref<FrameIstream> gb, int testColor)
02132 {  //test if the end is a bin or not
02133 
02134   const char* colorArg=NULL;
02135 
02136   if(testColor==0)
02137     {
02138       colorArg="White";
02139     }
02140   else
02141     {
02142       colorArg="Black";
02143     }
02144 
02145   int shapeCounter=0;//counter for the shape recognize loop
02146 
02147   // instantiate a model manager (for camera input):
02148   ModelManager manager("Canny Tester");
02149   // Instantiate our various ModelComponents:
02150 
02151   //######################################################
02152   //comment out in order to avoid camera setup problems
02153   // nub::soft_ref<FrameIstream>
02154   //  gb(makeIEEE1394grabber(manager, "cannycam", "cc"));
02155 
02156   //GRAB image from camera to be tested
02157   //manager.addSubComponent(gb);
02158   //#######################################################
02159 
02160   // Instantiate our various ModelComponents:
02161   nub::soft_ref<BeoSubCanny> test(new BeoSubCanny(manager));
02162   manager.addSubComponent(test);
02163 
02164 
02165    //Load in config file for camera FIX: put in a check whether config file exists!
02166   manager.loadConfig("camconfig.pmap");
02167 
02168   manager.start();
02169 
02170   //Test with a circle
02171   rutz::shared_ptr<ShapeModel> shape;
02172 
02173   Image< PixRGB<byte> > Img;
02174 
02175   double* p;
02176 
02177   //Set up shape to be matched
02178   //Recongnize the rectangle bin (or square???)
02179 
02180       //rectangle
02181   // p = (double*)calloc(6, sizeof(double));
02182   //p[1] = 150.0; //Xcenter
02183   // p[2] = 120.0; //Ycenter
02184   //  p[4] = 80.0f; // Width
02185   //  p[5] = 80.0f; // Height
02186   //  p[3] = (3.14159/4.0); //alpha
02187   //  shape.reset(new RectangleShape(120.0, p, true));
02188 
02189 
02190   //square
02191   p = (double*)calloc(5, sizeof(double));
02192   p[1] = 150.0; //Xcenter
02193   p[2] = 120.0; //Ycenter
02194   p[3] = 100.0; // Height
02195   p[4] = (3.14159/4.0); // alpha
02196   shape.reset(new SquareShape(100.0, p, true));
02197 
02198   while(1){
02199 
02200     //if not found anything in 5 loops, there is no bin
02201 
02202     if(shapeCounter++>5)
02203       {
02204         printf("Cannot find the bin, I give up!\n");
02205         return false;
02206       }
02207 
02208     //Get image to be matched
02209     //TO TEST FROM CAMERA
02210     Img = gb->readRGB();
02211 
02212     shape->setDimensions(p);
02213 
02214     //run the matching code, black bin
02215     test->setupCanny(colorArg, Img, true);
02216 
02217     //Middle
02218     //p[1] = 150.0;
02219     //p[2] = 120.0;
02220     //shape->setDimensions(p);
02221     bool shapeFound = test->runCanny(shape);
02222 
02223     if(!shapeFound){
02224       //stupid compiler, breaking on stupid warnings
02225     }
02226 
02227     //NOTE: Uncomment the following code to test using multiple starting points
02228 
02229     if(!shapeFound){ //Upper left
02230       p[1] = 60.0; //Xcenter
02231       p[2] = 180.0; //Ycenter
02232       shape->setDimensions(p);
02233       shapeFound = test->runCanny(shape);
02234     }
02235     if(!shapeFound){ //Upper right
02236       p[1] = 260.0; //Xcenter
02237       p[2] = 180.0; //Ycenter
02238       shape->setDimensions(p);
02239       shapeFound = test->runCanny(shape);
02240     }
02241     if(!shapeFound){ //Lower left
02242       p[1] = 60.0; //Xcenter
02243       p[2] = 60.0; //Ycenter
02244       shape->setDimensions(p);
02245       shapeFound = test->runCanny(shape);
02246     }
02247     if(!shapeFound){ //Lower right
02248       p[1] = 260.0; //Xcenter
02249       p[2] = 60.0; //Ycenter
02250       shape->setDimensions(p);
02251       shapeFound = test->runCanny(shape);
02252     }
02253 
02254     if(shapeFound)
02255       {//got the bin, go back!!!
02256         return true;
02257       }
02258 
02259     printf("shape not found in loop %i\n",shapeCounter-1);
02260 
02261 
02262   }//end of while loop
02263 
02264   //should never got here!!!
02265   return false;
02266 }//end of TestBin
02267 
02268 bool BeoSub::CenterBin()
02269 {
02270 //center the bin for marker dropping
02271 
02272 //get the mapping of the connection of bin and the pipeline
02273 //compare the mapping, and approach the bin
02274 
02275   ModelManager camManager("ColorTracker Tester");
02276 
02277   nub::soft_ref<FrameIstream>
02278     gb(makeIEEE1394grabber(camManager, "colorcam", "cocam"));
02279 
02280   camManager.addSubComponent(gb);
02281 
02282   camManager.start();
02283 
02284   // instantiate a model manager for the color tracker module:
02285   ModelManager manager("ColorTracker Tester");
02286 
02287   // Instantiate our various ModelComponents:
02288   nub::soft_ref<ColorTracker> test(new ColorTracker(manager));
02289   manager.addSubComponent(test);
02290   manager.start();
02291 
02292   Image< PixRGB<byte> > Img;
02293   float x = 320/2, y=240/2;
02294 
02295   //arbitary area of mass, need to calibrate!!!!
02296   float mass = 10.0;
02297 
02298   float width;
02299   float height;
02300   rutz::shared_ptr<XWindow> wini;
02301 
02302   bool xdone=false;
02303   bool ydone=false;
02304 
02305   while(!(xdone && ydone)){
02306     //Get image to be matched
02307     //TO TEST FROM CAMERA
02308       Img = gb->readRGB();
02309 
02310       //track the center of the black bin
02311 #ifndef DEBUG
02312       test->setupTracker("Black", grabImage(BEOSUBCAMDOWN), true);
02313 #else
02314       test->setupTracker("Black", Img /*grabImage(BEOSUBCAMDOWN)*/, true);
02315 #endif
02316 
02317       test->runTracker(25.0, x, y, mass);
02318 
02319       // wini->drawImage(Img);
02320       width = Img.getWidth();
02321 
02322       //make sure that positive is up-right
02323       x = x - width/2;
02324 
02325       height = Img.getHeight();
02326       y = height/2 - y;
02327 
02328       //centering part
02329       //need to change to PID control!!!
02330       //now just x,y tracking!
02331 
02332       //center x first
02333       printf("centering x...\n");
02334        if(fabs(x) > 20)
02335          {
02336            if (y == 0.0)
02337              {
02338                y+=0.01;
02339              }  //prevent divide by zero error
02340 
02341            printf("turn: %f %f\n",atan(x/y)*180/M_PI, M_PI);
02342 
02343 #ifndef DEBUG
02344            turnRel(Angle(atan(x/y) * 180/M_PI));
02345 #else
02346            if (atan(x/y)*180/M_PI > 0)
02347              {
02348                printf("Turn Right %f\n", fabs(x));
02349              }
02350            else
02351              {
02352                printf("Turn Left %f\n", fabs(x));
02353              }
02354 #endif
02355 
02356          }//end of if x
02357        xdone=true;
02358 
02359        //then center y
02360 
02361        printf("x done!\ncentering y.\n");
02362        if(fabs(y) > 20)
02363          {
02364            if(y>0)
02365              {
02366 
02367 #ifndef DEBUG
02368                advanceRel(1.5);
02369 #else
02370                printf("going forward!\n");
02371 #endif
02372              }
02373            else
02374              {
02375 #ifndef DEBUG
02376                advanceRel(-1.5);
02377 #else
02378                printf("going backward!\n");
02379 #endif
02380              }
02381          }//end of if y
02382        printf("y done!\n");
02383        ydone=true;
02384 
02385        //!!!need to check if overturned 180 degrees
02386   }//end of while
02387 
02388   if(xdone && ydone)
02389     {
02390       printf("alright, center finished!\n");
02391       return true;
02392     }
02393   else
02394     {
02395       printf("woops, center failed!\n");
02396       return false;
02397     }
02398 
02399 //        return true;
02400 }//end of CenterBin
02401 
02402 bool BeoSub::DropMarker()
02403 {
02404         //can we see the marker???
02405   for(int i = 0; i < 6; i++)
02406     {
02407 //############sub control part#####################
02408       //dropMarker();
02409     }
02410   printf("OK, marker dropped!\n");
02411   return true;
02412 
02413 }//end of DropMarker
02414 
02415 
02416 bool BeoSub::PassBin()        //Go Pass the bin
02417 {
02418 //get the mapping the connection of the bin and the pipeline
02419 //compare the mapping, go through the bin to the next connection
02420 
02421   return true;
02422 }//end of PassBin
02423 
02424 
02425 bool BeoSub::TaskC(){
02426 
02427   int step = 0;
02428   bool notDone = true;
02429   int counter = 0, maxcounter = 15;
02430   //NOTE: should we try shape recognition or saliency here? FIX?
02431   while(notDone){
02432     switch(step){
02433 
02434     case 0: //LOOK FOR PINGER & OCTAGON AT SAME TIME USING MAPPING
02435       {
02436         if (counter > maxcounter) return false;
02437 
02438         //BOTTOM
02439         rutz::shared_ptr<VisualObject> down(new VisualObject("current", "", grabImage(BEOSUBCAMDOWN)));
02440         rutz::shared_ptr<VisualObject> pingerDown = itsDownVODB->getObject("TaskC");
02441         VisualObjectMatch matchDown(pingerDown, down, VOMA_KDTREEBBF);
02442 
02443         //FRONT
02444         advanceRel(-8.0);
02445         diveRel(.3);
02446         rutz::shared_ptr<VisualObject> front(new VisualObject("current", "", grabImage(BEOSUBCAMFRONT)));
02447         rutz::shared_ptr<VisualObject> pingerFront = itsFrontVODB->getObject("TaskC");
02448         VisualObjectMatch matchFront(pingerFront, front, VOMA_KDTREEBBF);
02449         diveRel(-.3);
02450         advanceRel(8.0);
02451 
02452         if(matchDown.checkSIFTaffine() || matchFront.checkSIFTaffine()){
02453           step = 1;
02454           break;
02455         }
02456         else if(counter < 10){
02457           //ghetto circle strafe
02458           advanceRel(-1.5);
02459           turnRel(20.0);
02460           counter++;
02461         }
02462         else{
02463           return false;
02464         }
02465       }
02466     case 1://FINE TUNE POSITION USING MAPPING
02467       {
02468         if (counter > maxcounter) return false;
02469 
02470         if(affineSIFT(BEOSUBCAMDOWN, itsVOtaskCdown)){//approach
02471           step = 2;
02472           break;
02473         }
02474         else{
02475           ++counter; step = 0;
02476         }
02477       }
02478     case 2: //SURFACE!
02479       {
02480         if (counter > maxcounter) return false;
02481 
02482         //set ballast to 0 and wait until depth says 0?
02483         //or diveAbs?
02484         //use if statement to say whether dive again or not
02485         diveAbs(-1.0, true); //surface
02486         //if(!last){
02487         //  diveAbs(4.0, true);
02488         // }
02489         notDone = false;
02490       }
02491     }
02492   }
02493   taskCdone = true;
02494   return true;
02495 }
02496 // ######################################################################
02497 /* So things look consistent in everyone's emacs... */
02498 /* Local Variables: */
02499 /* indent-tabs-mode: nil */
02500 /* End: */
Generated on Sun May 8 08:40:19 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3