00001 /** 00002 \file Robots/LoBot/misc/LoScanMatch.H 00003 \brief Besl and McKay's Iterative Closest Point algorithm for laser 00004 range finder scan matching. 00005 00006 This file defines data structures and functions that implement the 00007 Iterative Closest Point algorithm described in: 00008 00009 Besl, P. J., McKay, N. D. 00010 A Method for Registration of 3-D Shapes 00011 IEEE Transactions on Pattern Analysis and Machine Intelligence, 00012 14(2):239--256, Feb 1992 00013 00014 For Robolocust, the ICP algorithm is used to perform scan matching 00015 between the current laser range finder scan and the previous one. The 00016 results of the scan matching procedure are used to correct odometry 00017 and then fed into the motion model for a grid-based FastSLAM algorithm 00018 so as to reduce the number of particles required by the 00019 Rao-Blackwellized particle filter (and, thereby, the total number of 00020 instances of the maps required). 00021 */ 00022 00023 // //////////////////////////////////////////////////////////////////// // 00024 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00025 // by the University of Southern California (USC) and the iLab at USC. // 00026 // See http://iLab.usc.edu for information about this project. // 00027 // //////////////////////////////////////////////////////////////////// // 00028 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00029 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00030 // in Visual Environments, and Applications'' by Christof Koch and // 00031 // Laurent Itti, California Institute of Technology, 2001 (patent // 00032 // pending; application number 09/912,225 filed July 23, 2001; see // 00033 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00034 // //////////////////////////////////////////////////////////////////// // 00035 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00036 // // 00037 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00038 // redistribute it and/or modify it under the terms of the GNU General // 00039 // Public License as published by the Free Software Foundation; either // 00040 // version 2 of the License, or (at your option) any later version. // 00041 // // 00042 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00043 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00044 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00045 // PURPOSE. See the GNU General Public License for more details. // 00046 // // 00047 // You should have received a copy of the GNU General Public License // 00048 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00049 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00050 // Boston, MA 02111-1307 USA. // 00051 // //////////////////////////////////////////////////////////////////// // 00052 // 00053 // Primary maintainer for this file: mviswana usc edu 00054 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/slam/LoScanMatch.H $ 00055 // $Id: LoScanMatch.H 13570 2010-06-16 15:56:00Z mviswana $ 00056 // 00057 00058 #ifndef LOBOT_SCAN_MATCH_DOT_H 00059 #define LOBOT_SCAN_MATCH_DOT_H 00060 00061 //------------------------------ HEADERS -------------------------------- 00062 00063 // lobot headers 00064 #include "Robots/LoBot/slam/LoPose.H" 00065 #include "Robots/LoBot/util/triple.hh" 00066 00067 // Standard C++ headers 00068 #include <vector> 00069 00070 //----------------------------- NAMESPACE ------------------------------- 00071 00072 namespace lobot { 00073 00074 //------------------------- CLASS DEFINITION ---------------------------- 00075 00076 /** 00077 \class lobot::Scan 00078 \brief An encapsulation of a laser range finder scan. 00079 00080 This class holds the range readings made by lobot's laser range finder 00081 in both polar and Cartesian form. It also records the robot's pose 00082 corresponding to those readings. 00083 00084 The scan matching algorithm takes two instances of this class and 00085 returns the transformation required to "convert" one scan to the other. 00086 */ 00087 class Scan { 00088 /// Each scan must be associated with a corresponding robot pose. 00089 Pose m_pose ; 00090 00091 /// A scan consists of the range readings returned by the laser range 00092 /// finder in polar form as well as Cartesian coordinates. This inner 00093 /// class holds both these readings forms together in one structure. 00094 public: 00095 class RangeReading { 00096 /// Each range reading is held in both polar and Cartesian forms. 00097 float m_r, m_x, m_y ; 00098 00099 public: 00100 /// During initialization, the client must specify both polar and 00101 /// Cartesisan coordinates for a range reading. 00102 RangeReading(float r, float x, float y) ; 00103 00104 /// Accessors. 00105 //@{ 00106 float r() const {return m_r ;} 00107 float x() const {return m_x ;} 00108 float y() const {return m_y ;} 00109 //@} 00110 } ; 00111 00112 private: 00113 /// This data structure holds the range readings associated with a 00114 /// scan. 00115 std::vector<RangeReading> m_range_readings ; 00116 00117 public: 00118 /// When a scan object is created, it should be given the pose and a 00119 /// vector containing the range readings in polar form. The 00120 /// constructor will take care of deriving the Cartesian coordinates 00121 /// for each distance reading from the given pose and the polar 00122 /// ranges. 00123 //@{ 00124 Scan(const Pose&, const std::vector<int>&) ; 00125 Scan(const Pose&, const std::vector<float>&) ; 00126 //@} 00127 00128 /// Various accessors. 00129 //@{ 00130 float x() const {return m_pose.x() ;} 00131 float y() const {return m_pose.y() ;} 00132 float theta() const {return m_pose.theta() ;} 00133 RangeReading& operator[](int i) {return m_range_readings[i] ;} 00134 const RangeReading& operator[](int i) const {return m_range_readings[i] ;} 00135 //@} 00136 00137 /// Clean-up. 00138 ~Scan() ; 00139 } ; 00140 00141 //------------------------- CLASS DEFINITION ---------------------------- 00142 00143 /** 00144 \class lobot::Transformation 00145 \brief An encapsulation of a transformation for "converting" one scan 00146 to another. 00147 00148 This class holds the rotation and translation required to transform a 00149 new scan into a reference scan. 00150 00151 Given two scans, this implementation of the IDC algorithm returns a 00152 Transformation. 00153 */ 00154 class Transformation { 00155 /// The rotation required to convert one scan to another. 00156 float m_w ; // omega (as used in the Lu-Milios paper) 00157 00158 /// The translation involved in converting one scan to another. 00159 float m_Tx, m_Ty ; 00160 00161 public: 00162 /// Initialization. 00163 //@{ 00164 Transformation(float w, float Tx, float Ty) ; 00165 Transformation(const triple<float, float, float>&) ; 00166 //@} 00167 00168 /// Accessors. 00169 //@{ 00170 float w() const {return m_w ;} 00171 float Tx() const {return m_Tx ;} 00172 float Ty() const {return m_Ty ;} 00173 //@} 00174 } ; 00175 00176 //----------------------------- FUNCTIONS ------------------------------- 00177 00178 /// This function implements the Iterative Dual Correspondence algorithm 00179 /// described by Lu and Milios to match two laser range finder scans and 00180 /// return the transformation required to properly register the current 00181 /// scan with reference to the previous one. 00182 Transformation match_scans(const Scan& curr, const Scan& prev) ; 00183 00184 //----------------------------------------------------------------------- 00185 00186 } // end of namespace encapsulating this file's definitions 00187 00188 #endif 00189 00190 /* So things look consistent in everyone's emacs... */ 00191 /* Local Variables: */ 00192 /* indent-tabs-mode: nil */ 00193 /* End: */