00001 /** 00002 \file Robots/LoBot/control/LoArbiter.H 00003 \brief An ABC for Robolocust motor control arbiters. 00004 00005 This file defines an abstract base class that provides a common 00006 interface for the different kinds of arbiters that are used to control 00007 lobot's motors. 00008 */ 00009 00010 // //////////////////////////////////////////////////////////////////// // 00011 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00012 // by the University of Southern California (USC) and the iLab at USC. // 00013 // See http://iLab.usc.edu for information about this project. // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00016 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00017 // in Visual Environments, and Applications'' by Christof Koch and // 00018 // Laurent Itti, California Institute of Technology, 2001 (patent // 00019 // pending; application number 09/912,225 filed July 23, 2001; see // 00020 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00021 // //////////////////////////////////////////////////////////////////// // 00022 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00023 // // 00024 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00025 // redistribute it and/or modify it under the terms of the GNU General // 00026 // Public License as published by the Free Software Foundation; either // 00027 // version 2 of the License, or (at your option) any later version. // 00028 // // 00029 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00030 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00031 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00032 // PURPOSE. See the GNU General Public License for more details. // 00033 // // 00034 // You should have received a copy of the GNU General Public License // 00035 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00036 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00037 // Boston, MA 02111-1307 USA. // 00038 // //////////////////////////////////////////////////////////////////// // 00039 // 00040 // Primary maintainer for this file: mviswana usc edu 00041 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/control/LoArbiter.H $ 00042 // $Id: LoArbiter.H 13521 2010-06-06 14:23:03Z mviswana $ 00043 // 00044 00045 #ifndef LOBOT_ARBITER_DOT_H 00046 #define LOBOT_ARBITER_DOT_H 00047 00048 //------------------------------ HEADERS -------------------------------- 00049 00050 // lobot headers 00051 #include "Robots/LoBot/ui/LoDrawable.H" 00052 #include "Robots/LoBot/io/LoRobot.H" 00053 #include "Robots/LoBot/thread/LoThread.H" 00054 00055 // POSIX threads 00056 #ifdef INVT_HAVE_LIBPTHREAD 00057 00058 #include <pthread.h> 00059 00060 #else // fake pthreads API to allow builds to succeed 00061 00062 typedef int pthread_mutex_t ; 00063 00064 #endif 00065 00066 // Standard C++ headers 00067 #include <string> 00068 #include <map> 00069 #include <list> 00070 00071 //----------------------------- NAMESPACE ------------------------------- 00072 00073 namespace lobot { 00074 00075 //------------------------- CLASS DEFINITION ---------------------------- 00076 00077 /** 00078 \class lobot::Arbiter 00079 \brief An ABC defining the common interface for lobot's motor control 00080 arbiters. 00081 00082 This class implements an abstract base class that provides a common 00083 interface for a behaviour arbitration mechanism. The Robolocust 00084 arbiter follows Rosenblatt's ideas as described in his Ph.D. thesis on 00085 the Distributed Architecture for Mobile Navigation (DAMN). 00086 00087 Thus, Robolocust behaviours do not directly control the motors or 00088 engage in such nefarious activities as suppressing or inhibiting each 00089 other (a la subsumption). Instead, they vote for each of the different 00090 possible motor control commands. A central arbiter tallies votes using 00091 a weighted sum and smoothing procedure that results in command fusion 00092 (as opposed to sensor fusion) and then issues the command with the 00093 highest vote. 00094 */ 00095 class Arbiter : public Drawable, private Thread { 00096 // Prevent copy and assignment 00097 Arbiter(const Arbiter&) ; 00098 Arbiter& operator=(const Arbiter&) ; 00099 00100 /// After each iteration of the main loop implemented in the run() 00101 /// method, the arbiter will pause a while. This update delay is a 00102 /// user setting specified in the config file. The delay is expected 00103 /// to be in milliseconds. 00104 /// 00105 /// CAUTION: Since the update delay for each arbiter is customizable, 00106 /// it is possible for users to completely ruin the lobot controller 00107 /// by providing bizarre values. Therefore, each arbiter is expected 00108 /// to guard itself against such weirdness. 00109 int m_update_delay ; 00110 00111 protected: 00112 /// A protected constructor because only subclasses should be able to 00113 /// invoke it. Clients cannot directly create arbiters. 00114 /// 00115 /// Derived classes must specify an appropriate update delay to use 00116 /// when they invoke this constructor. It is up to each individual 00117 /// arbiter to guard against possibly catastrophic update delay 00118 /// settings in the config file and provide reasonable defaults and 00119 /// boundaries. 00120 /// 00121 /// Optionally, arbiters interested in visualization may provide the 00122 /// names and geometries for their respective drawables. 00123 Arbiter(int update_delay, 00124 const std::string& drawable_name = "", 00125 const Drawable::Geometry& = Drawable::Geometry()) ; 00126 00127 /// This method implements the arbiter's main loop, taking care of 00128 /// checking with the lobot::Shutdown object whether or not it's time 00129 /// to quit. 00130 /// 00131 /// NOTE: Derived classes may but generally should not provide their 00132 /// own implementations of the Thread::run() method. If, for some 00133 /// reason, a subclass of lobot::Arbiter needs to define its own 00134 /// version of run(), it should be sure to check the status of the 00135 /// lobot::Shutdown object. 00136 void run() ; 00137 00138 /// Since an arbiter runs in its own thread, all subclasses *must* 00139 /// call Thread::start() in their constructors. However, because of 00140 /// private inheritance, Thread::start() won't be visible to 00141 /// subclasses without this explicit say-so. 00142 using Thread::start ; 00143 00144 /// These methods provide derived classes hooks for implementing any 00145 /// pre- and post-run operations. pre_run() is called right before the 00146 /// main loop is entered and post_run() right after it is exited. 00147 /// 00148 /// Derived classes are not required to define these functions. The 00149 /// default versions implemented in the Arbiter base class do nothing. 00150 //@{ 00151 virtual void pre_run() ; 00152 virtual void post_run() ; 00153 //@} 00154 00155 private: 00156 /// In order to perform command fusion properly, the arbiter needs to 00157 /// know each behaviour's priority. Behaviour priorities are assigned 00158 /// by users. User-specified values are usually not normalized, which 00159 /// is why we need to maintain this map. 00160 //@{ 00161 typedef std::map<std::string, float> PriorityMap ; 00162 PriorityMap m_priorities ; 00163 //@} 00164 00165 /// This method populates the behaviours priority map when the arbiter 00166 /// thread starts up. 00167 void init_priorities() ; 00168 00169 /// Retrieve the priority associated with the given behaviour. Each 00170 /// Arbiter subclass must implement this method. Usually, it would 00171 /// involve a lookup in the Robolocust configuration database. 00172 virtual float get_configured_priority(const std::string& beh) const = 0 ; 00173 00174 protected: 00175 /// Returns the normalized priority value stored in the behaviours 00176 /// priority map. 00177 float priority(const std::string& behaviour_name) const ; 00178 00179 public: 00180 /// Sometimes, a behaviour might want/need exclusive control over the 00181 /// robot's actuators. To facilitate this, the freeze() method freezes 00182 /// the arbiter's priority to that of the behaviour identified by the 00183 /// given name. Once frozen, the arbiter will ignore votes cast by 00184 /// behaviours whose priorities are lower than the priority at which 00185 /// the arbiter is frozen. 00186 /// 00187 /// After its need is fulfilled, the behaviour that has frozen the 00188 /// arbiter must unfreeze it to resume normal operation. 00189 /// 00190 /// NOTE: Freezing the arbiter goes against the grain of the DAMN 00191 /// paradigm. This feature is meant for occasional use by high 00192 /// priority behaviours that might have a need for implementing a 00193 /// sequence of actions without "interference" from other behaviours. 00194 /// Use this feature only if absolutely necessary. 00195 //@{ 00196 void freeze (const std::string& name) ; 00197 void unfreeze(const std::string& name) ; 00198 //@} 00199 00200 /// Check if the named behaviour has frozen the arbiter. 00201 bool is_frozen(const std::string& name) const ; 00202 00203 private: 00204 /// These data members keep track of the arbiter's freeze state. 00205 //@{ 00206 std::string m_freezer ; ///< behaviour that has frozen arbiter 00207 float m_freeze_priority ; ///< priority at which arbiter is frozen 00208 //@} 00209 00210 /// Because the freeze state can be accessed by multiple threads, we 00211 /// need to synchronize accesses, which we do with this mutex. 00212 mutable pthread_mutex_t m_freeze_mutex ; 00213 00214 protected: 00215 /// In the DAMN paradigm to robot control, the behaviours do not 00216 /// directly issue motor commands. Rather they vote for or against the 00217 /// available motor commands. Then, the DAMN arbiter issues the motor 00218 /// command by tallying votes and performing appropriate command 00219 /// fusions. 00220 /// 00221 /// Different types of arbiters will have different voting semantics 00222 /// and provide their own vote structures. However, all these vote 00223 /// structures should be derived from this one, i.e., 00224 /// Arbiter::VoteBase. 00225 /// 00226 /// NOTE: This inner class, which serves as a common base for all 00227 /// arbiter vote types, exists only to provide a virtual destructor so 00228 /// that the Arbiter base class can properly clean up its vote list. 00229 struct VoteBase { 00230 virtual ~VoteBase() ; 00231 } ; 00232 00233 /// This inner class is used to hold some vote metadata plus the vote 00234 /// itself (in terms of a VoteBase pointer). 00235 /// 00236 /// NOTE: This class's data members are all public. However, Arbiter 00237 /// subclasses should treat it as a read-only structure. 00238 struct vote_data { 00239 std::string behavior_name ; 00240 long long vote_time ; 00241 VoteBase* vote ; 00242 00243 vote_data(const std::string&, long long, VoteBase*) ; 00244 ~vote_data() ; 00245 } ; 00246 00247 /// The arbiter maintains all the votes in a list of this type. The 00248 /// list is held privately by the base (i.e., this) class and passed 00249 /// to subclasses as part of the motor_cmd() method. 00250 typedef std::list<vote_data*> Votes ; 00251 00252 private: 00253 /// All the votes are stored in this list and tallied in the arbiter's 00254 /// main loop. 00255 Votes m_votes ; 00256 00257 /// When a behaviour casts its vote for some set of motor commands, 00258 /// the vote gets added to the arbiter's list of votes. After the 00259 /// arbiter is done tallying votes, the list is purged prior to 00260 /// starting the next cycle. Since behaviours and arbiters run in 00261 /// separate threads, it is imperative to protect against simultaneous 00262 /// accesses to the votes list. 00263 pthread_mutex_t m_votes_mutex ; 00264 00265 public: 00266 /// Behaviours use this method to cast their votes. 00267 void vote(const std::string& name, VoteBase* vote) ; 00268 00269 protected: 00270 /// The DAMN arbiter's main loop (implemented in Arbiter::run()) is 00271 /// responsible for tallying the available votes and issuing the 00272 /// appropriae motor command. However, since each type of arbiter can 00273 /// have different voting semantics, the base class cannot tally votes 00274 /// and issue the motor commands. That must be done by subclasses. 00275 /// This method performs the vote tallying and issuance of motor 00276 /// commands. It must be implemented by each subclass. 00277 /// 00278 /// NOTE: Subclasses must treat the votes list as read-only. Although 00279 /// this list is passed to the subclass as const object, its nodes are 00280 /// actually up for grabs and can be modified. However, subclasses 00281 /// must refrain from editing the individual vote_data* nodes held by 00282 /// the votes list. Otherwise, Bad Things will happen. 00283 virtual void motor_cmd(const Votes&, Robot*) = 0 ; 00284 00285 public: 00286 /// Clean-up. 00287 virtual ~Arbiter() ; 00288 } ; 00289 00290 //----------------------------------------------------------------------- 00291 00292 } // end of namespace encapsulating this file's definitions 00293 00294 #endif 00295 00296 /* So things look consistent in everyone's emacs... */ 00297 /* Local Variables: */ 00298 /* indent-tabs-mode: nil */ 00299 /* End: */