Files
openvins_linux/ov_eval/src/format_converter.cpp
2022-08-05 08:23:25 +03:00

162 lines
5.0 KiB
C++

/*
* OpenVINS: An Open Platform for Visual-Inertial Research
* Copyright (C) 2018-2022 Patrick Geneva
* Copyright (C) 2018-2022 Guoquan Huang
* Copyright (C) 2018-2022 OpenVINS Contributors
* Copyright (C) 2018-2019 Kevin Eckenhoff
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <Eigen/Eigen>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem.hpp>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include "utils/colors.h"
#include "utils/print.h"
/**
* Given a CSV file this will convert it to our text file format.
*/
void process_csv(std::string infile) {
// Verbosity setting
ov_core::Printer::setPrintLevel("INFO");
// Check if file paths are good
std::ifstream file1;
std::string line;
file1.open(infile);
PRINT_INFO("Opening file %s\n", boost::filesystem::path(infile).filename().c_str());
// Check that it was successful
if (!file1) {
PRINT_ERROR(RED "ERROR: Unable to open input file...\n" RESET);
PRINT_ERROR(RED "ERROR: %s\n" RESET, infile.c_str());
std::exit(EXIT_FAILURE);
}
// Loop through each line of this file
std::vector<Eigen::VectorXd> traj_data;
std::string current_line;
while (std::getline(file1, current_line)) {
// Skip if we start with a comment
if (!current_line.find("#"))
continue;
// Loop variables
int i = 0;
std::istringstream s(current_line);
std::string field;
Eigen::Matrix<double, 8, 1> data;
// Loop through this line (timestamp(ns) tx ty tz qw qx qy qz)
while (std::getline(s, field, ',')) {
// Skip if empty
if (field.empty() || i >= data.rows())
continue;
// save the data to our vector
data(i) = std::atof(field.c_str());
i++;
}
// Only a valid line if we have all the parameters
if (i > 7) {
traj_data.push_back(data);
// std::stringstream ss;
// ss << std::setprecision(5) << data.transpose() << std::endl;
// PRINT_DEBUG(ss.str().c_str());
}
}
// Finally close the file
file1.close();
// Error if we don't have any data
if (traj_data.empty()) {
PRINT_ERROR(RED "ERROR: Could not parse any data from the file!!\n" RESET);
PRINT_ERROR(RED "ERROR: %s\n" RESET, infile.c_str());
std::exit(EXIT_FAILURE);
}
PRINT_INFO("\t- Loaded %d poses from file\n", (int)traj_data.size());
// If file exists already then crash
std::string outfile = infile.substr(0, infile.find_last_of('.')) + ".txt";
if (boost::filesystem::exists(outfile)) {
PRINT_ERROR(RED "\t- ERROR: Output file already exists, please delete and re-run this script!!\n" RESET);
PRINT_ERROR(RED "\t- ERROR: %s\n" RESET, outfile.c_str());
return;
}
// Open this file we want to write to
std::ofstream file2;
file2.open(outfile.c_str());
if (file2.fail()) {
PRINT_ERROR(RED "ERROR: Unable to open output file!!\n" RESET);
PRINT_ERROR(RED "ERROR: %s\n" RESET, outfile.c_str());
std::exit(EXIT_FAILURE);
}
file2 << "# timestamp(s) tx ty tz qx qy qz qw" << std::endl;
// Write to disk in the correct order!
for (size_t i = 0; i < traj_data.size(); i++) {
file2.precision(5);
file2.setf(std::ios::fixed, std::ios::floatfield);
file2 << 1e-9 * traj_data.at(i)(0) << " ";
file2.precision(6);
file2 << traj_data.at(i)(1) << " " << traj_data.at(i)(2) << " " << traj_data.at(i)(3) << " " << traj_data.at(i)(5) << " "
<< traj_data.at(i)(6) << " " << traj_data.at(i)(7) << " " << traj_data.at(i)(4) << std::endl;
}
PRINT_INFO("\t- Saved to file %s\n", boost::filesystem::path(outfile).filename().c_str());
// Finally close the file
file2.close();
}
int main(int argc, char **argv) {
// Ensure we have a path
if (argc < 2) {
PRINT_ERROR(RED "ERROR: Please specify a file to convert\n" RESET);
PRINT_ERROR(RED "ERROR: ./format_convert <file.csv or folder\n" RESET);
PRINT_ERROR(RED "ERROR: rosrun ov_eval format_convert <file.csv or folder>\n" RESET);
std::exit(EXIT_FAILURE);
}
// If we do not have a wildcard, then process this one csv
if (boost::algorithm::ends_with(argv[1], "csv")) {
// Process this single file
process_csv(argv[1]);
} else {
// Loop through this directory
boost::filesystem::path infolder(argv[1]);
for (auto &p : boost::filesystem::recursive_directory_iterator(infolder)) {
if (p.path().extension() == ".csv") {
process_csv(p.path().string());
}
}
}
// Done!
return EXIT_SUCCESS;
}