00001 /** 00002 \file Robots/LoBot/LograbMain.C 00003 \brief Program to test custom multi-grabber for Lobot/Robolocust. 00004 */ 00005 00006 // //////////////////////////////////////////////////////////////////// // 00007 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00008 // by the University of Southern California (USC) and the iLab at USC. // 00009 // See http://iLab.usc.edu for information about this project. // 00010 // //////////////////////////////////////////////////////////////////// // 00011 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00012 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00013 // in Visual Environments, and Applications'' by Christof Koch and // 00014 // Laurent Itti, California Institute of Technology, 2001 (patent // 00015 // pending; application number 09/912,225 filed July 23, 2001; see // 00016 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00017 // //////////////////////////////////////////////////////////////////// // 00018 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00019 // // 00020 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00021 // redistribute it and/or modify it under the terms of the GNU General // 00022 // Public License as published by the Free Software Foundation; either // 00023 // version 2 of the License, or (at your option) any later version. // 00024 // // 00025 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00026 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00027 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00028 // PURPOSE. See the GNU General Public License for more details. // 00029 // // 00030 // You should have received a copy of the GNU General Public License // 00031 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00032 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00033 // Boston, MA 02111-1307 USA. // 00034 // //////////////////////////////////////////////////////////////////// // 00035 // 00036 // Primary maintainer for this file: mviswana usc edu 00037 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/LograbMain.C $ 00038 // $Id: LograbMain.C 13905 2010-09-09 21:38:44Z mviswana $ 00039 // 00040 00041 //------------------------------ HEADERS -------------------------------- 00042 00043 // lobot headers 00044 #include "Robots/LoBot/ui/LoMainWindow.H" 00045 00046 #include "Robots/LoBot/io/LoCompositor.H" 00047 #include "Robots/LoBot/io/LoVideoRecorder.H" 00048 #include "Robots/LoBot/io/LoVideoStream.H" 00049 #include "Robots/LoBot/io/LoFireWireBus.H" 00050 00051 #include "Robots/LoBot/config/LoConfigHelpers.H" 00052 #include "Robots/LoBot/config/LoCommonOpts.H" 00053 #include "Robots/LoBot/config/LoDefaults.H" 00054 00055 #include "Robots/LoBot/thread/LoShutdown.H" 00056 #include "Robots/LoBot/thread/LoThread.H" 00057 00058 #include "Robots/LoBot/misc/LoExcept.H" 00059 #include "Robots/LoBot/misc/LoTypes.H" 00060 #include "Robots/LoBot/util/LoSTL.H" 00061 00062 // INVT image support 00063 #include "Image/Dims.H" 00064 00065 // INVT model component support 00066 #include "Component/ModelManager.H" 00067 #include "Component/ModelParam.H" 00068 00069 // INVT utilities 00070 #include "Util/log.H" 00071 00072 // Unix headers 00073 #include <unistd.h> 00074 00075 // Standard C++ headers 00076 #include <sstream> 00077 #include <algorithm> 00078 #include <iterator> 00079 #include <list> 00080 #include <vector> 00081 00082 //------------------------ APPLICATION OBJECT --------------------------- 00083 00084 // The following class wraps around the ModelManager and associated 00085 // objects, providing a neatly encapsulated API for the main program. 00086 namespace lobot { 00087 00088 struct LoApp { 00089 LoApp() ; 00090 void parse_command_line(int argc, const char* argv[]) ; 00091 void run() ; 00092 ~LoApp() ; 00093 00094 // Some useful types 00095 typedef Compositor<PixelType> ImageCompositor ; 00096 typedef std::vector<VideoStream*> VideoStreams ; 00097 typedef std::vector<VideoRecorder*> VideoRecorders ; 00098 typedef std::list<Drawable*> Drawables ; 00099 00100 // Accessing command line arguments 00101 std::string config_file() const {return m_conf_option.getVal() ;} 00102 00103 private: 00104 VideoStreams m_video_streams ; 00105 VideoRecorders m_video_recorders ; 00106 ImageCompositor m_compositor ; 00107 Drawables m_drawables ; 00108 ModelManager m_model_manager ; 00109 00110 // Various command line options specific to this program 00111 OModelParam<std::string> m_conf_option ; // --config-file 00112 } ; 00113 00114 } // end of namespace encapsulating above class definition 00115 00116 //------------------------------- MAIN ---------------------------------- 00117 00118 int main(int argc, const char* argv[]) 00119 { 00120 MYLOGVERB = LOG_ERR ; // minimize INVT's incessant chatter 00121 try 00122 { 00123 lobot::LoApp app ; 00124 app.parse_command_line(argc, argv) ; 00125 app.run() ; 00126 } 00127 catch (lobot::uhoh& e) 00128 { 00129 LERROR("%s", e.what()) ; 00130 return e.code() ; 00131 } 00132 catch (std::exception& e) 00133 { 00134 LERROR("%s", e.what()) ; 00135 return 255 ; 00136 } 00137 return 0 ; 00138 } 00139 00140 //----------------------------- NAMESPACE ------------------------------- 00141 00142 namespace lobot { 00143 00144 //----------------------- FORWARD DECLARATIONS -------------------------- 00145 00146 Dims grab_size() ; 00147 float grab_rate() ; 00148 bool recording_enabled() ; 00149 std::string recording_stem() ; 00150 bool show_ui() ; 00151 00152 //----------------------------- APP INIT -------------------------------- 00153 00154 // Setup INVT model manager and command line options 00155 LoApp::LoApp() 00156 : m_model_manager("lograb"), 00157 m_conf_option(& OPT_ConfigFile, & m_model_manager) 00158 { 00159 Shutdown::start_listening() ; 00160 } 00161 00162 // Create video streams to grab from each camera connected to FireWire 00163 // bus. 00164 static void create_video_streams(const Dims& resolution, float frame_rate, 00165 LoApp::VideoStreams* V) 00166 { 00167 const int n = FireWireBus::instance().num_cameras() ; 00168 V->reserve(n) ; 00169 for (int i = 0; i < n; ++i) 00170 V->push_back(new VideoStream(i, resolution, frame_rate)) ; 00171 00172 // Okay to release the FireWire camera nodes now. We won't be needing 00173 // them any further in this program. 00174 FireWireBus::instance().release_camera_nodes() ; 00175 } 00176 00177 // Create video recorders attached to each of the video streams to store 00178 // the input frames to corresponding MPEG movies. 00179 static void create_video_recorders(const LoApp::VideoStreams& V, 00180 const std::string& mpeg_name_root, 00181 LoApp::VideoRecorders* R) 00182 { 00183 const int n = V.size() ; 00184 R->reserve(n) ; 00185 for (int i = 0; i < n; ++i) 00186 R->push_back(new VideoRecorder(mpeg_name_root + to_string(i), V[i])) ; 00187 } 00188 00189 // DEVNOTE: THIS IS HORRIBLY BROKEN! NEEDS TO BE UPDATED TO USE OpenGL 00190 // FOR RENDERING THE GRABBED FRAMES AS THE OLD DRAWABLE STUFF IS NO 00191 // LONGER AVAILABLE (circa mid-Feb 2010) AS THE MAIN WINDOW WAS CONVERTED 00192 // TO A GLUT WINDOW AFTER THE ROBOLOCUST DEVELOPMENT FOCUS SHIFTED TO 00193 // USING A LASER RANGE FINDER AS THE PRIMARY SENSOR RATHER THAN CAMERAS. 00194 /* 00195 // Create drawables required to show the images being grabbed from the 00196 // cameras on the application's main window. 00197 static void create_drawables(const LoApp::ImageCompositor* C, 00198 LoApp::Drawables* D) 00199 { 00200 typedef ImageDrawable<PixelType> Img ; 00201 D->push_back(new Img(C, Rectangle(Point(0,0), C->getImageSize()))) ; 00202 } 00203 */ 00204 00205 //----------------------- COMMAND LINE PARSING -------------------------- 00206 00207 void LoApp::parse_command_line(int argc, const char* argv[]) 00208 { 00209 std::string default_config_file = getenv("HOME") ; 00210 default_config_file += "/" ; 00211 default_config_file += LOBOT_DEFAULT_CONFIG_FILE_NAME ; 00212 m_model_manager.setOptionValString(& OPT_ConfigFile, 00213 default_config_file.c_str()) ; 00214 00215 if (! m_model_manager.parseCommandLine(argc, argv, "", 0, 0)) 00216 throw customization_error(BAD_OPTION) ; 00217 } 00218 00219 //----------------------------- MAIN LOOP ------------------------------- 00220 00221 // Quick helper class to start and stop model manager (useful when 00222 // exceptions are thrown because destructor automatically stops the model 00223 // manager without requiring an explicit call to the stop method prior to 00224 // throwing the exception). 00225 class ModelManagerStarter { 00226 ModelManager& mgr ; 00227 public : 00228 ModelManagerStarter(ModelManager& m) : mgr(m) {mgr.start() ;} 00229 ~ModelManagerStarter() {mgr.stop() ;} 00230 } ; 00231 00232 // Application object's run method (aka main loop) 00233 void LoApp::run() 00234 { 00235 ModelManagerStarter M(m_model_manager) ; 00236 00237 // Load the config file (if any) 00238 try 00239 { 00240 Configuration::load(config_file()) ; 00241 //Configuration::dump() ; 00242 } 00243 catch (customization_error& e) // this is not fatal 00244 { 00245 LERROR("%s", e.what()) ; // simply report error and move on 00246 } 00247 00248 // Setup input video streams and output recording streams 00249 create_video_streams(grab_size(), grab_rate(), & m_video_streams) ; 00250 connect(m_video_streams, m_compositor) ; 00251 if (recording_enabled()) 00252 create_video_recorders(m_video_streams, recording_stem() + "-", 00253 & m_video_recorders) ; 00254 00255 // DEVNOTE: MAIN WINDOW CODE COMPLETELY BROKEN AND NEEDS TO BE FIXED 00256 // TO USE OpenGL/GLUT. ROBOLOCUST IS NOW (circa mid-Feb 2010) USING A 00257 // LASER RANGE FINDER RATHER THAN CAMERAS AS THE PRIMARY SENSING 00258 // MODALITY. 00259 /* 00260 // Create and configure main window 00261 MainWindow& W = MainWindow::instance() ; 00262 if (show_ui()) { 00263 create_drawables(& m_compositor, & m_drawables) ; 00264 connect(m_drawables, W) ; 00265 W.resize(m_compositor.getImageSize()) ; 00266 W.show("Lobot Multi-grab Tester") ; 00267 } 00268 */ 00269 00270 // Grab frames and display them 00271 while (! Shutdown::signaled()) 00272 { 00273 std::for_each(m_video_streams.begin(), m_video_streams.end(), 00274 std::mem_fun(& VideoStream::update)) ; 00275 std::for_each(m_video_recorders.begin(), m_video_recorders.end(), 00276 std::mem_fun(& VideoRecorder::update)) ; 00277 m_compositor.update() ; 00278 00279 /* 00280 W.render() ; 00281 if (W.dismissed()) { 00282 Shutdown::signal() ; 00283 Thread::wait_all() ; 00284 } 00285 */ 00286 usleep(15000) ; 00287 } 00288 } 00289 00290 //--------------------------- APP CLEAN-UP ------------------------------ 00291 00292 LoApp::~LoApp() 00293 { 00294 purge_container(m_drawables) ; 00295 purge_container(m_video_recorders) ; 00296 purge_container(m_video_streams) ; 00297 } 00298 00299 //------------------------------ HELPERS -------------------------------- 00300 00301 Dims grab_size() 00302 { 00303 try 00304 { 00305 Dims d ; 00306 convertFromString(video_conf<std::string>("grab_size"), d) ; 00307 return d ; 00308 } 00309 catch (std::exception&) // badly formatted dims string in config file 00310 { 00311 return LOBOT_DEFAULT_GRAB_SIZE ; // don't crash! 00312 } 00313 } 00314 00315 float grab_rate() 00316 { 00317 return video_conf("grab_rate", LOBOT_DEFAULT_GRAB_RATE) ; 00318 } 00319 00320 bool recording_enabled() 00321 { 00322 return recording_stem() != "" ; 00323 } 00324 00325 std::string recording_stem() 00326 { 00327 return video_conf<std::string>("record") ; 00328 } 00329 00330 bool show_ui() 00331 { 00332 return ui_conf("show_ui", true) ; 00333 } 00334 00335 //----------------------------------------------------------------------- 00336 00337 } // end of namespace lobot encapsulating the LoApp object 00338 00339 /* So things look consistent in everyone's emacs... */ 00340 /* Local Variables: */ 00341 /* indent-tabs-mode: nil */ 00342 /* End: */