00001 /** 00002 \file Robots/LoBot/LoApp.H 00003 \brief The Robolocust application object. 00004 00005 This file defines a class that implements the lone application object 00006 for the Robolocust robot controller. This object is responsible for 00007 creating all the I/O objects, the different behaviours, etc. and for 00008 running the main thread. 00009 */ 00010 00011 // //////////////////////////////////////////////////////////////////// // 00012 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00013 // by the University of Southern California (USC) and the iLab at USC. // 00014 // See http://iLab.usc.edu for information about this project. // 00015 // //////////////////////////////////////////////////////////////////// // 00016 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00017 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00018 // in Visual Environments, and Applications'' by Christof Koch and // 00019 // Laurent Itti, California Institute of Technology, 2001 (patent // 00020 // pending; application number 09/912,225 filed July 23, 2001; see // 00021 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00022 // //////////////////////////////////////////////////////////////////// // 00023 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00024 // // 00025 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00026 // redistribute it and/or modify it under the terms of the GNU General // 00027 // Public License as published by the Free Software Foundation; either // 00028 // version 2 of the License, or (at your option) any later version. // 00029 // // 00030 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00031 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00032 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00033 // PURPOSE. See the GNU General Public License for more details. // 00034 // // 00035 // You should have received a copy of the GNU General Public License // 00036 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00037 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00038 // Boston, MA 02111-1307 USA. // 00039 // //////////////////////////////////////////////////////////////////// // 00040 // 00041 // Primary maintainer for this file: mviswana usc edu 00042 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/LoApp.H $ 00043 // $Id: LoApp.H 13811 2010-08-21 02:00:08Z mviswana $ 00044 // 00045 00046 #ifndef LOBOT_APPLICATION_OBJECT_DOT_H 00047 #define LOBOT_APPLICATION_OBJECT_DOT_H 00048 00049 //------------------------------ HEADERS -------------------------------- 00050 00051 // lobot headers 00052 #include "Robots/LoBot/io/LoCompositor.H" 00053 #include "Robots/LoBot/thread/LoCondition.H" 00054 #include "Robots/LoBot/misc/LoTypes.H" 00055 #include "Robots/LoBot/misc/singleton.hh" 00056 00057 // INVT model component support 00058 #include "Component/ModelManager.H" 00059 #include "Component/ModelParam.H" 00060 00061 // Standard C++ headers 00062 #include <list> 00063 #include <vector> 00064 00065 //----------------------------- NAMESPACE ------------------------------- 00066 00067 namespace lobot { 00068 00069 //------------------------- CLASS DEFINITION ---------------------------- 00070 00071 // Forward declarations 00072 class Behavior ; 00073 class Map ; 00074 class LocustModel ; 00075 00076 class LocustViz ; 00077 class LaserViz ; 00078 class LaserVizFlat ; 00079 00080 class Robot ; 00081 class LaserRangeFinder ; 00082 class InputSource ; 00083 class VideoRecorder ; 00084 class VideoStream ; 00085 00086 /** 00087 \class lobot::App 00088 \brief An application object that ties together various I/O and other 00089 modules and runs the main thread. 00090 00091 This class is responsible for instantiating the various objects used 00092 to interface with the robot's sensors, motors, etc. It also creates 00093 the different behaviours that make up Robolocust's behaviour-based 00094 controller and runs the main thread's update loop that takes care of 00095 continously retrieving the latest sensor measurements, performing the 00096 necessary low-level state computations, etc. 00097 00098 The application object is implemented as a singleton. This allows 00099 other modules/behaviours to easily retrieve references to I/O and 00100 other objects. Thus, the application object serves as a central 00101 repository that holds together the various low-level shared objects 00102 required by the different behaviours. 00103 */ 00104 class App : public singleton<App> { 00105 // Prevent copy and assignment 00106 App(const App&) ; 00107 App& operator=(const App&) ; 00108 00109 // Boilerplate code to make the generic singleton design pattern work 00110 friend class singleton<App> ; 00111 00112 public: 00113 /// One of the main responsibilities of the application object is to 00114 /// hold a bunch of low-level things together in one place so that 00115 /// they may be accessed by other modules and threads as required. To 00116 /// ease the interface between these low-level objects and high-level 00117 /// behaviours that need them, we use these typedefs. 00118 //@{ 00119 typedef Compositor<PixelType> ImageCompositor ; 00120 typedef std::vector<VideoStream*> VideoStreams ; 00121 typedef std::vector<VideoRecorder*> VideoRecorders ; 00122 typedef std::vector<LocustModel*> LocustModels ; 00123 typedef std::vector<Behavior*> Behaviours ; 00124 //@} 00125 00126 private: 00127 /// These are different things the application object is responsible 00128 /// for creating, updating, or just having around handy so that other 00129 /// objects in the system can get to them conveniently. 00130 //@{ 00131 int m_argc ; 00132 const char** m_argv ; 00133 VideoStreams m_video_streams ; 00134 VideoRecorders m_video_recorders ; 00135 ImageCompositor* m_compositor ; 00136 LaserRangeFinder* m_lrf ; 00137 InputSource* m_input_source ; 00138 LocustModels m_locusts ; 00139 Robot* m_robot ; 00140 Map* m_map ; 00141 Behaviours m_behaviours ; 00142 LaserViz* m_laser_viz ; 00143 LaserVizFlat* m_laser_viz_flat ; 00144 LocustViz* m_locust_viz ; 00145 ModelManager m_model_manager ; 00146 //@} 00147 00148 public: 00149 /// Return references/pointers to the things held centrally by the 00150 /// application object. 00151 //@{ 00152 static int argc() {return instance().m_argc ;} 00153 static const char** argv() {return instance().m_argv ;} 00154 static LaserRangeFinder* lrf() {return instance().m_lrf ;} 00155 static Robot* robot() {return instance().m_robot;} 00156 static Map* map() {return instance().m_map ;} 00157 static const LocustModels& locusts() {return instance().m_locusts ;} 00158 static const Behaviours& behaviours() {return instance().m_behaviours ;} 00159 static LaserViz* laser_viz() {return instance().m_laser_viz ;} 00160 static LaserVizFlat* laser_viz_flat() {return instance().m_laser_viz_flat;} 00161 //@} 00162 00163 private: 00164 /// Various command line options specific to the Robolocust program. 00165 OModelParam<std::string> m_cf_option ; // --config-file 00166 00167 /// Return the name of the config file specified on the command line. 00168 std::string config_file() const {return m_cf_option.getVal() ;} 00169 00170 /// A private constructor because the application object is a 00171 /// singleton. 00172 App() ; 00173 00174 public: 00175 /// A convenient alias for returning the application object's lone 00176 /// instance. 00177 static App& create(int argc, const char* argv[]) ; 00178 00179 /// Parse the command line arguments. 00180 void parse_command_line() ; 00181 00182 /// The application object has two main responsibilities. First, it 00183 /// must instantiate all the different I/O modules, create the 00184 /// different behaviours, etc. Second, it must run the Robolocust 00185 /// application's main loop. This method implements the 00186 /// afore-mentioned loop. 00187 /// 00188 /// The main loop runs the update cycle, which takes care of 00189 /// retrieving the latest measurements from the sensors, computing any 00190 /// low-level state based on these measurements, etc. The loop exits 00191 /// when the lobot::Shutdown object is signaled. Before exiting, the 00192 /// main thread waits for all the other threads to wind-up. 00193 void run() ; 00194 00195 private: 00196 /// Some Robolocust threads don't care whether the application object 00197 /// is fully initialized or not; some do. Those that do can use this 00198 /// condition variable to coordinate. 00199 //@{ 00200 Condition m_initialized_cond ; 00201 bool m_initialized ; 00202 //@} 00203 00204 /// Helper classes for above condition variable. 00205 //@{ 00206 struct signal_pred { 00207 bool operator()() ; 00208 } ; 00209 00210 struct wait_pred { 00211 bool operator()() ; 00212 } ; 00213 00214 friend struct signal_pred ; 00215 friend struct wait_pred ; 00216 //@} 00217 00218 /// Set the initialized flag to let other threads know that the 00219 /// application object is fully loaded. 00220 void signal_init() ; 00221 00222 /// Let other threads wait for the initialized flag to be signaled. 00223 void wait_init() ; 00224 00225 public: 00226 /// External API for other threads to wait until the application 00227 /// object is fully initialized. 00228 static void wait_for_init() {instance().wait_init() ;} 00229 00230 /// Clean-up. 00231 ~App() ; 00232 } ; 00233 00234 //----------------------------------------------------------------------- 00235 00236 } // end of namespace encapsulating this file's definitions 00237 00238 #endif 00239 00240 /* So things look consistent in everyone's emacs... */ 00241 /* Local Variables: */ 00242 /* indent-tabs-mode: nil */ 00243 /* End: */