TestLongDelay.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2012, 2013 Instituto de Sistemas e Robotica, Instituto Superior Tecnico
00003  *
00004  * This file is part of SocRob Multicast.
00005  *
00006  * SocRob Multicast is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation, either version 3 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * SocRob Multicast is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with SocRob Multicast.  If not, see <http://www.gnu.org/licenses/>.
00018  */
00019 
00020 #ifndef TESTLONGDELAY_HPP
00021 #define TESTLONGDELAY_HPP
00022 
00023 #include <iostream>
00024 #include <fstream>
00025 
00026 #include <boost/thread/mutex.hpp>
00027 #include <boost/lexical_cast.hpp>
00028 
00029 #include <ros/ros.h>
00030 
00031 #include <socrob/multicast.h>
00032 
00033 #include <std_msgs/UInt8.h>
00034 #include <std_msgs/UInt32.h>
00035 #include <std_msgs/Time.h>
00036 
00037 
00038 
00039 using namespace std;
00040 using namespace ros;
00041 using namespace socrob::multicast;
00042 using boost::lexical_cast;
00043 
00044 
00045 
00046 struct rcv_data {
00047   Time time;
00048   size_t serial;
00049   Time production_time;
00050   Time send_time;
00051 };
00052 
00053 
00054 
00055 class TestLongDelay
00056 {
00057     int sid_;
00058     
00059     Time production_time_;
00060     size_t production_serial_;
00061     
00062     boost::mutex mutex_;
00063     vector<list<rcv_data> > rcv_;
00064     
00065     Time output_time_base_;
00066     unsigned output_line_[5];
00067     ofstream output_[5];
00068     
00069     
00070   public:
00071     TestLongDelay (int sid,
00072                    string const& type) :
00073       sid_ (sid),
00074       production_time_ (Time::now()),
00075       production_serial_ (0),
00076       rcv_ (5, list<rcv_data>()),
00077       output_time_base_ (Time::now()) {
00078       for (int i = 0; i < 5; i++) {
00079 #ifdef SOCROB_MULTICAST_LONG_SYNC_WORST
00080         output_[i].open ( ("/tmp/TestLongDelay_" + type + "_WorstCase_" + lexical_cast<string> (output_time_base_.sec) + "_at_" + lexical_cast<string> (sid_) + "_from_" + lexical_cast<string> (i) + ".csv").c_str());
00081 #else
00082         output_[i].open ( ("/tmp/TestLongDelay_" + type + "_Normal_" + lexical_cast<string> (output_time_base_.sec) + "_at_" + lexical_cast<string> (sid_) + "_from_" + lexical_cast<string> (i) + ".csv").c_str());
00083 #endif
00084         output_[i] << "\"Serial Number\""
00085                    << ";\"Production Time\""
00086                    << ";\"Send Time\""
00087                    << ";\"Reception Time\""
00088                    << ";\"Use Duration\""
00089                    << ";\"ACC Use Duration\""
00090                    << ";\"(Without) Age Rcv\""
00091                    << ";\"(Without) Age End\""
00092                    << ";\"(Without) ACC Average\""
00093                    << ";\"(With) Age Rcv\""
00094                    << ";\"(With) Age End\""
00095                    << ";\"(With) ACC Average\""
00096                    << endl;
00097         output_line_[i] = 1;
00098       }
00099     }
00100     
00101     
00102     
00103     ~TestLongDelay() {
00104       for (int i = 0; i < 5; i++) {
00105         output_[i] << ";;;;;;;;;;;" << endl;
00106         unsigned l = output_line_[i];
00107         output_[i] << "\"Received packages:\";=" << l << "-4" << endl;
00108         output_[i] << "\"Lost packages in between:\";=1+A" << l << "-A5-(" << l << "-4)" << endl;
00109         output_[i] << "\"Average without transmission:\";=I" << l << "/F" << l << "" << endl;
00110         output_[i] << "\"Average with transmission:\";=L" << l << "/F" << l << "" << endl;
00111       }
00112     }
00113     
00114     
00115     
00116     void
00117     long_marshall (vector<uint8_t> & buffer) {
00118       Time send_time = Time::now();
00119       
00120       std_msgs::UInt8 sid_msg;
00121       sid_msg.data = sid_;
00122       serialize_append (buffer, sid_msg);
00123       
00124       std_msgs::UInt32 prod_serial_msg;
00125       prod_serial_msg.data = production_serial_;
00126       serialize_append (buffer, prod_serial_msg);
00127       
00128       std_msgs::Time prod_time_msg;
00129       prod_time_msg.data = production_time_;
00130       serialize_append (buffer, prod_time_msg);
00131       
00132       std_msgs::Time send_time_msg;
00133       send_time_msg.data = send_time;
00134       serialize_append (buffer, send_time_msg);
00135       
00136       production_time_ = send_time;
00137       production_serial_++;
00138     }
00139     
00140     
00141     
00142     void
00143     long_unmarshall (socrob::multicast::id_type,
00144                      vector<uint8_t> & buffer) {
00145       Time now = Time::now();
00146       
00147       size_t offset = 0;
00148       std_msgs::UInt8 sid_msg;
00149       offset += deserialize (sid_msg, buffer, offset);
00150       std_msgs::UInt32 prod_serial_msg;
00151       offset += deserialize (prod_serial_msg, buffer, offset);
00152       std_msgs::Time prod_time_msg;
00153       offset += deserialize (prod_time_msg, buffer, offset);
00154       std_msgs::Time send_time_msg;
00155       offset += deserialize (send_time_msg, buffer, offset);
00156       
00157       int rcv_sid = sid_msg.data;
00158       
00159       rcv_data rcv;
00160       rcv.time = now;
00161       rcv.serial = prod_serial_msg.data;
00162       rcv.production_time = prod_time_msg.data;
00163       rcv.send_time = send_time_msg.data;
00164       
00165       boost::lock_guard<boost::mutex> _ (mutex_);
00166       
00167       rcv_[rcv_sid].push_back (rcv);
00168       
00169       unsigned l = ++ (output_line_[rcv_sid]);
00170       if (l >= 3 + 3/*line 3 + 3 ignored in statistics*/) {
00171         output_[rcv_sid] << rcv.serial
00172                          << ";" << (rcv.production_time - output_time_base_)
00173                          << ";" << (rcv.send_time - output_time_base_)
00174                          << ";" << (rcv.time - output_time_base_)
00175                          << ";" << "=D" << l << "-D" << (l - 1)
00176                          << ";" << "=E" << l << "+F" << (l - 1)
00177                          << ";" << "=C" << (l - 1) << "-B" << (l - 1)
00178                          << ";" << "=G" << l << "+E" << l
00179                          << ";" << "=I" << (l - 1) << "+(((G" << l << "+H" << l << ")/2)*E" << l << ")"
00180                          << ";" << "=D" << (l - 1) << "-B" << (l - 1)
00181                          << ";" << "=J" << l << "+E" << l
00182                          << ";" << "=L" << (l - 1) << "+(((J" << l << "+K" << l << ")/2)*E" << l << ")"
00183                          << endl;
00184       }
00185       else {
00186         output_[rcv_sid] << rcv.serial
00187                          << ";" << (rcv.production_time - output_time_base_)
00188                          << ";" << (rcv.send_time - output_time_base_)
00189                          << ";" << (rcv.time - output_time_base_)
00190                          << ";" << "\"vvv\""
00191                          << ";" << "0"
00192                          << ";" << "\"vvv\""
00193                          << ";" << "\"vvv\""
00194                          << ";" << "0"
00195                          << ";" << "\"vvv\""
00196                          << ";" << "\"vvv\""
00197                          << ";" << "0"
00198                          << endl;
00199       }
00200     }
00201     
00202     
00203     
00204     void
00205     statistics() {
00206       long double final_with = 0;
00207       long double final_without = 0;
00208       int active = 0;
00209       
00210       for (int sid = 0; sid < 5; sid++) {
00211         list<rcv_data>& rcv_list = rcv_[sid];
00212         
00213         rcv_list.pop_front();
00214         rcv_list.pop_front();
00215         rcv_list.pop_front();
00216         
00217         if (rcv_list.size() <= 1) {
00218           cout << sid_ << " Nothing or not enough received from sid " << sid << endl;
00219           continue;
00220         }
00221         
00222         // cout << sid_ << " Processing data from sid " << sid << endl;
00223         
00224         size_t lost_packages = (1 + rcv_list.back().serial - rcv_list.front().serial) - rcv_list.size();
00225         size_t received_packages = rcv_list.size();
00226         // cout << sid_ << "   Received " << received_packages << " packages, lost " << lost_packages << " packages." << endl;
00227         
00228         long double acc_use_time = 0;
00229         long double acc_without_transmission = 0;
00230         long double acc_with_transmission = 0;
00231         
00232         list<rcv_data>::iterator last_i = rcv_list.begin();
00233         for (list<rcv_data>::iterator i = ++ rcv_list.begin();
00234              i != rcv_list.end();
00235              i++) {
00236           rcv_data& last_data = *last_i;
00237           rcv_data& curr_data = *i;
00238           
00239           if (curr_data.serial <= last_data.serial) {
00240             cout << sid_ << "   Detected duplicate or reorder: Package with serial " << last_data.serial << " received before package with serial " << curr_data.serial << "." << endl;
00241           }
00242           
00243           long double use_time = (curr_data.time - last_data.time).toSec();
00244           acc_use_time += use_time;
00245           
00246           // Without transmission times
00247           {
00248             long double age_at_reception = (last_data.send_time - last_data.production_time).toSec();
00249             long double age_at_end = age_at_reception + use_time;
00250             cout << age_at_reception << " " << age_at_end << " " << use_time << endl;
00251             acc_without_transmission += ( (age_at_reception + age_at_end) / 2) * use_time;
00252           }
00253           
00254           // With transmission times
00255           {
00256             long double age_at_reception = (last_data.time - last_data.production_time).toSec();
00257             long double age_at_end = age_at_reception + use_time;
00258             acc_with_transmission += ( (age_at_reception + age_at_end) / 2) * use_time;
00259           }
00260           
00261           last_i = i;
00262         }
00263         
00264         long double without_transmission = acc_without_transmission / acc_use_time;
00265         long double with_transmission = acc_with_transmission / acc_use_time;
00266         long double transmission_time = with_transmission - without_transmission;
00267         
00268         if (sid != sid_) {
00269           final_with += with_transmission;
00270           final_without += without_transmission;
00271           active++;
00272         }
00273         
00274         // cout << sid_ << "   Without considering transmission time, the average outdatedness of data was " << without_transmission << endl;
00275         // cout << sid_ << "   Considering synchronized clocks and transmission time, the average outdatedness of data was " << with_transmission << endl;
00276         // cout << sid_ << "   Mean transmission time: "<<transmission_time<<endl;
00277         
00278         cout << sid_
00279              << " From: " << sid
00280              << ", received: " << received_packages
00281              << ", lost: " << lost_packages
00282              << ", without: " << lexical_cast<string> (without_transmission)
00283              << ", with: " << lexical_cast<string> (with_transmission)
00284              << ", transmission_time: " << transmission_time << "." << endl;
00285       }
00286       
00287       final_with /= active;
00288       final_without /= active;
00289       
00290       cout << "Final results at " << sid_ << ": without: " << lexical_cast<string> (final_without) << ", with: " << lexical_cast<string> (final_with) << "." << endl;
00291     }
00292 };
00293 
00294 #endif


socrob_multicast
Author(s): Joao Reis/jreis@isr.ist.utl.pt
autogenerated on Mon Jan 6 2014 11:47:49