00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "Robots/LoBot/metlog/LoExperiment.H"
00046 #include "Robots/LoBot/config/LoConfigHelpers.H"
00047 #include "Robots/LoBot/util/LoFile.H"
00048 #include "Robots/LoBot/misc/LoExcept.H"
00049 #include "Robots/LoBot/misc/singleton.hh"
00050
00051
00052 #include <iomanip>
00053 #include <fstream>
00054 #include <algorithm>
00055 #include <iterator>
00056
00057
00058
00059 namespace lobot {
00060
00061
00062
00063 namespace {
00064
00065
00066 template<typename T>
00067 inline T conf(const std::string& key, const T& default_value)
00068 {
00069 return lobot::global_conf<T>(key, default_value) ;
00070 }
00071
00072
00073
00074 class ExperimentParams : public singleton<ExperimentParams> {
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 float m_forward_speed_threshold ;
00099
00100
00101 ExperimentParams() ;
00102
00103
00104 friend class singleton<ExperimentParams> ;
00105
00106 public:
00107
00108
00109 static float forward_speed_threshold() {
00110 return instance().m_forward_speed_threshold ;
00111 }
00112
00113 } ;
00114
00115
00116 ExperimentParams::ExperimentParams()
00117 : m_forward_speed_threshold(conf("forward_speed_threshold", 0.099f))
00118 {}
00119
00120
00121 typedef ExperimentParams Params ;
00122
00123 }
00124
00125
00126
00127 Experiment* Experiment::create(const std::string& name)
00128 {
00129 return new Experiment(name) ;
00130 }
00131
00132 Experiment::Experiment(const std::string& name)
00133 : m_name(name),
00134 m_start_time(0), m_finis_time(0),
00135 m_trajectory(300),
00136 m_emergency_stop(100),
00137 m_extricate(100),
00138 m_lgmd_extricate(100),
00139 m_bump(5),
00140 m_emstop_stats(0, 0),
00141 m_lrf_extr_stats(0, 0),
00142 m_lgmd_extr_stats(0, 0),
00143 m_total_extr_stats(0, 0),
00144 m_lgmd_success_stats(0, 0),
00145 m_duration_stats(0, 0)
00146 {
00147 m_speed.reserve(40) ;
00148 }
00149
00150
00151
00152
00153 void Experiment::add_point(PointListName n, int x, int y)
00154 {
00155 switch (n)
00156 {
00157 case TRAJECTORY:
00158 add_trajectory(x, y) ;
00159 break ;
00160 case EMERGENCY_STOP:
00161 add_emergency_stop(x, y) ;
00162 break ;
00163 case EXTRICATE:
00164 add_extricate(x, y) ;
00165 break ;
00166 case LGMD_EXTRICATE:
00167 add_lgmd_extricate(x, y) ;
00168 break ;
00169 case BUMP:
00170 add_bump(x, y) ;
00171 break ;
00172 default:
00173 throw misc_error(LOGIC_ERROR) ;
00174 }
00175 }
00176
00177
00178 void Experiment::point_list(PointListName n, const PointList& L)
00179 {
00180 switch (n)
00181 {
00182 case TRAJECTORY:
00183 m_trajectory = L ;
00184 break ;
00185 case EMERGENCY_STOP:
00186 m_emergency_stop = L ;
00187 break ;
00188 case EXTRICATE:
00189 m_extricate = L ;
00190 break ;
00191 case LGMD_EXTRICATE:
00192 m_lgmd_extricate = L ;
00193 break ;
00194 case BUMP:
00195 m_bump = L ;
00196 break ;
00197 default:
00198 throw misc_error(LOGIC_ERROR) ;
00199 }
00200 }
00201
00202
00203
00204
00205
00206
00207 void Experiment::add_speed(float speed)
00208 {
00209 if (speed >= Params::forward_speed_threshold())
00210 m_speed.push_back(speed) ;
00211 }
00212
00213
00214
00215 void Experiment::speed_list(const std::vector<float>& speeds)
00216 {
00217 std::copy(speeds.begin(), speeds.end(), std::back_inserter(m_speed)) ;
00218 }
00219
00220
00221
00222 int Experiment::size(PointListName n) const
00223 {
00224 switch (n)
00225 {
00226 case TRAJECTORY:
00227 return trajectory_size() ;
00228 case EMERGENCY_STOP:
00229 return emergency_stop_size() ;
00230 case EXTRICATE:
00231 return extricate_size() ;
00232 case LGMD_EXTRICATE:
00233 return lgmd_extricate_size() ;
00234 case BUMP:
00235 return bump_size() ;
00236 }
00237 throw misc_error(LOGIC_ERROR) ;
00238 }
00239
00240 const PointList& Experiment::point_list(PointListName n) const
00241 {
00242 switch (n)
00243 {
00244 case TRAJECTORY:
00245 return m_trajectory ;
00246 case EMERGENCY_STOP:
00247 return m_emergency_stop ;
00248 case EXTRICATE:
00249 return m_extricate ;
00250 case LGMD_EXTRICATE:
00251 return m_lgmd_extricate ;
00252 case BUMP:
00253 return m_bump ;
00254 }
00255 throw misc_error(LOGIC_ERROR) ;
00256 }
00257
00258
00259
00260 static void
00261 save_point_list(std::ostream& os, const PointList& L, const char* label)
00262 {
00263 for (PointList::iterator i = L.begin(); i != L.end(); ++i)
00264 os << label << ' ' << i->first << ' ' << i->second << '\n' ;
00265 }
00266
00267 static std::ostream&
00268 operator<<(std::ostream& os, const generic_stats<int>& s)
00269 {
00270 os << s.n << ' ' << s.sum << ' ' << s.ssq << ' '
00271 << s.mean << ' ' << s.stdev ;
00272 return os ;
00273 }
00274
00275 static std::ostream&
00276 operator<<(std::ostream& os, const generic_stats<float>& s)
00277 {
00278 using std::setprecision ; using std::fixed ;
00279 os << s.n << ' '
00280 << setprecision(3) << fixed << s.sum << ' '
00281 << setprecision(3) << fixed << s.ssq << ' '
00282 << setprecision(3) << fixed << s.mean << ' '
00283 << setprecision(3) << fixed << s.stdev ;
00284 return os ;
00285 }
00286
00287 bool Experiment::save() const
00288 {
00289 if (exists(m_name.c_str()))
00290 return false ;
00291
00292 std::ofstream ofs(m_name.c_str()) ;
00293 save_point_list(ofs, m_trajectory, "trajectory") ;
00294 save_point_list(ofs, m_emergency_stop, "emergency_stop") ;
00295 save_point_list(ofs, m_extricate, "extricate") ;
00296 save_point_list(ofs, m_lgmd_extricate, "lgmd_extricate") ;
00297 save_point_list(ofs, m_bump, "bump") ;
00298
00299 ofs << "emstop_stats " << m_emstop_stats << '\n' ;
00300 ofs << "lrf_extrication_stats " << m_lrf_extr_stats << '\n' ;
00301 ofs << "lgmd_extrication_stats " << m_lgmd_extr_stats << '\n' ;
00302 ofs << "total_extrication_stats " << m_total_extr_stats << '\n' ;
00303 ofs << "lgmd_success_rate_stats " << m_lgmd_success_stats << '\n' ;
00304 ofs << "extr_success_rate_stats " << m_extr_success_stats << '\n' ;
00305 ofs << "speed_stats "
00306 << compute_stats<float>(m_speed.begin(),m_speed.end())<< '\n' ;
00307 ofs << "duration_stats " << m_duration_stats << '\n' ;
00308
00309 return true ;
00310 }
00311
00312
00313
00314 static void
00315 dump_trajectory(std::ostream& os, const PointList& L, const char* label)
00316 {
00317 os << L.size() << ' ' << label << " points:\n\t" ;
00318
00319 using namespace std ;
00320 for (PointList::iterator i = L.begin(); i != L.end(); ++i)
00321 os << '(' << left << setw(6) << i->first << i->second << ")\n\t" ;
00322 os << "\n\n" ;
00323 }
00324
00325 void Experiment::dump() const
00326 {
00327 using namespace std ;
00328
00329 ofstream ofs((m_name + ".dump").c_str()) ;
00330 ofs << "name: " << m_name << "\n\n" ;
00331
00332 ofs << "start time: " << m_start_time << '\n' ;
00333 ofs << "finis time: " << m_finis_time << '\n' ;
00334 ofs << " duration: " << setprecision(3) << fixed
00335 << (duration()/1000.0f) << " seconds\n\n" ;
00336
00337 dump_trajectory(ofs, m_trajectory, "normal trajectory") ;
00338 dump_trajectory(ofs, m_emergency_stop, "emergency stop") ;
00339 dump_trajectory(ofs, m_extricate, "extricate") ;
00340 dump_trajectory(ofs, m_lgmd_extricate, "LGMD extricate") ;
00341 dump_trajectory(ofs, m_bump, "bump") ;
00342
00343 std::pair<float, float> s =
00344 mean_stdev<float>(m_speed.begin(), m_speed.end()) ;
00345 ofs << "forward driving speed = "
00346 << setprecision(3) << fixed << s.first << " m/s +/- "
00347 << setprecision(3) << fixed << s.second << " m/s from "
00348 << m_speed.size() << " readings:\n\t" ;
00349 copy(m_speed.begin(), m_speed.end(),
00350 ostream_iterator<float>(ofs, " m/s\n\t")) ;
00351 ofs << '\n' ;
00352 }
00353
00354
00355
00356 }
00357
00358
00359
00360
00361