00001 /*!@file BeoSub/BeoSub.H 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.H $ 00035 // $Id: BeoSub.H 10845 2009-02-13 08:49:12Z itti $ 00036 // 00037 00038 #ifndef BEOSUB_H_DEFINED 00039 #define BEOSUB_H_DEFINED 00040 00041 #include "Util/Angle.H" 00042 #include "BeoSub/Attitude.H" 00043 #include "BeoSub/BeoSubDB.H" 00044 #include "BeoSub/BeoSubCanny.H" 00045 #include "BeoSub/BeoSubTaskDecoder.H" 00046 #include "BeoSub/ColorTracker.H" 00047 #include "Component/ModelComponent.H" 00048 #include "Component/ModelParam.H" 00049 #include "Image/Image.H" 00050 #include "Image/Pixels.H" 00051 #include "Image/ImageSet.H" 00052 #include "SIFT/VisualObject.H" 00053 #include "Util/Timer.H" 00054 #include <pthread.h> 00055 00056 class RawVisualCortex; 00057 class VisualObjectDB; 00058 class ShapeModel; 00059 00060 // ANDRE - NOTE: For a Global Position Variable (GPV), I made a struct 00061 struct Location { 00062 float x, y; 00063 }; 00064 00065 //! A simple enum to access one of our three cameras 00066 enum BeoSubCamera { BEOSUBCAMDOWN = 0, BEOSUBCAMFRONT = 1, 00067 BEOSUBCAMUP = 2 }; 00068 00069 //! Simple function to print the name (Front, Down, Up) of a camera 00070 const char *beoSubCameraName(const BeoSubCamera cam); 00071 00072 //! Definition and access functions for the BeoSub base class 00073 /*! BeoSub is an autonomous visually-guided submarine. This class 00074 implements the high-level functionality, relying on low-level 00075 drivers to handle motor activation, compass reading, etc. This is 00076 the base class. Some functions are purely virtual and need to be 00077 overloaded in various derived classes. */ 00078 class BeoSub : public ModelComponent 00079 { 00080 public: 00081 // ###################################################################### 00082 /*! @name Constructors and Destructors */ 00083 //@{ 00084 00085 //! Constructor 00086 BeoSub(OptionManager& mgr, 00087 const std::string& descrName = "BeoSub", 00088 const std::string& tagName = "BeoSub"); 00089 00090 //! Destructor 00091 virtual ~BeoSub(); 00092 00093 //@} 00094 00095 // ###################################################################### 00096 /*! @name Low-level behaviors */ 00097 //@{ 00098 00099 //NOTE: checkpoint may need FIXed 00100 /* 00101 //! Acquire and save a bunch of measurements 00102 virtual void checkpoint(const char *fmt, ...) 00103 // NOTE: this __attribute__ tells gcc that it should issue 00104 // printf-style warnings when compiling calls to 00105 // BeoSub::checkpoint(), treating the 1st argument (fmt) as the 00106 // format string, and the 2nd and subsequent arguments as the 00107 // printf-style parameters (SUBNOTE: because this is a member 00108 // function, there is a hidden 'this' parameter that counts as arg 00109 // 1, so the listed arguments are counted starting from 2) 00110 __attribute__((format(__printf__, 2, 3))) = 0; 00111 00112 //@} 00113 */ 00114 // ###################################################################### 00115 /*! @name Mid-level access functions */ 00116 //@{ 00117 00118 //! Have we reached the latest set target? 00119 /*! A tol of 1.0F corresponds to +/- 10deg in heading and +/- 20cm 00120 in depth, these tolerances scaling linearly with tol. Pitch and 00121 roll are ignored, we just assume they will be stabilized by the 00122 PID controller and the sub will always remain level. */ 00123 bool targetReached(const float tol = 1.0F) const; 00124 00125 //! Wait until a move is complete. Timeout is in seconds. 00126 void waitMove(const double timeout); 00127 00128 //! Turn the sub to the given heading 00129 /*! @param blocking if true will block until completion or some 00130 timeout occurs */ 00131 void turnAbs(const Angle finalHeading, const bool blocking = false); 00132 00133 //! Turns the sub to the given heading relative to our current heading 00134 void turnRel(const Angle relHeading, const bool blocking = false); 00135 00136 virtual void turnOpen(const Angle openHeading, const bool stop = true) = 0; 00137 00138 //! Pitch the sub to a given angle 00139 void pitchAbs(const Angle finalPitch, const bool blocking = false); 00140 00141 //! Makes the sub dive to a specific depth in meters 00142 void diveAbs(const float finalDepth, const bool blocking = false); 00143 00144 //! Makes the sub dive to a specific depth relative to current 00145 /*! Negative depth is up, positive is down. Distance is in meters. */ 00146 void diveRel(const float relDepth, const bool blocking = false); 00147 00148 //! Advance the sub by some distance in meters 00149 /*! Negative distance is to the rear, positive to the 00150 front. Distance is in meters (approximate). Note: this blocks for 00151 some time... */ 00152 virtual void advanceRel(const float relDist, const bool stop = true) = 0; 00153 00154 //! Strafes the sub by some distance in meters 00155 /*! Negative distance is to the left, positive to the 00156 right. Distance is in meters (approximate). Note: this blocks for 00157 some time... */ 00158 virtual void strafeRel(const float relDist); 00159 00160 //! Drop a marker 00161 virtual void dropMarker(const bool blocking = false) = 0; 00162 00163 //@} 00164 00165 // ###################################################################### 00166 /*! @name Visual processing functions */ 00167 //@{ 00168 00169 //! Grab a an image from one of the cameras 00170 virtual Image< PixRGB<byte> > 00171 grabImage(const enum BeoSubCamera cam) const = 0; 00172 00173 //! Get saliency map from a given camera 00174 /*! For ease of use, the output saliency map returned here is 00175 rescaled (with bilinear interpolation) to the same dims as the 00176 grabbed input image. */ 00177 virtual Image<float> getSaliencyMap(const enum BeoSubCamera cam) const; 00178 00179 //! match a known object to a grabbed image 00180 bool matchSIFT(const enum BeoSubCamera cam, 00181 const rutz::shared_ptr<VisualObject>& obj) const; 00182 00183 //! Recognize an image from our camera against our image databases 00184 /*! Returns true if reliable recognition was achieved. */ 00185 virtual bool recognizeSIFT(const enum BeoSubCamera cam, 00186 MappingData& data, Angle& myHeading) const; 00187 00188 virtual bool affineSIFT(const enum BeoSubCamera cam, 00189 rutz::shared_ptr<VisualObject> goal); 00190 00191 virtual bool findShape(rutz::shared_ptr<ShapeModel>& shapeArg, const char* colorArg, const enum BeoSubCamera camArg) const; 00192 00193 virtual bool centerColor(const char* colorArg, const enum BeoSubCamera camArg, float& thresholdMass); 00194 00195 virtual bool approachArea(std::string name, const enum BeoSubCamera cam, float stepdist); 00196 00197 virtual bool approachArea(MappingData goalArea, MappingData currentArea, float stepDist); 00198 00199 virtual bool Decode(); 00200 00201 virtual bool TaskGate(); 00202 00203 virtual bool TaskA(); 00204 00205 virtual bool TaskB(); 00206 00207 virtual bool TaskC(); 00208 00209 00210 00211 00212 //behaviors for the tasks 00213 00214 bool TaskScheduler(int TaskOrder); 00215 00216 //===============TaskA=================== 00217 bool LookForRedLight(); 00218 bool CenterRedLight(); 00219 bool ApproachRedLight(); 00220 bool PushRedLight(); 00221 00222 //===============TaskB=================== 00223 //break into LookForPipeLine and ApproachPipeLine 00224 virtual bool ApproachPipeLine(); 00225 00226 bool FollowPipeLine(); 00227 00228 int RecognizeBin(); 00229 00230 bool TestBin(nub::soft_ref<FrameIstream> gb, int testColor); 00231 00232 bool CenterBin(); 00233 00234 bool DropMarker(); 00235 00236 bool PassBin(); 00237 //@} 00238 00239 // ###################################################################### 00240 /*! @name Low-level access functions */ 00241 //@{ 00242 00243 //! Get time since started, in seconds 00244 double getTime() const; 00245 00246 //! Gets the Current Attitude of the Sub 00247 Attitude getCurrentAttitude() const; 00248 00249 //! Gets the Target Attitude of the Sub 00250 Attitude getTargetAttitude() const; 00251 00252 //! Get current heading (yaw axis), in degrees, ]-180.0 .. 180.0] 00253 Angle getHeading() const; 00254 00255 //! Get current pitch, in degrees, ]-180.0 .. 180.0] 00256 Angle getPitch() const; 00257 00258 //! Get current roll, in degrees, ]-180.0 .. 180.0] 00259 Angle getRoll() const; 00260 00261 //! Shorthand to get all 3 compass readings 00262 void getCompass(Angle& heading, Angle& pitch, Angle& roll) const; 00263 00264 //! Get current depth (units in meters) 00265 float getDepth() const; 00266 00267 //@} 00268 00269 //private: 00270 protected: 00271 OModelParam<std::string> itsFrontVODBfname; //!< file name of front object db 00272 rutz::shared_ptr<VisualObjectDB> itsFrontVODB; //!< front object db 00273 OModelParam<std::string> itsDownVODBfname; //!< file name of down object db 00274 rutz::shared_ptr<VisualObjectDB> itsDownVODB; //!< down object db 00275 OModelParam<std::string> itsUpVODBfname; //!< file name of up object db 00276 rutz::shared_ptr<VisualObjectDB> itsUpVODB; //!< up object db 00277 00278 Timer itsMasterClock; //!< our master clock, unit is useconds 00279 int itsCkPt; //!< our checkpoint number 00280 Attitude itsCurrentAttitude; //!< the current Attitude of the sub 00281 // Andre: NOTE: we need a global variable for attitude so we can 00282 //+/- our direction 00283 // whenever we rotate in TurnOpen(), with some drift error that cancels 00284 // itself slightly if we do a relative good number of +/- changes in direction 00285 // But I'm not sure if we need a new Attitude or just use itsCurrentAttitude 00286 Location itsGlobalPosition; 00287 Angle itsGlobalHeading; 00288 00289 Attitude itsTargetAttitude; //!< target (desired) Attitude of the sub 00290 nub::soft_ref<RawVisualCortex> itsVisualCortex; //!< To compute saliency maps 00291 00292 std::string itsFrontDBfname; //!< file name of front data db 00293 rutz::shared_ptr<BeoSubDB> itsFrontDB; //!< front data db 00294 std::string itsDownDBfname; //!< file name of down data db 00295 rutz::shared_ptr<BeoSubDB> itsDownDB; //!< down data db 00296 std::string itsUpDBfname; //!< file name of up data db 00297 rutz::shared_ptr<BeoSubDB> itsUpDB; //!< up data db 00298 00299 nub::soft_ref<BeoSubCanny> itsShapeDetector; 00300 nub::soft_ref<BeoSubTaskDecoder> itsTaskDecoder; 00301 nub::soft_ref<ColorTracker> itsColorTracker; 00302 nub::soft_ref<ColorTracker> itsColorTracker2; 00303 00304 bool decoderIsRed; 00305 public: 00306 bool taskAdone; 00307 bool taskBdone; 00308 bool taskCdone; 00309 std::list<char> itsTasks; 00310 std::list<char>::iterator itsTasksIter; 00311 00312 rutz::shared_ptr<VisualObject> itsVOtaskAdown, itsVOtaskAfront; 00313 rutz::shared_ptr<VisualObject> itsVOtaskBdown, itsVOtaskBfront; 00314 rutz::shared_ptr<VisualObject> itsVOtaskCdown, itsVOtaskCfront, itsVOtaskCup; 00315 rutz::shared_ptr<VisualObject> itsVOtaskGdown, itsVOtaskGfront, itsVOtaskGup; 00316 rutz::shared_ptr<VisualObject> itsVOtaskDfront; 00317 00318 Location taskAposition, taskBposition, taskCposition, taskGposition; 00319 00320 protected: 00321 pthread_mutex_t itsLock; //!< lock to control access to our internal data 00322 00323 virtual void start1(); //!< get started 00324 }; 00325 00326 00327 #endif 00328 00329 // ###################################################################### 00330 /* So things look consistent in everyone's emacs... */ 00331 /* Local Variables: */ 00332 /* indent-tabs-mode: nil */ 00333 /* End: */