add CSV metrics object

This commit is contained in:
Andre Puschmann 2017-09-23 22:24:37 +02:00
parent 124bd0a2ba
commit 6eb6468ba9
5 changed files with 217 additions and 3 deletions

64
srsue/hdr/metrics_csv.h Normal file
View File

@ -0,0 +1,64 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of the srsUE library.
*
* srsUE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsUE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
/******************************************************************************
* File: metrics_csv.h
* Description: Metrics class writing to CSV file.
*****************************************************************************/
#ifndef METRICS_CSV_H
#define METRICS_CSV_H
#include <pthread.h>
#include <stdint.h>
#include <string>
#include <iostream>
#include <fstream>
#include "srslte/common/metrics_hub.h"
#include "ue_metrics_interface.h"
namespace srsue {
class metrics_csv : public srslte::metrics_listener<ue_metrics_t>
{
public:
metrics_csv(std::string filename);
void set_metrics(ue_metrics_t &m, float report_period_secs);
void set_ue_handle(ue_metrics_interface *ue_);
private:
std::string float_to_string(float f, int digits, bool add_semicolon = true);
std::ofstream file;
ue_metrics_interface* ue;
uint32_t n_reports;
};
} // namespace srsue
#endif // METRICS_CSV_H

View File

@ -31,7 +31,7 @@ if (RPATH)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
endif (RPATH)
add_executable(srsue main.cc ue_base.cc ue.cc metrics_stdout.cc)
add_executable(srsue main.cc ue_base.cc ue.cc metrics_stdout.cc metrics_csv.cc)
target_link_libraries(srsue srsue_mac
srsue_phy
srsue_upper

109
srsue/src/metrics_csv.cc Normal file
View File

@ -0,0 +1,109 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2015 The srsUE Developers. See the
* COPYRIGHT file at the top-level directory of this distribution.
*
* \section LICENSE
*
* This file is part of the srsUE library.
*
* srsUE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsUE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include "metrics_csv.h"
#include <unistd.h>
#include <sstream>
#include <stdlib.h>
#include <math.h>
#include <float.h>
#include <iomanip>
#include <iostream>
#include <stdio.h>
using namespace std;
namespace srsue{
metrics_csv::metrics_csv(std::string filename)
:n_reports(0)
,ue(NULL)
{
file.open(filename.c_str());
}
void metrics_csv::set_ue_handle(ue_metrics_interface *ue_)
{
ue = ue_;
}
void metrics_csv::set_metrics(ue_metrics_t &metrics, float metrics_report_period)
{
if (file.is_open()) {
if (!ue->is_attached()) {
file << "# disconnected" << endl;
return;
}
if(n_reports == 0) {
file << "time;rsrp;pl;cfo;dl_mcs;dl_snr;dl_turbo;dl_brate;dl_bler;ul_mcs;ul_buff;ul_brate;ul_bler;rf_o;rf_u;rf_l" << endl;
}
file << (metrics_report_period*n_reports) << ";";
file << float_to_string(metrics.phy.dl.rsrp, 2);
file << float_to_string(metrics.phy.dl.pathloss, 2);
file << float_to_string(metrics.phy.sync.cfo, 2);
file << float_to_string(metrics.phy.dl.mcs, 2);
file << float_to_string(metrics.phy.dl.sinr, 2);
file << float_to_string(metrics.phy.dl.turbo_iters, 2);
file << float_to_string((float) metrics.mac.rx_brate/metrics_report_period, 2);
if (metrics.mac.rx_pkts > 0) {
file << float_to_string((float) 100*metrics.mac.rx_errors/metrics.mac.rx_pkts, 1);
} else {
file << float_to_string(0, 2);
}
file << float_to_string(metrics.phy.ul.mcs, 2);
file << float_to_string((float) metrics.mac.ul_buffer, 2);
file << float_to_string((float) metrics.mac.tx_brate/metrics_report_period, 2);
if (metrics.mac.tx_pkts > 0) {
file << float_to_string((float) 100*metrics.mac.tx_errors/metrics.mac.tx_pkts, 1);
} else {
file << float_to_string(0, 2);
}
file << float_to_string(metrics.rf.rf_o, 2);
file << float_to_string(metrics.rf.rf_u, 2);
file << float_to_string(metrics.rf.rf_l, 2, false);
file << endl;
n_reports++;
} else {
std::cout << "Error, couldn't write CSV file." << std::endl;
}
}
std::string metrics_csv::float_to_string(float f, int digits, bool add_semicolon)
{
std::ostringstream os;
const int precision = (f == 0.0) ? digits-1 : digits - log10(fabs(f))-2*DBL_EPSILON;
os << std::fixed << std::setprecision(precision) << f;
if (add_semicolon)
os << ';';
return os.str();
}
} // namespace srsue

View File

@ -22,6 +22,6 @@ add_subdirectory(phy)
add_subdirectory(mac)
add_subdirectory(upper)
add_executable(metrics_test metrics_test.cc ../src/metrics_stdout.cc)
add_executable(metrics_test metrics_test.cc ../src/metrics_stdout.cc ../src/metrics_csv.cc)
target_link_libraries(metrics_test srslte_phy srslte_common)
add_test(metrics_test metrics_test)
add_test(metrics_test metrics_test -o ${CMAKE_CURRENT_BINARY_DIR}/ue_metrics.csv)

View File

@ -25,16 +25,21 @@
*/
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include "ue_metrics_interface.h"
#include "srslte/common/metrics_hub.h"
#include "metrics_stdout.h"
#include "metrics_csv.h"
using namespace srsue;
namespace srsue {
char *csv_file_name = NULL;
// fake classes
class ue_dummy : public ue_metrics_interface
{
@ -56,19 +61,55 @@ public:
};
}
void usage(char *prog) {
printf("Usage: %s -o csv_output_file\n", prog);
}
void parse_args(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "o")) != -1) {
switch(opt) {
case 'o':
csv_file_name = argv[optind];
break;
default:
usage(argv[0]);
exit(-1);
}
}
if (!csv_file_name) {
usage(argv[0]);
exit(-1);
}
}
int main(int argc, char **argv)
{
float period = 1.0;
ue_dummy ue;
if (argc < 3) {
usage(argv[0]);
exit(-1);
}
parse_args(argc,argv);
// the default metrics type for stdout output
metrics_stdout metrics_screen;
metrics_screen.set_ue_handle(&ue);
// the CSV file writer
metrics_csv metrics_file(csv_file_name);
metrics_file.set_ue_handle(&ue);
// create metrics hub and register metrics for stdout
srslte::metrics_hub<ue_metrics_t> metricshub;
metricshub.init(&ue, period);
metricshub.add_listener(&metrics_screen);
metricshub.add_listener(&metrics_file);
// enable printing
metrics_screen.toggle_print(true);