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


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