00001 /** 00002 \file Robots/LoBot/ui/LoLaserWindow.H 00003 00004 \brief The main window for the laser range finder's test program. 00005 00006 This file defines a class that encapsulates the GLUT-based window for 00007 the Hokuyo laser range finder's test program. This window uses OpenGL 00008 for visualizing the laser range finder's measurement data. 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/ui/LoLaserWindow.H $ 00043 // $Id: LoLaserWindow.H 13037 2010-03-23 01:00:53Z mviswana $ 00044 // 00045 00046 #ifndef LOBOT_LRF_TESTER_WINDOW_DOT_H 00047 #define LOBOT_LRF_TESTER_WINDOW_DOT_H 00048 00049 //------------------------------ HEADERS -------------------------------- 00050 00051 // lobot headers 00052 #include "Robots/LoBot/ui/LoLaserWindowMarkings.H" 00053 #include "Robots/LoBot/ui/LoGLCanvas.H" 00054 00055 #include "Robots/LoBot/io/LoLaserRangeFinder.H" 00056 00057 #include "Robots/LoBot/misc/LoTypes.H" 00058 #include "Robots/LoBot/misc/singleton.hh" 00059 #include "Robots/LoBot/util/range.hh" 00060 00061 // Standard C++ headers 00062 #include <map> 00063 #include <string> 00064 00065 //----------------------------- NAMESPACE ------------------------------- 00066 00067 namespace lobot { 00068 00069 //------------------------- CLASS DEFINITION ---------------------------- 00070 00071 /** 00072 \class lobot::LaserWindow 00073 \brief The main window for the laser range finder's test program. 00074 00075 This class uses GLUT and OpenGL to encapsulate a visualization window 00076 for the Hokuyo laser range finder's distance measurements. A world 00077 coordinate system is setup to match the maximum range of the laser 00078 range finder and the device itself is depicted as a small triangle 00079 centered at the origin of the world coordinate system. A grid is 00080 overlaid on the world coordinate system with cells at regular 00081 intervals and the distance measurements are shown as rays emanating 00082 from the central triangle in each supported direction. 00083 00084 The user may tweak various parameters such as grid spacing, 00085 measurement ray directions, etc. Zoom and pan are also supported. 00086 */ 00087 struct LaserWindow : private singleton<LaserWindow> { 00088 // Boilerplate code to make generic singleton pattern work 00089 friend class singleton<LaserWindow> ; 00090 00091 /// Because of the weird way in which GLUT is structured, clients only 00092 /// need this one method to use this class. Everything else is handled 00093 /// internally (meaning everything else in this class is private). 00094 static void create(const std::string&) ; 00095 00096 private: 00097 /// The window title. This needs to be static because the singleton 00098 /// implementation only supports a default constructor. If we want the 00099 /// create() method to be able to pass the window title it gets from 00100 /// its client to this class's constructor, we need some means other 00101 /// than an argument to a constructor. 00102 static std::string m_title ; 00103 00104 /// Since the goal of this window is to render a "map" of the distance 00105 /// measurements made by a Hokuyo laser range finder, it shouldn't be 00106 /// surprising that we need an instance of the lobot::LaserRangeFinder 00107 /// class. 00108 /// 00109 /// DEVNOTE: A cleaner design would actually have this be part of the 00110 /// main program or some other module while this one simply takes care 00111 /// of the visualization details. However, no thanks to GLUT's 00112 /// architecture, doing the right thing becomes somewhat convoluted 00113 /// and unintuitive. Since this class is only used in the lolaser test 00114 /// program, which shouldn't experience much change once it works, we 00115 /// prefer to keep things as simple as possible and allow this 00116 /// UI/rendering object manage the data source object. 00117 LaserRangeFinder* m_lrf ; 00118 00119 /// This class uses GLUT to help visualize the laser range finder's 00120 /// measurement data. This member variable holds the window ID of the 00121 /// GLUT window. 00122 int m_window ; 00123 00124 /// We use a helper class to manage the OpenGL window and viewport 00125 /// transformations. 00126 GLCanvas* m_canvas ; 00127 00128 /// We use another helper class to draw markings at regular intervals 00129 /// to make it easier for users to read/gauge the distances being spit 00130 /// out by the laser range finder. 00131 LaserWindowMarkings* m_markings ; 00132 00133 /// Sometimes, we may want to pause the continuous updates of the 00134 /// laser range finder. This flag acts as a toggle for the pause 00135 /// state. 00136 bool m_paused ; 00137 00138 /// Private constructor because this class is a singleton. 00139 LaserWindow() ; 00140 00141 /// This method retrieves the latest readings from the laser range 00142 /// finder. 00143 void update() ; 00144 00145 /// This method renders the latest measurements obtained from the 00146 /// laser range finder. 00147 void render() ; 00148 00149 /// These methods respond to different key presses. We use a dispatch 00150 /// table to "route" key presses to the appropriate handler. 00151 //{@ 00152 void handle_key(unsigned char key) ; 00153 00154 typedef void (LaserWindow::*KeyHandler)() ; 00155 typedef std::map<unsigned char, KeyHandler> KeyMap ; 00156 KeyMap m_keymap ; // dispatch table 00157 00158 void reset_zoom_pan() ; 00159 void pause() ; 00160 void quit() ; 00161 //@} 00162 00163 /// These functions and variables take care different mouse events. 00164 //@{ 00165 int m_drag_button ; 00166 int m_drag_modifiers ; 00167 int m_drag_prev[2] ; 00168 00169 void left_click (int state, int modifiers, int x, int y) ; 00170 void middle_click(int state, int modifiers, int x, int y) ; 00171 void right_click (int state, int modifiers, int x, int y) ; 00172 00173 void left_drag (int x, int y) ; 00174 void middle_drag(int x, int y) ; 00175 void right_drag (int x, int y) ; 00176 //@} 00177 00178 /// GLUT callbacks 00179 //@{ 00180 static void reshape_callback(int width, int height) ; 00181 static void render_callback() ; 00182 static void keyboard_callback(unsigned char key, int mouse_x, int mouse_y) ; 00183 static void click_callback(int button, int state, int x, int y) ; 00184 static void drag_callback(int x, int y) ; 00185 static void timer_callback(int timer_id) ; 00186 //@} 00187 00188 /// A helper for setting up the update timer. 00189 void setup_timer() ; 00190 00191 /// This method responds to UI window resize events. 00192 void reshape(int width, int height) ; 00193 00194 /// Clean-up. 00195 ~LaserWindow() ; 00196 00197 /// This inner class encapsulates various parameters that can be used 00198 /// to tweak different aspects of the laser range finder 00199 /// visualization. 00200 class Params : public singleton<Params> { 00201 /// Private constructor because this is a singleton. 00202 Params() ; 00203 friend class singleton<Params> ; 00204 00205 /// The laser range finder can be connected to the host machine via 00206 /// USB or a plain-old RS-232C serial port. This setting specifies 00207 /// which device file to use when connecting to the LRF. 00208 std::string m_device ; 00209 00210 /// The data transfer rate between host machine and the LRF. 00211 int m_baud_rate ; 00212 00213 /// The type of markings that should be used to help users read the 00214 /// distance measurements being spit out by the laser range finder. 00215 /// At present, two marking types are supported, viz., grid and 00216 /// rings. In grid mode, we draw horizontal and vertical lines at 00217 /// regular intervals. In rings mode, we draw concentric circular 00218 /// contours to show the distance from the laser range finder. 00219 std::string m_markings_type ; 00220 00221 /// The laser range finder's test program continuously retrieves 00222 /// the latest set of distance readings from the device and paints 00223 /// them on the screen. This setting specifies the frequency with 00224 /// which these updates should be performed. It is expected to be a 00225 /// time expressed in milliseconds. Thus, for some value N, the 00226 /// update will be performed once every N milliseconds. 00227 int m_update_frequency ; 00228 00229 /// The LRF returns distance measurements corresponding to a range 00230 /// of angles with zero degrees being in front of the device, 00231 /// negative angles on the right and positive angles on the left. 00232 /// Drawing the measurements for all the angles in the device's 00233 /// range can result in a very cluttered and illegible picture. 00234 /// Thus, we allow users to specify the range of angles to use and 00235 /// the step size by which to increment the angle as we iterate 00236 /// through this range. 00237 //@{ 00238 range<int> m_angles_range ; 00239 int m_angles_step ; 00240 //@} 00241 00242 /// Color for the rays depicting laser range finder distance 00243 /// measurements. 00244 GLColor m_measurements_color ; 00245 00246 /// The LRF itself is depicted as a combination of a rectangle and 00247 /// a triangle. The triangle serves to let users know which 00248 /// direction the device is pointed toward. These two settings 00249 /// specify the size and direction of the LRF. 00250 /// 00251 /// The direction is simply an angle in the range 0 to 360 degrees. 00252 /// 00253 /// The size is specified in terms of the half-size of the shared 00254 /// edge between the rectangle and triangle. If this size is R, 00255 /// then the entire figure will be inscribed within an imaginary 00256 /// square of size 2R. 00257 /// 00258 /// NOTE: As the visualization window's logical/world coordinate 00259 /// system is setup to match the Hokuyo's specs, the units of the 00260 /// above-mentioned R will be millimeters. However, these are 00261 /// "logical" not true physical mm. 00262 float m_lrf_size ; 00263 float m_lrf_direction ; 00264 00265 /// Color for the LRF device (depicted as an upward pointing 00266 /// equilateral triangle). 00267 GLColor m_lrf_color ; 00268 00269 /// We can speed up or slow down the zoom by adjusting this factor. 00270 /// Higher values will result in amplifying mouse motion so that 00271 /// even a small movement results in a large zoom in or out; lower 00272 /// values will damp the mouse motion so that more dragging is 00273 /// required to achieve the desired zoom level. 00274 float m_zoom_drag_factor ; 00275 00276 public: 00277 // Accessing the various parameters 00278 static const std::string& device() ; 00279 static int baud_rate() ; 00280 static const std::string& markings_type() ; 00281 static int update_frequency() ; 00282 static const range<int>& angles_range() ; 00283 static int angles_step() ; 00284 static const GLColor& measurements_color() ; 00285 static float lrf_size() ; 00286 static float lrf_direction() ; 00287 static const GLColor& lrf_color() ; 00288 static float zoom_drag_factor() ; 00289 00290 // Clean-up 00291 ~Params() ; 00292 } ; 00293 } ; 00294 00295 //----------------------------------------------------------------------- 00296 00297 } // end of namespace encapsulating this file's definitions 00298 00299 #endif 00300 00301 /* So things look consistent in everyone's emacs... */ 00302 /* Local Variables: */ 00303 /* indent-tabs-mode: nil */ 00304 /* End: */