00001 /* +---------------------------------------------------------------------------+ 00002 | The Mobile Robot Programming Toolkit (MRPT) C++ library | 00003 | | 00004 | http://www.mrpt.org/ | 00005 | | 00006 | Copyright (C) 2005-2011 University of Malaga | 00007 | | 00008 | This software was written by the Machine Perception and Intelligent | 00009 | Robotics Lab, University of Malaga (Spain). | 00010 | Contact: Jose-Luis Blanco <jlblanco@ctima.uma.es> | 00011 | | 00012 | This file is part of the MRPT project. | 00013 | | 00014 | MRPT is free software: you can redistribute it and/or modify | 00015 | it under the terms of the GNU General Public License as published by | 00016 | the Free Software Foundation, either version 3 of the License, or | 00017 | (at your option) any later version. | 00018 | | 00019 | MRPT is distributed in the hope that it will be useful, | 00020 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 00021 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 00022 | GNU General Public License for more details. | 00023 | | 00024 | You should have received a copy of the GNU General Public License | 00025 | along with MRPT. If not, see <http://www.gnu.org/licenses/>. | 00026 | | 00027 +---------------------------------------------------------------------------+ */ 00028 #ifndef CRawlog_H 00029 #define CRawlog_H 00030 00031 #include <mrpt/poses/CPose2D.h> 00032 #include <mrpt/slam/CSensoryFrame.h> 00033 #include <mrpt/slam/CActionCollection.h> 00034 #include <mrpt/slam/CObservationComment.h> 00035 #include <mrpt/utils/CConfigFileMemory.h> 00036 00037 00038 namespace mrpt 00039 { 00040 namespace slam 00041 { 00042 DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE_LINKAGE( CRawlog, mrpt::utils::CSerializable, OBS_IMPEXP ) 00043 00044 using namespace mrpt::utils; 00045 00046 typedef std::pair<mrpt::system::TTimeStamp, CObservationPtr> TTimeObservationPair; //!< For usage with CRawlog classes. 00047 typedef std::multimap<mrpt::system::TTimeStamp, CObservationPtr> TListTimeAndObservations; //!< For usage with CRawlog classes. 00048 00049 00050 /** This class stores a rawlog (robotic datasets) in one of two possible formats: 00051 * - Format #1: A sequence of actions and observations. There is a sequence of objects, where each one can be of one type: 00052 * - An action: Implemented as a CActionCollection object, the actuation of the robot (i.e. odometry increment). 00053 * - Observations: Implemented as a CSensoryFrame, refering to a set of robot observations from the same pose. 00054 * - Format #2: A sequence of actions and observations. There is a sequence of objects, where each one can be of one type: 00055 * 00056 * Refer to the wiki page about <a href="http://www.mrpt.org/Rawlog_Format" >rawlog files</a>. 00057 * 00058 * See also the application <a href="http://www.mrpt.org/Application:RawLogViewer" >RawLogViewer</a > for the GUI program that visualizes and manages rawlogs. 00059 * 00060 * This class also publishes a static helper method for loading rawlog files in format #1: see CRawlog::readActionObservationPair 00061 * 00062 * There is a field for comments and blocks of parameters (in ini-like format) accessible through getCommentText and setCommentText 00063 * (introduced in MRPT 0.6.4). When serialized to a rawlog file, the commens are saved as an additional observation of the 00064 * type CObservationComments at the beginning of the file, but this observation does not appear after loading for clarity. 00065 * 00066 * \note Since MRPT version 0.5.5, this class also provides a STL container-like interface (see CRawlog::begin, CRawlog::iterator, ...). 00067 * \note The format #2 is supported since MRPT version 0.6.0. 00068 * \note There is a static helper method "detectImagesDirectory" for localizing the external images directory of a rawlog. 00069 * 00070 * \sa CSensoryFrame, CPose2D, <a href="http://www.mrpt.org/Rawlog_Format"> RawLog file format</a>. 00071 * \ingroup mrpt_obs_grp 00072 */ 00073 class OBS_IMPEXP CRawlog : public mrpt::utils::CSerializable 00074 { 00075 // This must be added to any CSerializable derived class: 00076 DEFINE_SERIALIZABLE( CRawlog ) 00077 00078 private: 00079 typedef std::vector<CSerializablePtr> TListObjects; 00080 TListObjects m_seqOfActObs; //!< The list where the objects really are in. 00081 00082 CObservationComment m_commentTexts; //!< Comments of the rawlog. 00083 00084 public: 00085 void getCommentText( std::string &t) const; //!< Returns the block of comment text for the rawlog 00086 std::string getCommentText() const; //!< Returns the block of comment text for the rawlog 00087 void setCommentText( const std::string &t); //!< Changes the block of comment text for the rawlog 00088 void getCommentTextAsConfigFile( mrpt::utils::CConfigFileMemory &memCfg ) const; //!< Saves the block of comment text for the rawlog into the passed config file object. 00089 00090 /** The type of each entry in a rawlog. 00091 * \sa CRawlog::getType 00092 */ 00093 enum TEntryType 00094 { 00095 etSensoryFrame = 0, 00096 etActionCollection, 00097 etObservation 00098 }; 00099 00100 /** Default constructor */ 00101 CRawlog(); 00102 00103 00104 /** Destructor: */ 00105 virtual ~CRawlog(); 00106 00107 /** Clear the sequence of actions/observations, freeing the memory of all the objects in the list. */ 00108 void clear(); 00109 00110 /** Clear the sequence of actions/observations, without deleting the objects themselves (USE ONLY IF YOU KNOW WHAT YOU DO, NORMALLY YOU'LL CALL "clear" INSTEAD). */ 00111 void clearWithoutDelete(); 00112 00113 /** Add an action to the sequence: a collection of just one element is created. 00114 * The object is duplicated, so the original one can be free if desired. 00115 */ 00116 void addAction( CAction &action ); 00117 00118 /** Add a set of actions to the sequence; the object is duplicated, so the original one can be free if desired. 00119 * \sa addObservations, addActionsMemoryReference 00120 */ 00121 void addActions( CActionCollection &action ); 00122 00123 /** Add a set of observations to the sequence; the object is duplicated, so the original one can be free if desired. 00124 * \sa addActions, addObservationsMemoryReference 00125 */ 00126 void addObservations( CSensoryFrame &observations ); 00127 00128 /** Add a set of actions to the sequence, using a smart pointer to the object to add. 00129 * \sa addActions, addObservationsMemoryReference, addObservationMemoryReference 00130 */ 00131 void addActionsMemoryReference( const CActionCollectionPtr &action ); 00132 00133 /** Add a set of observations to the sequence, using a smart pointer to the object to add. 00134 * \sa addObservations, addActionsMemoryReference, addObservationMemoryReference 00135 */ 00136 void addObservationsMemoryReference( const CSensoryFramePtr &observations ); 00137 00138 /** Add a single observation to the sequence, using a smart pointer to the object to add. 00139 * \sa addObservations, addActionsMemoryReference 00140 */ 00141 void addObservationMemoryReference( const CObservationPtr &observation ); 00142 00143 /** Load the contents from a file containing one of these possibilities: 00144 * - A "CRawlog" object. 00145 * - Directly the sequence of objects (pairs CSensoryFrame/CActionCollection or CObservation* objects). In this case the method stops reading on EOF of an unrecogniced class name. 00146 * \returns It returns false if the file does not exists. 00147 */ 00148 bool loadFromRawLogFile( const std::string &fileName ); 00149 00150 /** Saves the contents to a rawlog-file, compatible with RawlogViewer (As the sequence of internal objects). 00151 * The file is saved with gz-commpressed if MRPT has gz-streams. 00152 * \returns It returns false if any error is found while writing/creating the target file. 00153 */ 00154 bool saveToRawLogFile( const std::string &fileName ) const; 00155 00156 /** Returns the number of actions / observations object in the sequence. */ 00157 size_t size() const; 00158 00159 /** Returns the type of a given element. 00160 * \sa isAction, isObservation 00161 */ 00162 TEntryType getType( size_t index ) const; 00163 00164 /** Delete the action or observation stored in the given index. 00165 * \exception std::exception If index is out of bounds 00166 */ 00167 void remove( size_t index ); 00168 00169 /** Delete the elements stored in the given range of indices (including both the first and last one). 00170 * \exception std::exception If any index is out of bounds 00171 */ 00172 void remove( size_t first_index, size_t last_index ); 00173 00174 /** Returns the i'th element in the sequence, as being actions, where index=0 is the first object. 00175 * If it is not a CActionCollection, it throws an exception. Do neighter modify nor delete the returned pointer. 00176 * \sa size, isAction, getAsObservations, getAsObservation 00177 * \exception std::exception If index is out of bounds 00178 */ 00179 CActionCollectionPtr getAsAction( size_t index ) const; 00180 00181 /** Returns the i'th element in the sequence, as being an action, where index=0 is the first object. 00182 * If it is not an CSensoryFrame, it throws an exception. Do neighter modify nor delete the returned pointer. 00183 * \sa size, isAction, getAsAction, getAsObservation 00184 * \exception std::exception If index is out of bounds 00185 */ 00186 CSensoryFramePtr getAsObservations( size_t index ) const; 00187 00188 /** Returns the i'th element in the sequence, being its class whatever. 00189 * \sa size, isAction, getAsAction, getAsObservations 00190 * \exception std::exception If index is out of bounds 00191 */ 00192 CSerializablePtr getAsGeneric( size_t index ) const; 00193 00194 /** Returns the i'th element in the sequence, as being an observation, where index=0 is the first object. 00195 * If it is not an CObservation, it throws an exception. Do neighter modify nor delete the returned pointer. 00196 * This is the proper method to obtain the objects stored in a "only observations"-rawlog file (named "format #2" above. 00197 * \sa size, isAction, getAsAction 00198 * \exception std::exception If index is out of bounds 00199 */ 00200 CObservationPtr getAsObservation( size_t index ) const; 00201 00202 00203 /** A normal iterator, plus the extra method "getType" to determine the type of each entry in the sequence. */ 00204 class iterator 00205 { 00206 protected: 00207 TListObjects::iterator m_it; 00208 00209 public: 00210 iterator() : m_it() { } 00211 iterator(const TListObjects::iterator& it) : m_it(it) { } 00212 virtual ~iterator() { } 00213 00214 iterator & operator = (const iterator& o) { m_it = o.m_it; return *this; } 00215 00216 bool operator == (const iterator& o) { return m_it == o.m_it; } 00217 bool operator != (const iterator& o) { return m_it != o.m_it; } 00218 00219 CSerializablePtr operator *() { return *m_it; } 00220 00221 inline iterator operator ++(int) { iterator aux =*this; m_it++; return aux; } // Post 00222 inline iterator& operator ++() { m_it++; return *this; } // Pre 00223 inline iterator operator --(int) { iterator aux = *this; m_it--; return aux; } // Post 00224 inline iterator& operator --() { m_it--; return *this; } // Pre 00225 00226 TEntryType getType() const 00227 { 00228 if ( (*m_it)->GetRuntimeClass()->derivedFrom( CLASS_ID(CObservation) ) ) 00229 return etObservation; 00230 else if ( (*m_it)->GetRuntimeClass()->derivedFrom( CLASS_ID(CSensoryFrame) ) ) 00231 return etSensoryFrame; 00232 else 00233 return etActionCollection; 00234 } 00235 00236 static iterator erase( TListObjects& lst, const iterator &it) { return lst.erase(it.m_it); } 00237 }; 00238 00239 /** A normal iterator, plus the extra method "getType" to determine the type of each entry in the sequence. */ 00240 class const_iterator 00241 { 00242 protected: 00243 TListObjects::const_iterator m_it; 00244 00245 public: 00246 const_iterator() : m_it() { } 00247 const_iterator(const TListObjects::const_iterator& it) : m_it(it) { } 00248 virtual ~const_iterator() { } 00249 00250 bool operator == (const const_iterator& o) { return m_it == o.m_it; } 00251 bool operator != (const const_iterator& o) { return m_it != o.m_it; } 00252 00253 const CSerializablePtr operator *() const { return *m_it; } 00254 00255 inline const_iterator operator ++(int) { const_iterator aux =*this; m_it++; return aux; } // Post 00256 inline const_iterator& operator ++() { m_it++; return *this; } // Pre 00257 inline const_iterator operator --(int) { const_iterator aux = *this; m_it--; return aux; } // Post 00258 inline const_iterator& operator --() { m_it--; return *this; } // Pre 00259 00260 TEntryType getType() const 00261 { 00262 if ( (*m_it)->GetRuntimeClass()->derivedFrom( CLASS_ID(CObservation) ) ) 00263 return etObservation; 00264 else if ( (*m_it)->GetRuntimeClass()->derivedFrom( CLASS_ID(CSensoryFrame) ) ) 00265 return etSensoryFrame; 00266 else 00267 return etActionCollection; 00268 } 00269 00270 }; 00271 00272 00273 const_iterator begin() const { return m_seqOfActObs.begin(); } 00274 iterator begin() { return m_seqOfActObs.begin(); } 00275 const_iterator end() const { return m_seqOfActObs.end(); } 00276 iterator end() { return m_seqOfActObs.end(); } 00277 00278 iterator erase(const iterator &it) { return iterator::erase(m_seqOfActObs, it); } 00279 00280 /** Returns the sub-set of observations of a given class whose time-stamp t fulfills time_start <= t < time_end. 00281 * This method requires the timestamps of the sensors to be in strict ascending order (which should be the normal situation). 00282 * Otherwise, the output is undeterminate. 00283 * \sa findClosestObservationsByClass 00284 */ 00285 void findObservationsByClassInRange( 00286 mrpt::system::TTimeStamp time_start, 00287 mrpt::system::TTimeStamp time_end, 00288 const mrpt::utils::TRuntimeClassId *class_type, 00289 TListTimeAndObservations &out_found, 00290 size_t guess_start_position = 0 00291 ) const; 00292 00293 /** Efficiently copy the contents from other existing object, and remove the data from the origin (after calling this, the original object will have no actions/observations). 00294 */ 00295 void moveFrom( CRawlog &obj); 00296 00297 /** Efficiently swap the contents of two existing objects. 00298 */ 00299 void swap( CRawlog &obj); 00300 00301 /** Reads a consecutive pair action / observation from the rawlog opened at some input stream. 00302 * Previous contents of action and observations are discarded (using stlplus::smart_ptr::clear_unique), and 00303 * at exit they contain the new objects read from the rawlog file. 00304 * The input/output variable "rawlogEntry" is just a counter of the last rawlog entry read, for logging or monitoring purposes. 00305 * \return false if there was some error, true otherwise. 00306 * \sa getActionObservationPair, getActionObservationPairOrObservation 00307 */ 00308 static bool readActionObservationPair( 00309 CStream &inStream, 00310 CActionCollectionPtr &action, 00311 CSensoryFramePtr &observations, 00312 size_t & rawlogEntry ); 00313 00314 /** Reads a consecutive pair action/sensory_frame OR an observation, depending of the rawlog format, from the rawlog opened at some input stream. 00315 * Previous contents of action and observations are discarded (using stlplus::smart_ptr::clear_unique), and 00316 * at exit they contain the new objects read from the rawlog file. 00317 * 00318 * At return, one of this will happen: 00319 * - action/observations contain objects (i.e. action.present() evaluates as true). 00320 * - observation contains an object (i.e. observation.present() evaluates as true). 00321 * 00322 * The input/output variable "rawlogEntry" is just a counter of the last rawlog entry read, for logging or monitoring purposes. 00323 * \return false if there was some error, true otherwise. 00324 * \sa getActionObservationPair 00325 */ 00326 static bool getActionObservationPairOrObservation( 00327 CStream &inStream, 00328 CActionCollectionPtr &action, 00329 CSensoryFramePtr &observations, 00330 CObservationPtr &observation, 00331 size_t & rawlogEntry ); 00332 00333 /** Gets the next consecutive pair action / observation from the rawlog loaded into this object. 00334 * Previous contents of action and observations are discarded (using stlplus::smart_ptr::clear_unique), and 00335 * at exit they contain the new objects read from the rawlog file. 00336 * The input/output variable "rawlogEntry" is just a counter of the last rawlog entry read, for logging or monitoring purposes. 00337 * \return false if there was some error, true otherwise. 00338 * \sa readActionObservationPair 00339 */ 00340 bool getActionObservationPair( 00341 CActionCollectionPtr &action, 00342 CSensoryFramePtr &observations, 00343 size_t &rawlogEntry ) const; 00344 00345 /** Tries to auto-detect the external-images directory of the given rawlog file. 00346 * This searches for the existence of the directories: 00347 * - "<rawlog_file_path>/<rawlog_filename>_Images" 00348 * - "<rawlog_file_path>/<rawlog_filename>_images" 00349 * - "<rawlog_file_path>/<rawlog_filename>_IMAGES" 00350 * - "<rawlog_file_path>/Images" (This one is returned if none of the choices actually exists). 00351 * 00352 * The results from this function should be written into mrpt::utils::CImage::IMAGES_PATH_BASE to enable automatic 00353 * loading of extenrnally-stored images in rawlogs. 00354 */ 00355 static std::string detectImagesDirectory(const std::string &rawlogFilename); 00356 00357 }; // End of class def. 00358 00359 } // End of namespace 00360 } // End of namespace 00361 00362 #endif
| Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011 |