00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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
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