TestShortMultipleInLongDelay.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 TESTSHORTMULTIPLEINLONGDELAY_HPP
00021 #define TESTSHORTMULTIPLEINLONGDELAY_HPP
00022 
00023 #include <iostream>
00024 #include <fstream>
00025 #include <limits>
00026 
00027 #include <boost/thread/mutex.hpp>
00028 #include <boost/random.hpp>
00029 #include <boost/lexical_cast.hpp>
00030 #include <boost/foreach.hpp>
00031 #define foreach BOOST_FOREACH
00032 
00033 #include <ros/ros.h>
00034 
00035 #include <socrob/multicast.h>
00036 
00037 #include <std_msgs/UInt8.h>
00038 #include <std_msgs/UInt32.h>
00039 #include <std_msgs/Time.h>
00040 
00041 
00042 
00043 using namespace std;
00044 using namespace ros;
00045 using namespace socrob::multicast;
00046 using boost::lexical_cast;
00047 
00048 
00049 
00050 class TestShortMultipleInLongDelay
00051 {
00052     boost::mutex mutex_;
00053     
00054     int sid_;
00055     
00056     const uint8_t QUESTION_MAGIC_BYTE_;
00057     const uint8_t ANSWER_MAGIC_BYTE_;
00058     
00059     bool waiting_;
00060     unsigned round_number_;
00061     unsigned round_uid_;
00062     Time round_tx_;
00063     map<id_type, Time> round_answers_;
00064     
00065     bool answer_;
00066     unsigned answer_number_;
00067     unsigned answer_uid_;
00068     Time answer_time_;
00069     
00070     long double acc_max_arrival_delay_;
00071     long double acc_avg_arrival_delay_;
00072     long double acc_complete_delay_;
00073     unsigned long num_rounds_;
00074     
00075     boost::variate_generator<boost::mt19937, boost::uniform_int<unsigned> > random_uid_;
00076     
00077     Time output_time_base_;
00078     unsigned output_line_;
00079     ofstream output_;
00080     
00081   public:
00082     TestShortMultipleInLongDelay (int sid,
00083                                   string const& type) :
00084       sid_ (sid),
00085       QUESTION_MAGIC_BYTE_ (0),
00086       ANSWER_MAGIC_BYTE_ (1),
00087       waiting_ (false),
00088       round_number_ (0),
00089       round_uid_(),
00090       round_tx_ (Time::now()),
00091       answer_ (false),
00092       acc_max_arrival_delay_ (0),
00093       acc_avg_arrival_delay_ (0),
00094       acc_complete_delay_ (0),
00095       num_rounds_ (0),
00096       random_uid_ (boost::mt19937 (Time::now().toNSec()),
00097                    boost::uniform_int<unsigned> (numeric_limits<unsigned>::min(), numeric_limits<unsigned>::max())),
00098       output_time_base_ (Time::now()) {
00099       if (0 != sid_) {
00100         return;
00101       }
00102       
00103       waiting_ = true;
00104       round_number_++;
00105       round_uid_ = random_uid_();
00106       round_tx_ = Time::now();
00107       round_answers_.clear();
00108       
00109       output_.open ( ("/tmp/TestShortMultipleInLongDelay_" + type + "_" + lexical_cast<string> (output_time_base_.sec) + ".csv").c_str());
00110       output_ << "\"Round Number\""
00111               << ";\"Handler Delay 1\""
00112               << ";\"Handler Delay 2\""
00113               << ";\"Handler Delay 3\""
00114               << ";\"Handler Delay 4\""
00115               << ";\"Callback Delay\""
00116               << endl;
00117       output_line_ = 1;
00118     }
00119     
00120     
00121     
00122     ~TestShortMultipleInLongDelay() {
00123       unsigned l = output_line_;
00124       output_ << ";;;" << endl;
00125       output_ << "\"Average Handler Delay:\";=AVERAGE(B2:E" << l << ")" << endl;
00126       output_ << "\"Average Callback Delay:\";=AVERAGE(F2:F" << l << ")" << endl;
00127     }
00128     
00129     
00130     
00131     void
00132     timer () {
00133       if (0 != sid_) {
00134         return;
00135       }
00136       
00137       boost::lock_guard<boost::mutex> _ (mutex_);
00138       
00139       if (waiting_) {
00140         Duration age = Time::now() - round_tx_;
00141         if (age > Duration (1, 0)) {
00142           ROS_WARN_STREAM_THROTTLE (1, "Last round (" << round_number_ << ") was created " << age << " seconds ago, still waiting...");
00143         }
00144         return;
00145       }
00146     }
00147     
00148     
00149     
00150     void
00151     long_marshall (vector<uint8_t> & buffer) {
00152       boost::lock_guard<boost::mutex> _ (mutex_);
00153       
00154       if (answer_) {
00155         std_msgs::UInt8 magic_msg;
00156         magic_msg.data = ANSWER_MAGIC_BYTE_;
00157         serialize_append (buffer, magic_msg);
00158         
00159         std_msgs::UInt32 number_msg;
00160         number_msg.data = answer_number_;
00161         serialize_append (buffer, number_msg);
00162         
00163         std_msgs::UInt32 uid_msg;
00164         uid_msg.data = answer_uid_;
00165         serialize_append (buffer, uid_msg);
00166         
00167         std_msgs::UInt8 sid_msg;
00168         sid_msg.data = sid_;
00169         serialize_append (buffer, sid_msg);
00170         
00171         std_msgs::Time time_msg;
00172         time_msg.data = answer_time_;
00173         serialize_append (buffer, time_msg);
00174         
00175         answer_ = false;
00176         return;
00177       }
00178       
00179       if ( (0 == sid_)
00180            && (! waiting_)) {
00181         waiting_ = true;
00182         round_number_++;
00183         round_uid_ = random_uid_();
00184         round_tx_ = Time::now();
00185         round_answers_.clear();
00186         
00187         // To simulate worst case, not sending this time.
00188         return;
00189       }
00190       
00191       if (! waiting_) {
00192         return;
00193       }
00194       
00195       std_msgs::UInt8 magic_msg;
00196       magic_msg.data = QUESTION_MAGIC_BYTE_;
00197       serialize_append (buffer, magic_msg);
00198       
00199       std_msgs::UInt32 number_msg;
00200       number_msg.data = round_number_;
00201       serialize_append (buffer, number_msg);
00202       
00203       std_msgs::UInt32 uid_msg;
00204       uid_msg.data = round_uid_;
00205       serialize_append (buffer, uid_msg);
00206     }
00207     
00208     
00209     
00210     void
00211     long_unmarshall (socrob::multicast::id_type,
00212                      vector<uint8_t> & buffer) {
00213       size_t offset = 0;
00214       
00215       std_msgs::UInt8 magic_msg;
00216       offset += deserialize (magic_msg, buffer, offset);
00217       
00218       if (magic_msg.data == 0) {
00219         std_msgs::UInt32 number_msg;
00220         offset += deserialize (number_msg, buffer, offset);
00221         std_msgs::UInt32 uid_msg;
00222         offset += deserialize (uid_msg, buffer, offset);
00223         
00224         boost::lock_guard<boost::mutex> _ (mutex_);
00225         
00226         answer_ = true;
00227         answer_number_ = number_msg.data;
00228         answer_uid_ = uid_msg.data;
00229         answer_time_ = Time::now();
00230       }
00231       else if (magic_msg.data == 1) {
00232         if (0 != sid_) {
00233           return;
00234         }
00235         
00236         boost::lock_guard<boost::mutex> _ (mutex_);
00237         
00238         if (! waiting_) {
00239           ROS_WARN_STREAM ("Received package while short rounds not active");
00240           return;
00241         }
00242         
00243         std_msgs::UInt32 number_msg;
00244         offset += deserialize (number_msg, buffer, offset);
00245         std_msgs::UInt32 uid_msg;
00246         offset += deserialize (uid_msg, buffer, offset);
00247         std_msgs::UInt8 sid_msg;
00248         offset += deserialize (sid_msg, buffer, offset);
00249         std_msgs::Time arrival_time_msg;
00250         offset += deserialize (arrival_time_msg, buffer, offset);
00251         
00252         unsigned sent_number = number_msg.data;
00253         unsigned sent_uid = uid_msg.data;
00254         id_type sid = sid_msg.data;
00255         
00256         if (sid != 1 && sid != 2 && sid != 3 && sid != 4) {
00257           ROS_FATAL_STREAM ("Received answer from wrong agent while testing short rounds multiple.");
00258           abort();
00259         }
00260         if (sent_number != round_number_) {
00261           ROS_WARN ("Received answer wrong round number while testing short rounds single.");
00262           return;
00263         }
00264         if (sent_uid != round_uid_) {
00265           ROS_WARN ("Received answer with right number but wrong UID while testing short rounds single.");
00266           return;
00267         }
00268         
00269         if (0 == round_answers_.count (sid)) {
00270           round_answers_[sid] = arrival_time_msg.data;
00271         }
00272         
00273         if (round_answers_.size() == 4) {
00274           all_answers ();
00275           waiting_ = false;
00276         }
00277       }
00278       else {
00279         ROS_FATAL_STREAM ("Received package with wrong magic byte.");
00280         abort();
00281       }
00282     }
00283     
00284     
00285     
00286   private:
00287     void
00288     all_answers () {
00289       Time now = Time::now();
00290       
00291       long double avg_arrival_delay = 0;
00292       long double max_arrival_delay = 0;
00293       
00294       /*unsigned l =*/
00295       ++ (output_line_);
00296       output_ << round_number_;
00297       
00298       typedef map<id_type, Time>::value_type tmp_t;
00299       foreach (tmp_t const & answer_pair, round_answers_) {
00300         Time const& ans_arrival_time = answer_pair.second;
00301         
00302         Duration arrival_delay = ans_arrival_time - round_tx_;
00303         
00304         output_ << ";" << arrival_delay;
00305         
00306         long double arrival_delay_ld = (long double) arrival_delay.sec + 1e-9 * (long double) arrival_delay.nsec;
00307         avg_arrival_delay += arrival_delay_ld / 4;
00308         max_arrival_delay = max (max_arrival_delay, arrival_delay_ld);
00309       }
00310       
00311       Duration complete_delay = now - round_tx_;
00312       
00313       output_ << ";" << complete_delay << endl;
00314       
00315       ROS_INFO_STREAM ("Short round " << round_number_ << " to {1,2,3,4}: q. took " << avg_arrival_delay << " avg s and " << max_arrival_delay << " max s to arrive at dest, and " << complete_delay << " seconds from start to callback.");
00316       
00317       acc_avg_arrival_delay_ += avg_arrival_delay;
00318       acc_max_arrival_delay_ += max_arrival_delay;
00319       acc_complete_delay_ += (long double) complete_delay.sec + 1e-9 * (long double) complete_delay.nsec;
00320       num_rounds_++;
00321     }
00322     
00323     
00324     
00325   public:
00326     void
00327     statistics() {
00328       if (0 != sid_) {
00329         return;
00330       }
00331       
00332       acc_avg_arrival_delay_ /= num_rounds_;
00333       acc_max_arrival_delay_ /= num_rounds_;
00334       acc_complete_delay_ /= num_rounds_;
00335       
00336       cout << "Final results at " << sid_ << " for short multiple: handler avg delay: " << lexical_cast<string> (acc_avg_arrival_delay_) << ", handler avg of max delay: " << lexical_cast<string> (acc_max_arrival_delay_) << ", callback delay: " << lexical_cast<string> (acc_complete_delay_) << "." << endl;
00337     }
00338 };
00339 
00340 #endif


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