LoLaserWindow.H

Go to the documentation of this file.
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: */
Generated on Sun May 8 08:05:56 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3