00001 /** 00002 \file Robots/LoBot/control/LoGoal.H 00003 \brief A behaviour for driving the robot toward a list of goals. 00004 00005 This file implements a class designed to use lobot's SLAM/localization 00006 module to drive towards each goal location specified in a list of 00007 goals. The behaviour will drive the robot towards the first goal in 00008 the list, then the second, then the third, and so on. It can be 00009 configured to continually loop through the goal list and/or to 00010 backtrack over the goals once it reaches the end of the list. 00011 */ 00012 00013 // //////////////////////////////////////////////////////////////////// // 00014 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00015 // by the University of Southern California (USC) and the iLab at USC. // 00016 // See http://iLab.usc.edu for information about this project. // 00017 // //////////////////////////////////////////////////////////////////// // 00018 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00019 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00020 // in Visual Environments, and Applications'' by Christof Koch and // 00021 // Laurent Itti, California Institute of Technology, 2001 (patent // 00022 // pending; application number 09/912,225 filed July 23, 2001; see // 00023 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00024 // //////////////////////////////////////////////////////////////////// // 00025 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00026 // // 00027 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00028 // redistribute it and/or modify it under the terms of the GNU General // 00029 // Public License as published by the Free Software Foundation; either // 00030 // version 2 of the License, or (at your option) any later version. // 00031 // // 00032 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00033 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00034 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00035 // PURPOSE. See the GNU General Public License for more details. // 00036 // // 00037 // You should have received a copy of the GNU General Public License // 00038 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00039 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00040 // Boston, MA 02111-1307 USA. // 00041 // //////////////////////////////////////////////////////////////////// // 00042 // 00043 // Primary maintainer for this file: mviswana usc edu 00044 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/control/LoGoal.H $ 00045 // $Id: LoGoal.H 13703 2010-07-28 00:15:12Z mviswana $ 00046 // 00047 00048 #ifndef LOBOT_GOAL_BEHAVIOUR_DOT_H 00049 #define LOBOT_GOAL_BEHAVIOUR_DOT_H 00050 00051 //------------------------------ HEADERS -------------------------------- 00052 00053 // lobot headers 00054 #include "Robots/LoBot/control/LoBehavior.H" 00055 #include "Robots/LoBot/misc/LoVector.H" 00056 #include "Robots/LoBot/misc/factory.hh" 00057 00058 // Standard C++ headers 00059 #include <ostream> 00060 #include <vector> 00061 00062 //----------------------------- NAMESPACE ------------------------------- 00063 00064 namespace lobot { 00065 00066 //------------------------- CLASS DEFINITION ---------------------------- 00067 00068 // Forward declaration 00069 class Pose ; 00070 00071 /** 00072 \class lobot::Goal 00073 \brief A behaviour for driving the robot toward a list of goals. 00074 00075 This class implements a behaviour for driving the robot toward each 00076 goal in a list of goals. When the robot reaches a goal, the behaviour 00077 can be configured to continue on to the next goal or pause and wait 00078 for the user to resume the robot. When the robot is at the last goal 00079 in the list, the behaviour can either maintain the final goal or loop 00080 to the first goal and start over. Additionally, in looping mode, the 00081 behaviour can either start from the first goal or backtrack over the 00082 goal list in reverse. 00083 00084 By default, the behaviour continues on to the next goal once it 00085 reaches one goal on the list and it maintains the final goal when it 00086 reaches the end of the goal list. 00087 00088 A goal is a rectangle specified in map coordinates. The behaviour will 00089 direct the robot towards the center of each goal rectangle. However, 00090 the goal is considered satisfied when the robot is located anywhere 00091 within the target rectangle. 00092 */ 00093 class Goal : public Behavior { 00094 // Prevent copy and assignment 00095 Goal(const Goal&) ; 00096 Goal& operator=(const Goal&) ; 00097 00098 // Handy type to have around in a derived class 00099 typedef Behavior base ; 00100 00101 // Boilerplate code to make the generic factory design pattern work 00102 friend class subfactory<Goal, base> ; 00103 typedef register_factory<Goal, base> my_factory ; 00104 static my_factory register_me ; 00105 00106 /// A helper class for encapsulating a goal. 00107 class Target { 00108 /// A goal is specified as a rectangle in map coordinates. 00109 float m_left, m_right, m_bottom, m_top ; 00110 00111 /// Since the goal seeking behaviour will often want to know a goal 00112 /// rectangle's center, it makes sense to compute these coordinates 00113 /// during initialization and keep them around for later use. 00114 float m_center_x, m_center_y ; 00115 00116 public: 00117 /// Goal init. 00118 Target(float left, float right, float bottom, float top) ; 00119 00120 /// Return the goal's bounds. 00121 //@{ 00122 float left() const {return m_left ;} 00123 float right() const {return m_right ;} 00124 float bottom() const {return m_bottom ;} 00125 float top() const {return m_top ;} 00126 //@} 00127 00128 /// Convenient aliases. 00129 //@{ 00130 float L() const {return left() ;} 00131 float R() const {return right() ;} 00132 float B() const {return bottom() ;} 00133 float T() const {return top() ;} 00134 //@} 00135 00136 /// Return the goal rectangle's center coordinates. 00137 //@{ 00138 float x() const {return m_center_x ;} 00139 float y() const {return m_center_y ;} 00140 //@} 00141 00142 /// Check if a location is within the goal's bounds. 00143 bool at(float x, float y) const { 00144 return x >= m_left && x <= m_right && y >= m_bottom && y <= m_top ; 00145 } 00146 00147 /// Helper to dump goals to an output stream. 00148 friend std::ostream& operator<<(std::ostream& os, const Target& t) { 00149 os << '(' << t.x() << ", " << t.y() << ") " 00150 << '[' << t.L() << ' ' << t.R() 00151 << ' ' << t.B() << ' ' << t.T() << ']' ; 00152 return os ; 00153 } 00154 } ; 00155 00156 /// The goal behaviour maintains a list of goals and drives the robot 00157 /// to each one in turn. 00158 std::vector<Target> m_goals ; 00159 00160 /// This data member is used to keep track of the current goal. 00161 int m_goal ; 00162 00163 /// To direct the robot towards the current goal, this behaviour 00164 /// implements the VFF method described by Borenstein and Koren in 00165 /// "Real-time Obstacle Avoidance for Fast Mobile Robots," IEEE 00166 /// Transactions on Systems, Man, and Cybernetics 19(5):1179--1187, 00167 /// Sep/Oct 1989. 00168 /// 00169 /// To compute the total repulsive force exerted by obstacles within 00170 /// the active window of the certainty grid, we use a vector mask. 00171 /// Each cell of this mask contains a force vector scaled by Fcr/d2, 00172 /// where Fcr is the constant repulsive force and d2 is the square of 00173 /// the distance between that cell and the mask's center. See equation 00174 /// (1) in the above-mentioned paper. 00175 /// 00176 /// When we want to perform the repulsive force computation, we 00177 /// extract a subportion of the map centered at the robot's current 00178 /// position and sized the same as the mask. We then convolve the mask 00179 /// and certainty values in the map's subportion to obtain the final 00180 /// repulsive force vector. 00181 std::vector<Vector> m_vff_mask ; 00182 00183 /// We need the most recent VFF vectors for visualization. 00184 Vector m_attractive, m_repulsive, m_steering ; 00185 00186 /// The turn direction corresponding to the steering vector is also a 00187 /// useful thing to visualize. 00188 int m_turn_dir ; 00189 00190 /// A private constructor because behaviours are instantiated with an 00191 /// object factory and not directly by clients. 00192 Goal() ; 00193 00194 /// Stuff to do before regular action processing begins. 00195 void pre_run() ; 00196 00197 /// To properly log when this behaviour starts seeking the next goal 00198 /// on its list and when it reaches a goal, we need to override the 00199 /// default run() method provided by the Behavior class. 00200 void run() ; 00201 00202 /// This method implements this behaviour's goal-seeking action. 00203 void action() ; 00204 00205 /// A helper function for sending goal stats to the metrics log. 00206 void log(const char* msg, int goal_index, const Target&, const Pose&) const; 00207 00208 /// Visualizing the goal behaviour's votes. 00209 void render_me() ; 00210 00211 /// Visualizing the goals on lobot's map. 00212 //@{ 00213 static void render_goals(unsigned long client_data) ; 00214 void render_goals() ; 00215 static void render_goal(const Target&) ; 00216 //@} 00217 00218 /// Clean-up. 00219 ~Goal() ; 00220 } ; 00221 00222 //----------------------------------------------------------------------- 00223 00224 } // end of namespace encapsulating this file's definitions 00225 00226 #endif 00227 00228 /* So things look consistent in everyone's emacs... */ 00229 /* Local Variables: */ 00230 /* indent-tabs-mode: nil */ 00231 /* End: */