00001 /** 00002 \file Robots/LoBot/ui/LoLaserViz.H 00003 \brief LRF visualizer. 00004 00005 This file defines a class that implements a drawable for visualizing 00006 the laser range finder's measurement data. 00007 */ 00008 00009 // //////////////////////////////////////////////////////////////////// // 00010 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00011 // by the University of Southern California (USC) and the iLab at USC. // 00012 // See http://iLab.usc.edu for information about this project. // 00013 // //////////////////////////////////////////////////////////////////// // 00014 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00015 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00016 // in Visual Environments, and Applications'' by Christof Koch and // 00017 // Laurent Itti, California Institute of Technology, 2001 (patent // 00018 // pending; application number 09/912,225 filed July 23, 2001; see // 00019 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00020 // //////////////////////////////////////////////////////////////////// // 00021 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00022 // // 00023 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00024 // redistribute it and/or modify it under the terms of the GNU General // 00025 // Public License as published by the Free Software Foundation; either // 00026 // version 2 of the License, or (at your option) any later version. // 00027 // // 00028 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00029 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00030 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00031 // PURPOSE. See the GNU General Public License for more details. // 00032 // // 00033 // You should have received a copy of the GNU General Public License // 00034 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00035 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00036 // Boston, MA 02111-1307 USA. // 00037 // //////////////////////////////////////////////////////////////////// // 00038 // 00039 // Primary maintainer for this file: mviswana usc edu 00040 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/ui/LoLaserViz.H $ 00041 // $Id: LoLaserViz.H 13674 2010-07-18 22:13:22Z mviswana $ 00042 // 00043 00044 #ifndef LOBOT_LRF_VISUALIZER_DOT_H 00045 #define LOBOT_LRF_VISUALIZER_DOT_H 00046 00047 //------------------------------ HEADERS -------------------------------- 00048 00049 // lobot headers 00050 #include "Robots/LoBot/ui/LoDrawable.H" 00051 #include "Robots/LoBot/ui/LoLaserWindowMarkings.H" 00052 #include "Robots/LoBot/ui/LoGLCanvas.H" 00053 00054 #include "Robots/LoBot/io/LoLaserRangeFinder.H" 00055 00056 #include "Robots/LoBot/misc/LoTypes.H" 00057 #include "Robots/LoBot/misc/singleton.hh" 00058 #include "Robots/LoBot/util/range.hh" 00059 00060 // Standard C++ headers 00061 #include <memory> 00062 00063 //----------------------------- NAMESPACE ------------------------------- 00064 00065 namespace lobot { 00066 00067 //------------------------- CLASS DEFINITION ---------------------------- 00068 00069 /** 00070 \class lobot::LaserViz 00071 \brief A drawable for visualizing laser range finder data. 00072 00073 This class uses OpenGL to visualize the Hokuyo laser range finder's 00074 distance measurements. A world coordinate system is setup to match the 00075 maximum range of the laser range finder and the device itself is 00076 depicted as a small triangle centered at the origin of the world 00077 coordinate system. A grid is overlaid on the world coordinate system 00078 with cells at regular intervals and the distance measurements are 00079 shown as rays emanating from the central triangle in each supported 00080 direction. Instead of a grid, the visualizer may also be configured to 00081 display concentric rings to help users gauge the distances being 00082 measured by the LRF. 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 class LaserViz : public Drawable { 00088 /// Since this drawable is used to visualize LRF data, it makes sense 00089 /// for it to keep handy a reference to an LRF object. 00090 const LaserRangeFinder* m_lrf ; 00091 00092 /// We use a helper class to manage the OpenGL window and viewport 00093 /// transformations. 00094 std::auto_ptr<GLCanvas> m_canvas ; 00095 00096 /// We use another helper class to draw markings at regular intervals 00097 /// to make it easier for users to read/gauge the distances being spit 00098 /// out by the laser range finder. 00099 std::auto_ptr<LaserWindowMarkings> m_markings ; 00100 00101 public: 00102 /// Initialization. 00103 LaserViz(const LaserRangeFinder*) ; 00104 00105 private: 00106 /// OpenGL related initialization: we need to configure the 00107 /// initial projection matrix based on the LRF max distance. 00108 void gl_init() ; 00109 00110 /// This method renders the latest measurements obtained from the 00111 /// laser range finder. 00112 void render_me() ; 00113 00114 /// The LRF visualizer supports zoom/pan operations. 00115 //@{ 00116 void zoom_by(float zoom_factor) ; 00117 void pan(int x, int y, int prev_x, int prev_y) ; 00118 void reset_zoom_pan() ; 00119 //@} 00120 00121 /// OpenGL related clean-up: the laser window ring markings object 00122 /// uses a display list that has to be released before the GL 00123 /// rendering context is destroyed, which may happen before (not 00124 /// good) or after (okay) the laser visualizer's destructor is called 00125 /// by the main thread because the rendering context is managed by 00126 /// the lobot::MainWindow object in a different thread and the OS 00127 /// scheduler can decide to take down threads however it pleases. 00128 /// 00129 /// Therefore, we need to release the ring markings object when the 00130 /// main window lets us know that the GL rendering context is about 00131 /// to be nuked, i.e., when it invokes each drawable's gl_cleanup() 00132 /// method. If we wait to do this in the destructor, we could get a 00133 /// segfault as the Robolocust controller shuts down. 00134 virtual void gl_cleanup() ; 00135 00136 public: 00137 /// Clean-up. 00138 ~LaserViz() ; 00139 00140 private: 00141 /// This inner class encapsulates various parameters that can be used 00142 /// to tweak different aspects of the LRF and behaviours' 00143 /// visualization. 00144 class Params : public singleton<Params> { 00145 /// The location and size of the LRF visualizer (within the 00146 /// Robolocust main window). 00147 Drawable::Geometry m_geometry ; 00148 00149 /// The laser range finder's measurements can be depicted either as 00150 /// rays emanating from the LRF or as hull joining the tips of all 00151 /// the rays (but without the actual rays themselves). This setting 00152 /// allows users to change the LRF measurements style. 00153 std::string m_measurements_style ; 00154 00155 /// The type of markings that should be used to help users read the 00156 /// distance measurements being spit out by the laser range finder. 00157 /// At present, two marking types are supported, viz., grid and 00158 /// rings. In grid mode, we draw horizontal and vertical lines at 00159 /// regular intervals. In rings mode, we draw concentric circular 00160 /// contours to show the distance from the laser range finder. 00161 std::string m_markings_type ; 00162 00163 /// The LRF returns distance measurements corresponding to a range 00164 /// of angles with zero degrees being in front of the device, 00165 /// negative angles on the right and positive angles on the left. 00166 /// Drawing the measurements for all the angles in the device's 00167 /// range can result in a very cluttered and illegible picture. 00168 /// Thus, we allow users to specify the range of angles to use and 00169 /// the step size by which to increment the angle as we iterate 00170 /// through this range. 00171 //@{ 00172 range<int> m_angles_range ; 00173 int m_angles_step ; 00174 //@} 00175 00176 /// Color for the rays depicting laser range finder distance 00177 /// measurements. 00178 GLColor m_measurements_color ; 00179 00180 /// The LRF itself is depicted as a combination of a rectangle and 00181 /// a triangle. The triangle serves to let users know which 00182 /// direction the device is pointed toward. These two settings 00183 /// specify the size and direction of the LRF. 00184 /// 00185 /// The direction is simply an angle in the range 0 to 360 degrees. 00186 /// 00187 /// The size is specified in terms of the half-size of the shared 00188 /// edge between the rectangle and triangle. If this size is R, 00189 /// then the entire figure will be inscribed within an imaginary 00190 /// square of size 2R. 00191 /// 00192 /// NOTE: As the visualization window's logical/world coordinate 00193 /// system is setup to match the Hokuyo's specs, the units of the 00194 /// above-mentioned R will be millimeters. However, these are 00195 /// "logical" not true physical mm. 00196 //@{ 00197 float m_lrf_size ; 00198 float m_lrf_direction ; 00199 //@} 00200 00201 /// Color for the LRF device (depicted as an upward pointing 00202 /// equilateral triangle). 00203 GLColor m_lrf_color ; 00204 00205 /// Private constructor because this is a singleton. 00206 Params() ; 00207 friend class singleton<Params> ; 00208 00209 public: 00210 /// Accessing the various parameters 00211 //@{ 00212 static const Drawable::Geometry& geometry() { 00213 return instance().m_geometry ; 00214 } 00215 static const std::string& measurements_style() { 00216 return instance().m_measurements_style ; 00217 } 00218 static bool draw_rays() {return measurements_style() == "rays" ;} 00219 static bool draw_hull() {return measurements_style() == "hull" ;} 00220 static const std::string& markings_type() { 00221 return instance().m_markings_type ; 00222 } 00223 static const range<int>& angles_range() { 00224 return instance().m_angles_range ; 00225 } 00226 static int angles_step() {return instance().m_angles_step ;} 00227 static const GLColor& measurements_color() { 00228 return instance().m_measurements_color ; 00229 } 00230 static float lrf_size() {return instance().m_lrf_size ;} 00231 static float lrf_direction() {return instance().m_lrf_direction ;} 00232 static const GLColor& lrf_color() {return instance().m_lrf_color ;} 00233 //@} 00234 00235 /// Clean-up 00236 ~Params() ; 00237 } ; 00238 } ; 00239 00240 //----------------------------------------------------------------------- 00241 00242 } // end of namespace encapsulating this file's definitions 00243 00244 #endif 00245 00246 /* So things look consistent in everyone's emacs... */ 00247 /* Local Variables: */ 00248 /* indent-tabs-mode: nil */ 00249 /* End: */