Loader.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 "Loader.h"
23 
24 using namespace ov_eval;
25 
26 void Loader::load_data(std::string path_traj, std::vector<double> &times, std::vector<Eigen::Matrix<double, 7, 1>> &poses,
27  std::vector<Eigen::Matrix3d> &cov_ori, std::vector<Eigen::Matrix3d> &cov_pos) {
28 
29  // Try to open our trajectory file
30  std::ifstream file(path_traj);
31  if (!file.is_open()) {
32  PRINT_ERROR(RED "[LOAD]: Unable to open trajectory file...\n" RESET);
33  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path_traj.c_str());
34  std::exit(EXIT_FAILURE);
35  }
36 
37  // Loop through each line of this file
38  std::string current_line;
39  while (std::getline(file, current_line)) {
40 
41  // Skip if we start with a comment
42  if (!current_line.find("#"))
43  continue;
44 
45  // Loop variables
46  int i = 0;
47  std::istringstream s(current_line);
48  std::string field;
49  Eigen::Matrix<double, 20, 1> data;
50 
51  // Loop through this line (timestamp(s) tx ty tz qx qy qz qw Pr11 Pr12 Pr13 Pr22 Pr23 Pr33 Pt11 Pt12 Pt13 Pt22 Pt23 Pt33)
52  while (std::getline(s, field, ' ')) {
53  // Skip if empty
54  if (field.empty() || i >= data.rows())
55  continue;
56  // save the data to our vector
57  data(i) = std::atof(field.c_str());
58  i++;
59  }
60 
61  // Only a valid line if we have all the parameters
62  if (i >= 20) {
63  // time and pose
64  times.push_back(data(0));
65  poses.push_back(data.block(1, 0, 7, 1));
66  // covariance values
67  Eigen::Matrix3d c_ori, c_pos;
68  c_ori << data(8), data(9), data(10), data(9), data(11), data(12), data(10), data(12), data(13);
69  c_pos << data(14), data(15), data(16), data(15), data(17), data(18), data(16), data(18), data(19);
70  c_ori = 0.5 * (c_ori + c_ori.transpose());
71  c_pos = 0.5 * (c_pos + c_pos.transpose());
72  cov_ori.push_back(c_ori);
73  cov_pos.push_back(c_pos);
74  } else if (i >= 8) {
75  times.push_back(data(0));
76  poses.push_back(data.block(1, 0, 7, 1));
77  }
78  }
79 
80  // Finally close the file
81  file.close();
82 
83  // Error if we don't have any data
84  if (times.empty()) {
85  PRINT_ERROR(RED "[LOAD]: Could not parse any data from the file!!\n" RESET);
86  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path_traj.c_str());
87  std::exit(EXIT_FAILURE);
88  }
89 
90  // Assert that they are all equal
91  if (times.size() != poses.size()) {
92  PRINT_ERROR(RED "[LOAD]: Parsing error, pose and timestamps do not match!!\n" RESET);
93  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path_traj.c_str());
94  std::exit(EXIT_FAILURE);
95  }
96 
97  // Assert that they are all equal
98  if (!cov_ori.empty() && (times.size() != cov_ori.size() || times.size() != cov_pos.size())) {
99  PRINT_ERROR(RED "[LOAD]: Parsing error, timestamps covariance size do not match!!\n" RESET);
100  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path_traj.c_str());
101  std::exit(EXIT_FAILURE);
102  }
103 
104  // Debug print amount
105  // std::string base_filename = path_traj.substr(path_traj.find_last_of("/\\") + 1);
106  // PRINT_DEBUG("[LOAD]: loaded %d poses from %s\n",(int)poses.size(),base_filename.c_str());
107 }
108 
109 void Loader::load_data_csv(std::string path_traj, std::vector<double> &times, std::vector<Eigen::Matrix<double, 7, 1>> &poses,
110  std::vector<Eigen::Matrix3d> &cov_ori, std::vector<Eigen::Matrix3d> &cov_pos) {
111 
112  // Try to open our trajectory file
113  std::ifstream file(path_traj);
114  if (!file.is_open()) {
115  PRINT_ERROR(RED "[LOAD]: Unable to open trajectory file...\n" RESET);
116  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path_traj.c_str());
117  std::exit(EXIT_FAILURE);
118  }
119 
120  // Loop through each line of this file
121  std::string current_line;
122  while (std::getline(file, current_line)) {
123 
124  // Skip if we start with a comment
125  if (!current_line.find("#"))
126  continue;
127 
128  // Loop variables
129  int i = 0;
130  std::istringstream s(current_line);
131  std::string field;
132  Eigen::Matrix<double, 20, 1> data;
133 
134  // Loop through this line (groundtruth state [time(sec),q_GtoI,p_IinG,v_IinG,b_gyro,b_accel])
135  while (std::getline(s, field, ',')) {
136  // Skip if empty
137  if (field.empty() || i >= data.rows())
138  continue;
139  // save the data to our vector
140  data(i) = std::atof(field.c_str());
141  i++;
142  }
143 
144  // Only a valid line if we have all the parameters
145  // Times are in nanoseconds -> convert to seconds
146  // Our "fixed" state vector from the ETH GT format [q,p,v,bg,ba]
147  if (i >= 8) {
148  times.push_back(1e-9 * data(0));
149  Eigen::Matrix<double, 7, 1> imustate;
150  imustate(0, 0) = data(1, 0); // pos
151  imustate(1, 0) = data(2, 0);
152  imustate(2, 0) = data(3, 0);
153  imustate(3, 0) = data(5, 0); // quat (xyzw)
154  imustate(4, 0) = data(6, 0);
155  imustate(5, 0) = data(7, 0);
156  imustate(6, 0) = data(4, 0);
157  poses.push_back(imustate);
158  }
159  }
160 
161  // Finally close the file
162  file.close();
163 
164  // Error if we don't have any data
165  if (times.empty()) {
166  PRINT_ERROR(RED "[LOAD]: Could not parse any data from the file!!\n" RESET);
167  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path_traj.c_str());
168  std::exit(EXIT_FAILURE);
169  }
170 
171  // Assert that they are all equal
172  if (times.size() != poses.size()) {
173  PRINT_ERROR(RED "[LOAD]: Parsing error, pose and timestamps do not match!!\n" RESET);
174  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path_traj.c_str());
175  std::exit(EXIT_FAILURE);
176  }
177 }
178 
179 void Loader::load_simulation(std::string path, std::vector<Eigen::VectorXd> &values) {
180 
181  // Try to open our trajectory file
182  std::ifstream file(path);
183  if (!file.is_open()) {
184  PRINT_ERROR(RED "[LOAD]: Unable to open file...\n" RESET);
185  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path.c_str());
186  std::exit(EXIT_FAILURE);
187  }
188 
189  // Loop through each line of this file
190  std::string current_line;
191  while (std::getline(file, current_line)) {
192 
193  // Skip if we start with a comment
194  if (!current_line.find("#"))
195  continue;
196 
197  // Loop variables
198  std::istringstream s(current_line);
199  std::string field;
200  std::vector<double> vec;
201 
202  // Loop through this line (timestamp(s) values....)
203  while (std::getline(s, field, ' ')) {
204  // Skip if empty
205  if (field.empty())
206  continue;
207  // save the data to our vector
208  vec.push_back(std::atof(field.c_str()));
209  }
210 
211  // Create eigen vector
212  Eigen::VectorXd temp(vec.size());
213  for (size_t i = 0; i < vec.size(); i++) {
214  temp(i) = vec.at(i);
215  }
216  values.push_back(temp);
217  }
218 
219  // Finally close the file
220  file.close();
221 
222  // Error if we don't have any data
223  if (values.empty()) {
224  PRINT_ERROR(RED "[LOAD]: Could not parse any data from the file!!\n" RESET);
225  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path.c_str());
226  std::exit(EXIT_FAILURE);
227  }
228 
229  // Assert that all rows in this file are of the same length
230  int rowsize = values.at(0).rows();
231  for (size_t i = 0; i < values.size(); i++) {
232  if (values.at(i).rows() != rowsize) {
233  PRINT_ERROR(RED "[LOAD]: Invalid row size on line %d (of size %d instead of %d)\n" RESET, (int)i, (int)values.at(i).rows(), rowsize);
234  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path.c_str());
235  std::exit(EXIT_FAILURE);
236  }
237  }
238 }
239 
240 void Loader::load_timing_flamegraph(std::string path, std::vector<std::string> &names, std::vector<double> &times,
241  std::vector<Eigen::VectorXd> &timing_values) {
242 
243  // Try to open our trajectory file
244  std::ifstream file(path);
245  if (!file.is_open()) {
246  PRINT_ERROR(RED "[LOAD]: Unable to open file...\n" RESET);
247  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path.c_str());
248  std::exit(EXIT_FAILURE);
249  }
250 
251  // Loop through each line of this file
252  std::string current_line;
253  while (std::getline(file, current_line)) {
254 
255  // We should have a commented line of the names of the categories
256  // Here we will process them (skip the first since it is just the timestamps)
257  if (!current_line.find("#")) {
258  // Loop variables
259  std::istringstream s(current_line);
260  std::string field;
261  names.clear();
262  // Loop through this line
263  bool skipped_first = false;
264  while (std::getline(s, field, ',')) {
265  // Skip if empty
266  if (field.empty())
267  continue;
268  // Skip the first ever one
269  if (skipped_first)
270  names.push_back(field);
271  skipped_first = true;
272  }
273  continue;
274  }
275 
276  // Loop variables
277  std::istringstream s(current_line);
278  std::string field;
279  std::vector<double> vec;
280 
281  // Loop through this line (timestamp(s) values....)
282  while (std::getline(s, field, ',')) {
283  // Skip if empty
284  if (field.empty())
285  continue;
286  // save the data to our vector
287  vec.push_back(std::atof(field.c_str()));
288  }
289 
290  // Create eigen vector
291  Eigen::VectorXd temp(vec.size() - 1);
292  for (size_t i = 1; i < vec.size(); i++) {
293  temp(i - 1) = vec.at(i);
294  }
295  times.push_back(vec.at(0));
296  timing_values.push_back(temp);
297  }
298 
299  // Finally close the file
300  file.close();
301 
302  // Error if we don't have any data
303  if (timing_values.empty()) {
304  PRINT_ERROR(RED "[LOAD]: Could not parse any data from the file!!\n" RESET);
305  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path.c_str());
306  std::exit(EXIT_FAILURE);
307  }
308 
309  // Assert that all rows in this file are of the same length
310  int rowsize = names.size();
311  for (size_t i = 0; i < timing_values.size(); i++) {
312  if (timing_values.at(i).rows() != rowsize) {
313  PRINT_ERROR(RED "[LOAD]: Invalid row size on line %d (of size %d instead of %d)\n" RESET, (int)i, (int)timing_values.at(i).rows(),
314  rowsize);
315  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path.c_str());
316  std::exit(EXIT_FAILURE);
317  }
318  }
319 }
320 
321 void Loader::load_timing_percent(std::string path, std::vector<double> &times, std::vector<Eigen::Vector3d> &summed_values,
322  std::vector<Eigen::VectorXd> &node_values) {
323 
324  // Try to open our trajectory file
325  std::ifstream file(path);
326  if (!file.is_open()) {
327  PRINT_ERROR(RED "[LOAD]: Unable to open timing file...\n" RESET);
328  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path.c_str());
329  std::exit(EXIT_FAILURE);
330  }
331 
332  // Loop through each line of this file
333  std::string current_line;
334  while (std::getline(file, current_line)) {
335 
336  // Skip if we start with a comment
337  if (!current_line.find("#"))
338  continue;
339 
340  // Loop variables
341  std::istringstream s(current_line);
342  std::string field;
343  std::vector<double> vec;
344 
345  // Loop through this line (timestamp(s) values....)
346  while (std::getline(s, field, ' ')) {
347  // Skip if empty
348  if (field.empty())
349  continue;
350  // save the data to our vector
351  vec.push_back(std::atof(field.c_str()));
352  }
353 
354  // Create eigen vector
355  Eigen::VectorXd temp(vec.size());
356  for (size_t i = 0; i < vec.size(); i++) {
357  temp(i) = vec.at(i);
358  }
359 
360  // Skip if there where no threads
361  if (temp(3) == 0.0)
362  continue;
363 
364  // Save the summed value
365  times.push_back(temp(0));
366  summed_values.push_back(temp.block(1, 0, 3, 1));
367  node_values.push_back(temp.block(4, 0, temp.rows() - 4, 1));
368  }
369 
370  // Finally close the file
371  file.close();
372 
373  // Error if we don't have any data
374  if (times.empty()) {
375  PRINT_ERROR(RED "[LOAD]: Could not parse any data from the file!!\n" RESET);
376  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path.c_str());
377  std::exit(EXIT_FAILURE);
378  }
379 
380  // Assert that they are all equal
381  if (times.size() != summed_values.size() || times.size() != node_values.size()) {
382  PRINT_ERROR(RED "[LOAD]: Parsing error, pose and timestamps do not match!!\n" RESET);
383  PRINT_ERROR(RED "[LOAD]: %s\n" RESET, path.c_str());
384  std::exit(EXIT_FAILURE);
385  }
386 }
387 
388 double Loader::get_total_length(const std::vector<Eigen::Matrix<double, 7, 1>> &poses) {
389 
390  // Loop through every pose and append its segment
391  double distance = 0.0;
392  for (size_t i = 1; i < poses.size(); i++) {
393  distance += (poses[i].block(0, 0, 3, 1) - poses[i - 1].block(0, 0, 3, 1)).norm();
394  }
395 
396  // return the distance
397  return distance;
398 }
static void load_data(std::string path_traj, std::vector< double > &times, std::vector< Eigen::Matrix< double, 7, 1 >> &poses, std::vector< Eigen::Matrix3d > &cov_ori, std::vector< Eigen::Matrix3d > &cov_pos)
This will load space separated trajectory into memory.
Definition: Loader.cpp:26
#define RESET
RED
XmlRpcServer s
static double get_total_length(const std::vector< Eigen::Matrix< double, 7, 1 >> &poses)
Will calculate the total trajectory distance.
Definition: Loader.cpp:388
Evaluation and recording utilities.
static void load_data_csv(std::string path_traj, std::vector< double > &times, std::vector< Eigen::Matrix< double, 7, 1 >> &poses, std::vector< Eigen::Matrix3d > &cov_ori, std::vector< Eigen::Matrix3d > &cov_pos)
This will load comma separated trajectory into memory (ASL/ETH format)
Definition: Loader.cpp:109
static void load_timing_percent(std::string path, std::vector< double > &times, std::vector< Eigen::Vector3d > &summed_values, std::vector< Eigen::VectorXd > &node_values)
Load space separated timing file from pid_ros.py file.
Definition: Loader.cpp:321
static void load_simulation(std::string path, std::vector< Eigen::VectorXd > &values)
Load an arbitrary sized row of space separated values, used for our simulation.
Definition: Loader.cpp:179
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