timing_comparison.cpp
Go to the documentation of this file.
1 /*
2  * OpenVINS: An Open Platform for Visual-Inertial Research
3  * Copyright (C) 2018-2023 Patrick Geneva
4  * Copyright (C) 2018-2023 Guoquan Huang
5  * Copyright (C) 2018-2023 OpenVINS Contributors
6  * Copyright (C) 2018-2019 Kevin Eckenhoff
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <Eigen/Eigen>
23 #include <boost/algorithm/string/predicate.hpp>
24 #include <boost/filesystem.hpp>
25 #include <boost/foreach.hpp>
26 #include <fstream>
27 #include <iostream>
28 #include <string>
29 
30 #include "utils/Loader.h"
31 #include "utils/Statistics.h"
32 #include "utils/colors.h"
33 #include "utils/print.h"
34 
35 #ifdef HAVE_PYTHONLIBS
36 
37 // import the c++ wrapper for matplot lib
38 // https://github.com/lava/matplotlib-cpp
39 // sudo apt-get install python-matplotlib python-numpy python2.7-dev
40 #include "plot/matplotlibcpp.h"
41 
42 #endif
43 
44 int main(int argc, char **argv) {
45 
46  // Verbosity setting
48 
49  // Ensure we have a path
50  if (argc < 2) {
51  PRINT_ERROR(RED "ERROR: Please specify a timing file\n" RESET);
52  PRINT_ERROR(RED "ERROR: ./timing_comparison <file_times1.txt> ... <file_timesN.txt>\n" RESET);
53  PRINT_ERROR(RED "ERROR: rosrun ov_eval timing_comparison <file_times1.txt> ... <file_timesN.txt>\n" RESET);
54  std::exit(EXIT_FAILURE);
55  }
56 
57  // Read in all our trajectories from file
58  std::vector<std::string> names;
59  std::vector<ov_eval::Statistics> total_times;
60  PRINT_INFO("======================================\n");
61  for (int z = 1; z < argc; z++) {
62 
63  // Parse the name of this timing
64  boost::filesystem::path path(argv[z]);
65  std::string name = path.stem().string();
66  PRINT_INFO("[TIME]: loading data for %s\n", name.c_str());
67 
68  // Load it!!
69  std::vector<std::string> names_temp;
70  std::vector<double> times;
71  std::vector<Eigen::VectorXd> timing_values;
72  ov_eval::Loader::load_timing_flamegraph(argv[z], names_temp, times, timing_values);
73  PRINT_DEBUG("[TIME]: loaded %d timestamps from file (%d categories)!!\n", (int)times.size(), (int)names_temp.size());
74 
75  // Our categories
76  std::vector<ov_eval::Statistics> stats;
77  for (size_t i = 0; i < names_temp.size(); i++)
78  stats.push_back(ov_eval::Statistics());
79 
80  // Loop through each and report the average timing information
81  for (size_t i = 0; i < times.size(); i++) {
82  for (size_t c = 0; c < names_temp.size(); c++) {
83  stats.at(c).timestamps.push_back(times.at(i));
84  stats.at(c).values.push_back(timing_values.at(i)(c));
85  }
86  }
87 
88  // Now print the statistic for this run
89  for (size_t i = 0; i < names_temp.size(); i++) {
90  stats.at(i).calculate();
91  PRINT_INFO("mean_time = %.4f | std = %.4f | 99th = %.4f | max = %.4f (%s)\n", stats.at(i).mean, stats.at(i).std,
92  stats.at(i).ninetynine, stats.at(i).max, names_temp.at(i).c_str());
93  }
94 
95  // Append the total stats to the big vector
96  if (!stats.empty()) {
97  names.push_back(name);
98  total_times.push_back(stats.at(stats.size() - 1));
99  } else {
100  PRINT_ERROR(RED "[TIME]: unable to load any data.....\n" RESET);
101  }
102  PRINT_INFO("======================================\n");
103  }
104 
105 #ifdef HAVE_PYTHONLIBS
106 
107  // Valid colors
108  // https://matplotlib.org/stable/tutorials/colors/colors.html
109  // std::vector<std::string> colors = {"blue","aqua","lightblue","lightgreen","yellowgreen","green"};
110  // std::vector<std::string> colors = {"navy","blue","lightgreen","green","gold","goldenrod"};
111  std::vector<std::string> colors = {"black", "blue", "red", "green", "cyan", "magenta"};
112 
113  // Plot this figure
114  matplotlibcpp::figure_size(1200, 400);
115 
116  // Zero our time arrays
117  double starttime = (total_times.at(0).timestamps.empty()) ? 0 : total_times.at(0).timestamps.at(0);
118  double endtime = (total_times.at(0).timestamps.empty()) ? 0 : total_times.at(0).timestamps.at(total_times.at(0).timestamps.size() - 1);
119  for (size_t i = 0; i < total_times.size(); i++) {
120  for (size_t j = 0; j < total_times.at(i).timestamps.size(); j++) {
121  total_times.at(i).timestamps.at(j) -= starttime;
122  }
123  }
124 
125  // Now loop through each and plot it!
126  for (size_t n = 0; n < names.size(); n++) {
127 
128  // Sub-sample the time and values
129  int keep_every = 10;
130  std::vector<double> times_skipped;
131  for (size_t t = 0; t < total_times.at(n).timestamps.size(); t++) {
132  if (t % keep_every == 0) {
133  times_skipped.push_back(total_times.at(n).timestamps.at(t));
134  }
135  }
136  std::vector<double> values_skipped;
137  for (size_t t = 0; t < total_times.at(n).values.size(); t++) {
138  if (t % keep_every == 0) {
139  values_skipped.push_back(total_times.at(n).values.at(t));
140  }
141  }
142 
143  // Paramters for our line
144  std::map<std::string, std::string> params;
145  params.insert({"label", names.at(n)});
146  params.insert({"linestyle", "-"});
147  params.insert({"color", colors.at(n % colors.size())});
148 
149  // Finally plot
150  matplotlibcpp::plot(times_skipped, values_skipped, params);
151  }
152 
153  // Finally add labels and show it
154  matplotlibcpp::ylabel("execution time (s)");
155  matplotlibcpp::xlim(0.0, endtime - starttime);
156  matplotlibcpp::xlabel("dataset time (s)");
159 
160  // Display to the user
161  matplotlibcpp::show(true);
162 
163 #endif
164 
165  // Done!
166  return EXIT_SUCCESS;
167 }
Statistics object for a given set scalar time series values.
Definition: Statistics.h:39
#define RESET
RED
void figure_size(size_t w, size_t h)
bool plot(const std::vector< Numeric > &x, const std::vector< Numeric > &y, const std::map< std::string, std::string > &keywords)
void show(const bool block=true)
int main(int argc, char **argv)
static void setPrintLevel(const std::string &level)
void xlim(Numeric left, Numeric right)
void xlabel(const std::string &str, const std::map< std::string, std::string > &keywords={})
void ylabel(const std::string &str, const std::map< std::string, std::string > &keywords={})
void tight_layout()
static void load_timing_flamegraph(std::string path, std::vector< std::string > &names, std::vector< double > &times, std::vector< Eigen::VectorXd > &timing_values)
Load comma separated timing file from pid_ros.py file.
Definition: Loader.cpp:240


ov_eval
Author(s): Patrick Geneva , Kevin Eckenhoff , Guoquan Huang
autogenerated on Wed Jun 21 2023 03:05:40