Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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) {
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
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
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
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
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
00275
00276
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