diff options
| author | guest <guest@cba7306a-a4a0-4afd-bcb4-bd19f8a24309> | 2007-11-30 13:41:25 +0000 |
|---|---|---|
| committer | guest <guest@cba7306a-a4a0-4afd-bcb4-bd19f8a24309> | 2007-11-30 13:41:25 +0000 |
| commit | eacbf5bb4d57af21c731f41251015d3b991ad490 (patch) | |
| tree | 477f43a79c75b400228a7c492f670a1c4886b5c3 /cdrom/tools/latencyTest/latenc.c | |
final version, initial import
git-svn-id: svn+ssh://mecka.net/home/svn/rtcorba-thesis@1 cba7306a-a4a0-4afd-bcb4-bd19f8a24309
Diffstat (limited to 'cdrom/tools/latencyTest/latenc.c')
| -rwxr-xr-x | cdrom/tools/latencyTest/latenc.c | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/cdrom/tools/latencyTest/latenc.c b/cdrom/tools/latencyTest/latenc.c new file mode 100755 index 0000000..77e3570 --- /dev/null +++ b/cdrom/tools/latencyTest/latenc.c @@ -0,0 +1,352 @@ +/** + * latenc.c + * -------------------------------- + * (c) Manuel Traut <mail@manut.de> + * 06/11/08 - version 0.98 + * -------------------------------- + * This program is free software; + * you can redistribute it and/or + * modify it under the terms of + * the GNU General Public License + * Version 2 as published by the + * Free Software Foundation. +**/ + +#include <fstream> +#include <stdlib.h> +#include <string> +#include <iostream> +#include <sstream> +#include <math.h> +#include <list> + +/** + * structure for latency-list + * -------------------------------- + * 1st latency + * 2nd counter + */ +struct latency_counter{ + float latency; + unsigned int counter; + latency_counter(float _latency){ + counter = 1; + latency = _latency; + } +} typedef lat_count; + +/** + * seperates values of one line + * convert time + * -------------------------------- + * 1st time + * 2nd reference signal + * 3rd delayed signal + * 4th another delayed signal +**/ + +void sep_values(std::string cpp_string, float* time, int* val1, int* val2, int* val3){ + + int posStart = 0; + int posEnd = cpp_string.find(",", posStart); + + std::string time_str = cpp_string.substr(posStart, posEnd); + int posOfExp = time_str.find("e", 0); + std::string expo = time_str; + std::string base = time_str.substr(0, posOfExp); + expo = expo.substr(posOfExp+1, expo.length()); + float fbase = atof(base.c_str()); + float fexpo = atof(expo.c_str()); + *time = fbase*pow(10.0,fexpo); + + posStart = posEnd+1; + posEnd = cpp_string.find(",", posStart)-1; + + *val1 = atoi(cpp_string.substr(posStart, posEnd).c_str()); + + posStart = posEnd+2; + posEnd = cpp_string.find(",", posStart)-1; + + if(posEnd > cpp_string.length()){ + + posEnd = cpp_string.length()-1; + + *val2 = atoi(cpp_string.substr(posStart, posEnd).c_str()); + *val3 = 0; + + } else { + + *val2 = atoi(cpp_string.substr(posStart, posEnd).c_str()); + + posStart = posEnd+2; + posEnd = cpp_string.find(",", posStart)-1; + + if(posEnd < cpp_string.length()) posEnd = cpp_string.length()-1; + *val3 = atoi(cpp_string.substr(posStart, posEnd).c_str()); + } +} + +/** + * adds a latencie to a latency- + * counter-list + * -------------------------------- + * 1st latency + * 2nd latencycounterlist + * ret counter state +**/ + +int add_latency(float latency, std::list<lat_count>* lat_list){ + + latency = latency*1000; + + std::cout.precision(20); + // latency already in list? + for(std::list<lat_count>::iterator it = lat_list->begin(); it != lat_list->end(); it++){ + if(it->latency == latency){ + it->counter++; + return it->counter; + } + } + // add latency + lat_count new_lat_count(latency); + lat_list->push_back(new_lat_count); + return new_lat_count.counter; +} + +/** + * calculates jitter of a latency- + * counter-list + * -------------------------------- + * 1st latencycounterlist + * ret jitter +**/ + +float calc_jitter(std::list<lat_count>* lat_list){ + + double avg = 0; + int sum = 0; + + for(std::list<lat_count>::iterator it = lat_list->begin(); it != lat_list->end(); it++){ + avg += it->counter * it->latency; + sum += it->counter; + } + avg = (double)(avg/sum); + std::cout<<"Mittelwert:\t"<<avg<<" sec"; + + double jitter = 0; + + for(std::list<lat_count>::iterator it = lat_list->begin(); it != lat_list->end(); it++){ + jitter += ((it->latency-avg)*it->counter); + } + jitter = (double)(jitter/sum); + + return (float)jitter; +} + +/** + * calculates modalvalues and ranges + * of a latency-counter-list + * -------------------------------- + * 1st latencycounterlist + * 2nd debug +**/ + +void calc_modal(std::list<lat_count>* lat_list, bool debug=false){ + + lat_count modal(0); + lat_count min(0); + min = *lat_list->begin(); + lat_count max(0); + max = *lat_list->begin(); + + for(std::list<lat_count>::iterator it = lat_list->begin(); it != lat_list->end(); it++){ + if(it->latency < min.latency){ // for difference min -> modal (best case) + min = *it; + } + if(it->latency > max.latency){ // for difference max -> modal (worst case) + max = *it; + } + if(it->counter>modal.counter){ // most occurences + modal = *it; + } else if (it->counter == modal.counter) { // if same occurence, lower value + if (it->latency < modal.latency){ + modal = *it; + } + } + } + std::cout<<"\nModalwert:\t"<<modal.latency<<" sec - Haeufigkeit: "<< modal.counter; + std::cout<<"\nSpannweite:\t"<<min.latency-modal.latency<<" sec (best case)\n\t\t "<<max.latency-modal.latency<<" sec (worst case)\n"; +} + +/** + * prints out latency-counter-list + * -------------------------------- + * 1st latencycounterlist + * 2nd debug +**/ + +void print_lat_count(std::list<lat_count>* lat_list, int* ch_counter, bool display=false){ + int i = 0; + std::stringstream ss; + ss<<*ch_counter; + std::string file = "result"+ss.str()+".txt"; + std::ofstream w(file.c_str()); + if(!w.is_open()){ + std::cerr<<"cannot write output file\n"; + } else { + w.precision(20); + for(std::list<lat_count>::iterator it = lat_list->begin(); it != lat_list->end(); it++){ + if(display) std::cout<<it->latency<<" "<<it->counter<<std::endl; + w<<it->latency<<" "<<it->counter<<std::endl; + i++; + } + if(i>0) *ch_counter = *ch_counter+1; + } +} + +/** + * main routine + * -------------------------------- + * 1st filename of the csv-file +**/ + +int main(int argc, char** argv){ + + if(argc < 2){ + std::cout<<"\nlatenc by Manuel Traut <mail@manut.de>\n\ndraws a graphical visualization and some statistical informations about latencies out of a Tektronix TDS 3034B generated csv file\n\nPhysical Configuration:\nCH1: reference signal\nCH2: delayed signal \nCH3: (optional) delayed signal\n\nOsciloscope Configuration:\n1) measure\n2) delay \n3) save \n4) all channels \n5) to FDD\n\nSYNOPSIS:\nlatenc <TEKxxxx.CSV> [debug]\n\n"; + return EXIT_FAILURE; + } + + bool debug = false; + + // open file + std::ifstream f(argv[1]); + if(!f.is_open()){ + std::cerr<<"file open failed\n"; + return EXIT_FAILURE; + } + + std::string d = "debug"; + if(argc > 2) if(d==(argv[2])){ + debug = true; + } + + // var decl + int* val1; // actual value reference signal + int* val2; // actual value 1st delayed signal + int* val3; // actual value 2nd delayed signal + int voltage1, voltage2, voltage3; // state of the signal (+/-) + float* time; // actual time (1st csv) + float refTimeDown, refTimeUp; // timestamp ref signal raised/falled + + bool firstFound = true; // to find a proper start + bool latStartUp = false; + bool latStartDown = false; + + std::string linenr; // one csv line + + int ch_counter = 0; + + std::list<lat_count>* latencies1st; + std::list<lat_count>* latencies2nd; + + val1 = new int; + val2 = new int; + val3 = new int; + time = new float; + + latencies1st = new std::list<lat_count>; + latencies2nd = new std::list<lat_count>; + + while(!f.eof()){ + + getline(f, linenr); + + if(!f.eof()){ + + sep_values(linenr, time, val1, val2, val3); + + if(firstFound){ // to find a proper start + + firstFound = false; + voltage1 = *val1; + + } else { + + if ( (voltage1 > 0) && (*val1 <= 0) ){ // if ref state changed + + refTimeDown = *time; + if(debug) std::cout<<*time<<": ref Down: "<<voltage1<<"->"<<*val1<<std::endl; + voltage1 = *val1; + latStartDown = true; + + } else if ( (voltage1 <= 0) && (*val1 > 0) ){ // if ref state changed + + refTimeUp = *time; + if(debug) std::cout<<*time<<": ref Up: "<<voltage1<<"->"<<*val1<<std::endl; + voltage1 = *val1; + latStartUp = true; + + } + + if ( (voltage2 > 0) && (*val2 <= 0) && latStartDown ){ // if delayed state changed + + float latency2 = *time - refTimeDown; // calc latency + voltage2 = *val2; // remember state + if(debug) std::cout<<*time<<": CH1 latency Down: "<<latency2<<std::endl; + if(latency2 != 0){ // may happen at begining of cvs + add_latency(latency2, latencies1st); + } + + } else if ( (voltage2 <= 0) && (*val2 > 0) && latStartUp ){ // see above! + + float latency2 = *time - refTimeUp; + voltage2 = *val2; + if(debug) std::cout<<*time<<": CH1 latency Up: "<<latency2<<std::endl; + if(latency2 != 0) add_latency(latency2, latencies1st); + + } + if ( (voltage3 > 0) && (*val3 <= 0) && latStartDown ){ // see above! + + float latency3 = *time - refTimeDown; + voltage3 = *val3; + if(debug) std::cout<<*time<<": CH2 latency Down: "<<latency3<<std::endl; + if(latency3 != 0) add_latency(latency3, latencies2nd); + + } else if ( (voltage3 <= 0) && (*val3 > 0) && latStartUp ){ // see above! + + float latency3 = *time - refTimeUp; + voltage3 = *val3; + if(debug) std::cout<<*time<<": CH2 latency Up: "<<latency3<<std::endl; + if(latency3 != 0) add_latency(latency3, latencies2nd); + + } + } + } + } + + delete val1; + delete val2; + delete val3; + delete time; + + f.close(); + + std::cout<<"\n\ndelayed 1st\n---------------\n\n"; + print_lat_count(latencies1st, &ch_counter, debug); + std::cout<<"\nJitter:\t\t"<<calc_jitter(latencies1st)<<" sec"; + calc_modal(latencies1st, debug); + + std::cout<<"\n\ndelayed 2nd\n---------------\n\n"; + print_lat_count(latencies2nd, &ch_counter, debug); + + if(ch_counter == 1){ + system("sh lat.sh"); + } else { + std::cout<<"\nJitter:\t\t"<<calc_jitter(latencies2nd)<<" sec"; + calc_modal(latencies2nd, debug); + system("sh lats.sh"); + } + + return EXIT_SUCCESS; +} |
