LoExperiment.H

00001 /**
00002    \file  Robots/LoBot/misc/LoExperiment.H
00003    \brief An object to store a parsed metrics log.
00004 
00005    This file defines a class that implements a simple object for storing
00006    a parsed metrics log, i.e., this class holds all the relevant data for
00007    an experiment conducted to record the robot's trajectory from start
00008    position to goal using an LGMD-based obstacle avoidance algorithm.
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/metlog/LoExperiment.H $
00043 // $Id: LoExperiment.H 14285 2010-12-01 17:33:15Z mviswana $
00044 //
00045 
00046 #ifndef LOBOT_EXPERIMENT_DOT_H
00047 #define LOBOT_EXPERIMENT_DOT_H
00048 
00049 //------------------------------ HEADERS --------------------------------
00050 
00051 // lobot headers
00052 #include "Robots/LoBot/metlog/LoPointList.H"
00053 #include "Robots/LoBot/metlog/LoPointTypes.H"
00054 #include "Robots/LoBot/util/LoStats.H"
00055 
00056 // Standard C++ headers
00057 #include <string>
00058 #include <vector>
00059 
00060 //----------------------------- NAMESPACE -------------------------------
00061 
00062 namespace lobot {
00063 
00064 //------------------------- CLASS DEFINITION ----------------------------
00065 
00066 /**
00067    \class lobot::Experiment
00068    \brief A class for storing all the relevant info from
00069    trajectory-related metrics logs.
00070 
00071    This class is used to hold all of the relevant data from a metlog and
00072    provide a convenient API for assisting with various number crunching
00073    tasks for the data analysis.
00074 */
00075 class Experiment {
00076    // Prevent copy and assignment
00077    Experiment(const Experiment&) ;
00078    Experiment& operator=(const Experiment&) ;
00079 
00080    /// Each experiment is loaded from a metrics log. This data member is
00081    /// used to store the name of that log file.
00082    std::string m_name ;
00083 
00084    /// These two data members hold the experiment's start and end times
00085    /// expressed as the number of milliseconds elapsed since the Unix
00086    /// epoch.
00087    ///
00088    /// DEVNOTE: We use "finis" rather than "finish" because "finis" is
00089    /// the same length string as "start" and this makes code line up
00090    /// nicely.
00091    long long int m_start_time, m_finis_time ;
00092 
00093    /// As the robot moves from start to finish, it periodically records
00094    /// its position. Some of these position checks correspond to specific
00095    /// events such as an emergency stop, an extrication or a bump. Most
00096    /// of them are simply trajectory information recorded for analysis.
00097    /// These lists are used to store the positions in their proper
00098    /// "slots."
00099    //@{
00100    PointList m_trajectory ;
00101    PointList m_emergency_stop ;
00102    PointList m_extricate ;
00103    PointList m_lgmd_extricate ;
00104    PointList m_bump ;
00105    //@}
00106 
00107    /// In addition to recording its position, the robot also periodically
00108    /// records its speed. This list holds all the speed readings.
00109    std::vector<float> m_speed ;
00110 
00111    /// These data members record the means and standard deviations for
00112    /// the different kinds of events we are interested in analyzing from
00113    /// all the experiments in a dataset. In addition to the means and
00114    /// standard deviations (which are used to produce pretty plots), we
00115    /// also record some other values such as the number of data points,
00116    /// the sum of all the data and the sum of the squares. These values
00117    /// are used for two-way ANOVA.
00118    ///
00119    /// DEVNOTE: This class does double duty: it stores the information
00120    /// extracted by the metlog parsing process and is also used to store
00121    /// the final data analysis results.
00122    ///
00123    /// Yes, this is lousy design.
00124    ///
00125    /// However, since lomet was originally conceived as a
00126    /// quick-and-dirty, one-time use, throwaway kind of program,
00127    /// expediency was put above design correctness, extensibility,
00128    /// robustness and all that jazz.
00129    //@{
00130    typedef generic_stats<int>   istats ; // shortcut to make code line up
00131    typedef generic_stats<float> fstats ; // shortcut to make code line up
00132    istats m_emstop_stats,
00133           m_lrf_extr_stats, m_lgmd_extr_stats, m_total_extr_stats ;
00134    fstats m_lgmd_success_stats, m_extr_success_stats, m_duration_stats ;
00135    //@}
00136 
00137    /// A private constructor because Experiment objects are created with
00138    /// a "named constructor" to ensure that clients don't create them on
00139    /// the stack.
00140    Experiment(const std::string& name) ;
00141 
00142 public:
00143    /// This method can be used to create Experiment objects. This "named
00144    /// constructor" ensures that all instances of this class are created
00145    /// with the new operator and not as local objects on the stack.
00146    static Experiment* create(const std::string& name) ;
00147 
00148    /// Return this experiment's name.
00149    std::string name() const {return m_name ;}
00150 
00151    /// These methods record the times at which the experiment began and
00152    /// ended. These time stamps are expressed as the number of
00153    /// milliseconds elapsed since the Unix epoch.
00154    ///
00155    /// These methods are meant to be used by the metlog parsing module,
00156    /// i.e., within the lex-generated rules in LoMetlogParser.l.
00157    ///
00158    /// DEVNOTE: We use "finis" rather than "finish" because "finis" is
00159    /// the same length string as "start" and this makes code line up
00160    /// nicely (as can be seen with the definitions of these functions).
00161    //@{
00162    void start_time(long long int t) {m_start_time = t ;}
00163    void finis_time(long long int t) {m_finis_time = t ;}
00164    //@}
00165 
00166    /// This function returns the duration of the experiment in
00167    /// milliseconds.
00168    int duration() const {return m_finis_time - m_start_time ;}
00169 
00170    /// These methods add trajectory info to their corresponding lists.
00171    /// They are meant to be used by the metlog parsing module, i.e.,
00172    /// within the lex-generated rules in LoMetlogParser.l.
00173    //@{
00174    void add_trajectory(int x, int y)     {m_trajectory.add(x, y)     ;}
00175    void add_emergency_stop(int x, int y) {m_emergency_stop.add(x, y) ;}
00176    void add_extricate(int x, int y)      {m_extricate.add(x, y)      ;}
00177    void add_lgmd_extricate(int x, int y) {m_lgmd_extricate.add(x, y) ;}
00178    void add_bump(int x, int y)           {m_bump.add(x, y)           ;}
00179    //@}
00180 
00181    /// This method adds a point to the named list.
00182    void add_point(PointListName, int x, int y) ;
00183 
00184    /// This method adds an entire point list to the one named by its
00185    /// parameter. It is meant to be used by the lomet program's main
00186    /// thread for building the result "experiment" from the analysis
00187    /// performed on the entire dataset.
00188    void point_list(PointListName, const PointList&) ;
00189 
00190    /// These functions return the sizes of the different point lists
00191    /// maintained by an experiment.
00192    //@{
00193    int trajectory_size()     const {return m_trajectory.size()     ;}
00194    int emergency_stop_size() const {return m_emergency_stop.size() ;}
00195    int extricate_size()      const {return m_extricate.size()      ;}
00196    int lgmd_extricate_size() const {return m_lgmd_extricate.size() ;}
00197    int bump_size()           const {return m_bump.size()           ;}
00198    //@}
00199 
00200    /// This function returns the size of the named point list.
00201    int size(PointListName) const ;
00202 
00203    /// This method returns the named point list.
00204    ///
00205    /// NOTE: This method returns a reference to an internal data
00206    /// structure. Clients should consider the returned data structure
00207    /// read-only, i.e., they should refrain from casting away the
00208    /// constness of the returned object and doing nasty things to it.
00209    const PointList& point_list(PointListName) const ;
00210 
00211    /// This method adds a speed reading to the list of speed readings
00212    /// subject to the condition that the speed actually represents a
00213    /// forward driving speed. This information is used to compute the
00214    /// average forward driving speed over the entire run.
00215    ///
00216    /// This method is meant to be used by the metlog parsing module,
00217    /// i.e., with the lex-generated rules in LoMetlogParser.l.
00218    void add_speed(float) ;
00219 
00220    /// This method adds all the speed readings in the given std::vector
00221    /// to this object's list of speed readings.
00222    ///
00223    /// NOTE: This method is meant to be used by the lomet main thread for
00224    /// computing the final result, which is represented using an instance
00225    /// of this class. Yes, dreadful design. Ideally, we should have split
00226    /// the result related functionality into a separate class, viz.,
00227    /// Result, which could have used private derivation from Experiment
00228    /// to take advantage of the functionality encapsulated here. Anyway,
00229    /// since the lomet program was originally conceived as a one-time,
00230    /// throwaway sort of thing, these shortcuts were deemed acceptable.
00231    void speed_list(const std::vector<float>&) ;
00232 
00233    /// This function returns an std::vector of floats containing the
00234    /// speed readings recorded by this experiment.
00235    ///
00236    /// WARNING: This function actually returns a const reference to an
00237    /// internal data structure. Yes, yes, bad design. Anyhoo, clients are
00238    /// advised/requested to treat the returned object as read-only.
00239    const std::vector<float>& speed_list() const {return m_speed ;}
00240 
00241    /// These functions record the means and standard deviations for
00242    /// various things such as the time-to-goal, number of extrication
00243    /// events, LGMD-based obstacle avoidance algorithm success rate, etc.
00244    /// These functions are meant to be used by the lomet main thread as
00245    /// part of the results computation (double duty, bad design, etc.;
00246    /// see comments appearing earlier).
00247    ///
00248    /// NOTE: In addition to the means and standard deviations, we also
00249    /// record some other values such as the n and sum and sum of squares.
00250    /// These are useful for two-way ANOVA.
00251    //@{
00252    void emergency_stop_stats   (const istats& s) {m_emstop_stats       = s ;}
00253    void lrf_extricate_stats    (const istats& s) {m_lrf_extr_stats     = s ;}
00254    void lgmd_extricate_stats   (const istats& s) {m_lgmd_extr_stats    = s ;}
00255    void total_extricate_stats  (const istats& s) {m_total_extr_stats   = s ;}
00256    void lgmd_success_stats     (const fstats& s) {m_lgmd_success_stats = s ;}
00257    void extricate_success_stats(const fstats& s) {m_extr_success_stats = s ;}
00258    void duration_stats         (const fstats& s) {m_duration_stats     = s ;}
00259    //@}
00260 
00261    /// This method saves the experiment to a file whose name is the same
00262    /// as the experiment's name. It is meant to be called by the lomet
00263    /// main thread for saving the data analysis results.
00264    ///
00265    /// It returns false to indicate that saving failed; this would happen
00266    /// if there is already an extant file that has the same name as this
00267    /// experiment. This feature ensures that metlogs loaded and parsed
00268    /// into an Experiment won't be overwritten if a client inadvertently
00269    /// calls this function. It also ensures that a previous result file
00270    /// won't be overwritten unless the user explicitly takes some action
00271    /// to allow the save to proceed, e.g., delete the old result file or
00272    /// reconfigure the program to save results to a differently named
00273    /// file.
00274    bool save() const ;
00275 
00276    /// Debugging support: dumps all the info to a file named dump-foo,
00277    /// where "foo" is actually the experiment's name, i.e., the same as
00278    /// the name of the log file from which this data object was created.
00279    void dump() const ;
00280 } ;
00281 
00282 //-----------------------------------------------------------------------
00283 
00284 } // end of namespace encapsulating this file's definitions
00285 
00286 #endif
00287 
00288 /* So things look consistent in everyone's emacs... */
00289 /* Local Variables: */
00290 /* indent-tabs-mode: nil */
00291 /* End: */
Generated on Sun May 8 08:05:55 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3