SaccadeControllers.H

Go to the documentation of this file.
00001 /*!@file Neuro/SaccadeControllers.H Derived classes for saccade generation */
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/Neuro/SaccadeControllers.H $
00035 // $Id: SaccadeControllers.H 9412 2008-03-10 23:10:15Z farhan $
00036 //
00037 
00038 #ifndef SACCADECONTROLLERS_H_DEFINED
00039 #define SACCADECONTROLLERS_H_DEFINED
00040 
00041 #include "Component/ModelParam.H"
00042 #include "Image/ArrayData.H" // for class Dims
00043 #include "Neuro/SaccadeController.H"
00044 #include "Util/SimTime.H"
00045 
00046 #include <deque>
00047 #include <string>
00048 
00049 class SpatialMetrics;
00050 
00051 // ######################################################################
00052 //! Stub saccade controller
00053 /*! No-op implementation -- never makes a decision (eye movement). */
00054 
00055 class StubSaccadeController : public SaccadeController
00056 {
00057 public:
00058   //! Constructor
00059   StubSaccadeController(OptionManager& mgr, const SaccadeBodyPart bodypart);
00060 
00061   //! Destructor
00062   virtual ~StubSaccadeController();
00063 
00064 protected:
00065   //! evolve one time step
00066   virtual void doEvolve(SimEventQueue& q);
00067 
00068   //! This method is called each time a new percept has arrived
00069   virtual void computeWhenNewPercept(SimEventQueue& q);
00070 
00071   //! This method is called each time a reset is made
00072   virtual void computeWhenResetPos(SimEventQueue& q);
00073 
00074   //! This method is called each time a new decision is requested
00075   virtual Point2D<int> computeWhenNewDecision(SaccadeState& sacstate,
00076                                          bool& blinkstate, SimEventQueue& q);
00077 };
00078 
00079 // ######################################################################
00080 //! Trivial saccade controller
00081 /*! TrivialSaccadeController is a direct mapping from percept to decision. */
00082 
00083 class TrivialSaccadeController : public SaccadeController
00084 {
00085 public:
00086   //! Constructor
00087   TrivialSaccadeController(OptionManager& mgr, const SaccadeBodyPart bodypart);
00088 
00089   //! Destructor
00090   virtual ~TrivialSaccadeController();
00091 
00092 protected:
00093   OModelParam<float> itsMinSacLen; //!< Minimum saccade len
00094 
00095   //! evolve one time step
00096   virtual void doEvolve(SimEventQueue& q);
00097 
00098   //! This method is called each time a new percept has arrived
00099   virtual void computeWhenNewPercept(SimEventQueue& q);
00100 
00101   //! This method is called each time a reset is made
00102   virtual void computeWhenResetPos(SimEventQueue& q);
00103 
00104   //! This method is called each time a new decision is requested
00105   virtual Point2D<int> computeWhenNewDecision(SaccadeState& sacstate,
00106                                          bool& blinkstate, SimEventQueue& q);
00107 };
00108 
00109 // ######################################################################
00110 //! Fixed saccade controller
00111 /*! FixedSaccadeController holds fixation at a fixed point, ignoring
00112 its percepts. Useful to render the difference between covert and overt
00113 attention evident in the model. Also useful for creating foveated
00114 displays with fixed viewpoint. Like with all saccade controllers, the
00115 fixation point may externally be changed using resetPos(). */
00116 
00117 class FixedSaccadeController : public SaccadeController
00118 {
00119 public:
00120   //! Constructor
00121   FixedSaccadeController(OptionManager& mgr, const SaccadeBodyPart bodypart);
00122 
00123   //! Destructor
00124   virtual ~FixedSaccadeController();
00125 
00126 protected:
00127   //! evolve one time step
00128   virtual void doEvolve(SimEventQueue& q);
00129 
00130   //! This method is called each time a new percept has arrived
00131   virtual void computeWhenNewPercept(SimEventQueue& q);
00132 
00133   //! This method is called each time a reset is made
00134   virtual void computeWhenResetPos(SimEventQueue& q);
00135 
00136   //! This method is called each time a new decision is requested
00137   virtual Point2D<int> computeWhenNewDecision(SaccadeState& sacstate,
00138                                          bool& blinkstate, SimEventQueue& q);
00139 
00140 private:
00141   Point2D<int> itsPos;
00142 };
00143 
00144 // ######################################################################
00145 //! Friction-damped mass-spring saccade controller
00146 /*! FrictionSaccadeController acts like a mass (at saccade center)
00147 connected to the covert focus of attention through a spring of zero
00148 rest length, and sliding on a plane in the presence of friction. */
00149 
00150 class FrictionSaccadeController : public SaccadeController
00151 {
00152 public:
00153   //! Constructor
00154   /*! @param part As this controller may be used either for the eye or
00155     for the head (as part of bigger controllers that include both eye
00156     and head), this should be either SaccadeBodyPartEye or
00157     SaccadeBodyPartHead and will determine which model options we use
00158     for our internal parameters (eye or head) */
00159   FrictionSaccadeController(OptionManager& mgr,
00160                             const SaccadeBodyPart bodypart);
00161 
00162   //! Destructor
00163   virtual ~FrictionSaccadeController();
00164 
00165 protected:
00166   friend class ThresholdFrictionSaccadeController;
00167   friend class MonkeySaccadeController;
00168 
00169   OModelParam<double> itsSpringK;    //!< spring stiffness
00170   OModelParam<double> itsFrictionMu; //!< friction coeff
00171   OModelParam<Dims> itsDims;         //!< Image size so that we stay inside it
00172   OModelParam<SimTime> itsTimeStep;  //!< Simulation time step
00173 
00174   //! evolve one time step
00175   virtual void doEvolve(SimEventQueue& q);
00176 
00177   //! This method is called each time a new percept has arrived
00178   virtual void computeWhenNewPercept(SimEventQueue& q);
00179 
00180   //! This method is called each time a reset is made
00181   virtual void computeWhenResetPos(SimEventQueue& q);
00182 
00183   //! This method is called each time a new decision is requested
00184   virtual Point2D<int> computeWhenNewDecision(SaccadeState& sacstate,
00185                                          bool& blinkstate, SimEventQueue& q);
00186 
00187 private:
00188   double x, y, oldx, oldy;
00189   SimTime oldt;
00190 };
00191 
00192 // ######################################################################
00193 //! Threshold-limited controller that eliminates small or unreliable shifts
00194 /*! ThresholdSaccadeController will issue an overt control whenever
00195   the received covert shifts are large and go to a same target for
00196   several successive covert shifts. It is hence to be used with IOR
00197   turned off, so that the covert system will keep attending to a same
00198   location for a while. Once a minimum number of covert shifts have
00199   been made that are sufficiently far from the current overt location
00200   and that are sufficiently close to each other, an overt shift will
00201   be issued, to the average location of the accumulated covert
00202   locations. */
00203 
00204 class ThresholdSaccadeController : public SaccadeController
00205 {
00206 public:
00207   //! Constructor
00208   /*! @param minovertdist minimum distance required to warrant an overt
00209   shift (in pixels at the original image's scale).
00210   @param maxcovertdist maximum distance to consider that two covert
00211   shifts point to the "same" location.
00212   @param minfix minimum number of covert shifts within maxcovertdist
00213   of each other and farther than minovertdist from the curent overt
00214   fixation, such as to warrant an overt shift.
00215   @param sweigh if true, average covert location is a weighted average
00216   with saliency values at the covert locations used as weights. Otherwise,
00217   the weight of each covert location is unity. */
00218 
00219   /*! @param part As this controller may be used either for the eye or
00220       for the head (as part of bigger controllers that include both
00221       eye and head), this should be either SaccadeBodyPartEye or
00222       SaccadeBodyPartHead and will determine which model options we
00223       use for our internal parameters (eye or head) */
00224   ThresholdSaccadeController(OptionManager& mgr,
00225                              const SaccadeBodyPart bodypart);
00226 
00227   //! Destructor
00228   virtual ~ThresholdSaccadeController();
00229 
00230   //! Reset ThresholdSaccadeController
00231   /*! See the base function in ModelComponent.H for info. */
00232   virtual void reset1();
00233 
00234   //! Check queued-up percepts and return average
00235   /*! check whether queued-up percepts are close to each other, and
00236     also return average position of percept queue */
00237   virtual void checkPercepts(bool& areclose, Point2D<int>& avgp);
00238 
00239 protected:
00240   friend class ThresholdFrictionSaccadeController;
00241 
00242   //! evolve one time step
00243   virtual void doEvolve(SimEventQueue& q);
00244 
00245   //! This method is called each time a new percept has arrived
00246   virtual void computeWhenNewPercept(SimEventQueue& q);
00247 
00248   //! This method is called each time a reset is made
00249   virtual void computeWhenResetPos(SimEventQueue& q);
00250 
00251   //! This method is called each time a new decision is requested
00252   virtual Point2D<int> computeWhenNewDecision(SaccadeState& sacstate,
00253                                          bool& blinkstate, SimEventQueue& q);
00254 
00255   //! Get us started
00256   virtual void start1();
00257 
00258   OModelParam<float> itsOdist;    //!< min overt distance
00259   OModelParam<float> itsCdist;    //!< max covert distance
00260   OModelParam<int> itsMinNum;     //!< min number of close covert shifts
00261   OModelParam<bool> itsSalWeight; //!< weight average covert pos by saliency
00262 
00263   nub::ref<SpatialMetrics> itsMetrics; //!< metrics that depend on input size
00264 
00265   float odistsq;  // square of min overt distance
00266   float cdistsq;  // square of max covert distance
00267   bool sweight;   // use saliency as weight for average covert location
00268   bool didresetpos;  // just did a resetPos
00269   Point2D<int> resetloc; // location of reset
00270 };
00271 
00272 // ######################################################################
00273 //! Threshold-limited friction-damped controller
00274 /*! ThresholdFrictionSaccadeController combines the features of
00275   ThresholdSaccadeController and FrictionSaccadeController.
00276 
00277   The ThresholdSaccadeController determines when a new saccade is
00278   warranted. The FrictionSaccadeController is fed with the average
00279   covert location over the duration of the percept queue of the
00280   Threshold controller. It then is responsible for inducing slow
00281   drifts of overt attention towards that average, in between two
00282   saccades. In addition, this controller will return to the center of
00283   the image if it does not move in some time. */
00284 class ThresholdFrictionSaccadeController : public SaccadeController
00285 {
00286 public:
00287   //! Constructor
00288   /*! See the two base classes for parameters.
00289 
00290       @param maxidle max time (in seconds) before we naturally return
00291       to the center of the image. This will happen if the covert
00292       shifts are so chaotic that we never decide to follow them
00293       overtly.
00294 
00295       @param part As this controller may be used either for the eye or
00296       for the head (as part of bigger controllers that include both
00297       eye and head), this should be either SaccadeBodyPartEye or
00298       SaccadeBodyPartHead and will determine which model options we
00299       use for our internal parameters (eye or head) */
00300   ThresholdFrictionSaccadeController(OptionManager& mgr,
00301                                      const SaccadeBodyPart bodypart);
00302 
00303   //! Destructor
00304   virtual ~ThresholdFrictionSaccadeController();
00305 
00306 protected:
00307   //! evolve one time step
00308   virtual void doEvolve(SimEventQueue& q);
00309 
00310   //! This method is called each time a new percept has arrived
00311   virtual void computeWhenNewPercept(SimEventQueue& q);
00312 
00313   //! This method is called each time a reset is made
00314   virtual void computeWhenResetPos(SimEventQueue& q);
00315 
00316   //! This method is called each time a new decision is requested
00317   virtual Point2D<int> computeWhenNewDecision(SaccadeState& sacstate,
00318                                          bool& blinkstate, SimEventQueue& q);
00319 
00320   OModelParam<SimTime> itsMaxIdle; //!< max time (in s) before we return to IEP
00321 
00322 private:
00323   nub::ref<SpatialMetrics> itsMetrics;
00324   nub::ref<ThresholdSaccadeController> tsc;
00325   nub::ref<FrictionSaccadeController> fsc;
00326 };
00327 
00328 
00329 // ######################################################################
00330 //! Realistic Monkey Eye or Head controller
00331 /*! This is part of an attempt at a simplified approach to the
00332   MonkeySaccadeCopntroller, which turned out quite complex because of
00333   the interdependency between head and eye movements. Here, we fake it
00334   by having independent controllers for the eyes and the head, such
00335   that we don't need to even deal with gaze stabilization during head
00336   movements and VOR. This controller will do either the head or the
00337   eye. For a controller that does both, see
00338   Monkey2SaccadeController. */
00339 class MonkeySaccadeController : public SaccadeController
00340 {
00341 public:
00342   //! Constructor
00343   /*! Parameters are similar to the FrictionSaccadeController, plus
00344       @param part As this controller may be used either for the eye or
00345       for the head (as part of bigger controllers that include both
00346       eye and head), this should be either SaccadeBodyPartEye or
00347       SaccadeBodyPartHead and will determine which model options we
00348       use for our internal parameters (eye or head) */
00349   MonkeySaccadeController(OptionManager& mgr,
00350                           const SaccadeBodyPart bodypart);
00351 
00352   //! Destructor
00353   ~MonkeySaccadeController();
00354 
00355 protected:
00356   //! evolve one time step
00357   virtual void doEvolve(SimEventQueue& q);
00358 
00359   //! This method is called each time a new percept has arrived
00360   virtual void computeWhenNewPercept(SimEventQueue& q);
00361 
00362   //! This method is called each time a reset is made
00363   virtual void computeWhenResetPos(SimEventQueue& q);
00364 
00365   //! This method is called each time a new decision is requested
00366   virtual Point2D<int> computeWhenNewDecision(SaccadeState& sacstate,
00367                                          bool& blinkstate, SimEventQueue& q);
00368 
00369 private:
00370   nub::ref<FrictionSaccadeController> fsc;
00371   nub::ref<SpatialMetrics> itsMetrics; // metrics that depend on input size
00372   double duration; // duration of realistic saccade
00373   SimTime oldt;    // time of last call to evolve()
00374   SimTime startt;  // time of start of realistic saccade
00375   double currx, curry; // current eye position
00376   double vmax;   // max velocity
00377   double accel;  // acceleration
00378   double theta; // angle of saccade
00379 };
00380 
00381 #endif
00382 
00383 // ######################################################################
00384 /* So things look consistent in everyone's emacs... */
00385 /* Local Variables: */
00386 /* indent-tabs-mode: nil */
00387 /* End: */
Generated on Sun May 8 08:41:03 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3