My Project 1.0
Holistic Fusion: A Generic Framework for Multimodal Sensor Fusion
Loading...
Searching...
No Matches
FileLogger.cpp
Go to the documentation of this file.
1/*
2Copyright 2024 by Julian Nubert, Robotic Systems Lab, ETH Zurich.
3All rights reserved.
4This file is released under the "BSD-3-Clause License".
5Please see the LICENSE file that has been included as part of this package.
6 */
7
8// Implementation
10
11// C++
12#include <gtsam/inference/Symbol.h>
13
14// Output
16#define REGULAR_COUT std::cout << YELLOW_START << "GMSF-TransformExpressionKeys" << COLOR_END
17
18namespace holistic_fusion {
19
20// Create File Streams
21// 1. CSV
22// Pose3
23void FileLogger::createPose3CsvFileStream(std::map<std::string, std::ofstream>& fileStreams, const std::string& savePath,
24 const std::string& transformIdentifier, const std::string& timeString,
25 const bool saveCovarianceFlag) {
26 if (fileStreams.find(transformIdentifier) == fileStreams.end()) {
27 // If not, create a new file stream for this category
28 const std::string stateFileName = savePath + timeString + "/" + transformIdentifier + ".csv";
29 REGULAR_COUT << GREEN_START << " Saving 6D pose states to CSV-file: " << COLOR_END << stateFileName << std::endl;
30
31 // Open for writing and appending
32 fileStreams[transformIdentifier].open(stateFileName, std::ofstream::out | std::ofstream::app);
33 // Write header
34 fileStreams[transformIdentifier] << "time, x, y, z, quat_x, quat_y, quat_z, quat_w, roll, pitch, yaw\n";
35
36 if (saveCovarianceFlag) {
37 const std::string covarianceFileName = savePath + timeString + "/" + transformIdentifier + "_covariance.csv";
38 REGULAR_COUT << GREEN_START << " Saving covariances to CSV-file: " << COLOR_END << covarianceFileName << std::endl;
39 // Open for writing and appending
40 fileStreams[transformIdentifier + "_covariance"].open(covarianceFileName, std::ofstream::out | std::ofstream::app);
41 // Write header
42 fileStreams[transformIdentifier + "_covariance"] << "time, cov_t1_t1, cov_t1_t2, cov_t1_t3, cov_t1_r1, cov_t1_r2, cov_t1_r3, "
43 "cov_t2_t1, cov_t2_t2, cov_t2_t3, cov_t2_r1, cov_t2_r2, cov_t2_r3, "
44 "cov_t3_t1, cov_t3_t2, cov_t3_t3, cov_t3_r1, cov_t3_r2, cov_t3_r3, "
45 "cov_r1_t1, cov_r1_t2, cov_r1_t3, cov_r1_r1, cov_r1_r2, cov_r1_r3, "
46 "cov_r2_t1, cov_r2_t2, cov_r2_t3, cov_r2_r1, cov_r2_r2, cov_r2_r3, "
47 "cov_r3_t1, cov_r3_t2, cov_r3_t3, cov_r3_r1, cov_r3_r2, cov_r3_r3\n";
48 }
49 }
50}
51
52// Latitude, Longitude, Altitude
53void FileLogger::createLatLonAltCsvFileStream(std::map<std::string, std::ofstream>& fileStreams, const std::string& savePath,
54 const std::string& transformIdentifier, const std::string& timeString) {
55 if (fileStreams.find(transformIdentifier) == fileStreams.end()) {
56 // If not, create a new file stream for this category
57 std::string fileName = savePath + timeString + "/" + transformIdentifier + ".csv";
58 REGULAR_COUT << GREEN_START << " Saving lat-lon-alt states to CSV-file: " << COLOR_END << fileName << std::endl;
59 // Open for writing and appending
60 fileStreams[transformIdentifier].open(fileName, std::ofstream::out | std::ofstream::app);
61 // Write header
62 fileStreams[transformIdentifier] << "time, latitude, longitude, altitude\n";
63 }
64}
65
66// Point3
67void FileLogger::createPoint3CsvFileStream(std::map<std::string, std::ofstream>& fileStreams, const std::string& savePath,
68 const std::string& transformIdentifier, const std::string& timeString) {
69 if (fileStreams.find(transformIdentifier) == fileStreams.end()) {
70 // If not, create a new file stream for this category
71 std::string fileName = savePath + timeString + "/" + transformIdentifier + ".csv";
72 REGULAR_COUT << GREEN_START << " Saving 3D states to CSV-file: " << COLOR_END << fileName << std::endl;
73 // Open for writing and appending
74 fileStreams[transformIdentifier].open(fileName, std::ofstream::out | std::ofstream::app);
75 // Write header
76 fileStreams[transformIdentifier] << "time, x, y, z\n";
77 }
78}
79
80// Imu Bias
81void FileLogger::createImuBiasCsvFileStream(std::map<std::string, std::ofstream>& fileStreams, const std::string& savePath,
82 const std::string& stateCategoryIdentifier, const std::string& timeString) {
83 if (fileStreams.find(stateCategoryIdentifier) == fileStreams.end()) {
84 // If not, create a new file stream for this category
85 std::string fileName = savePath + timeString + "/" + stateCategoryIdentifier + ".csv";
86 REGULAR_COUT << GREEN_START << " Saving IMU bias states to CSV-file: " << COLOR_END << fileName << std::endl;
87 // Open for writing and appending
88 fileStreams[stateCategoryIdentifier].open(fileName, std::ofstream::out | std::ofstream::app);
89 // Write header
90 fileStreams[stateCategoryIdentifier] << "time, accel_x, accel_y, accel_z, gyro_x, gyro_y, gyro_z\n";
91 }
92}
93
94// Double
95void FileLogger::createDoubleCsvFileStream(std::map<std::string, std::ofstream>& fileStreams, const std::string& savePath,
96 const std::string& transformIdentifier, const std::string& timeString) {
97 if (fileStreams.find(transformIdentifier) == fileStreams.end()) {
98 // If not, create a new file stream for this category
99 std::string fileName = savePath + timeString + "/" + transformIdentifier + ".csv";
100 REGULAR_COUT << GREEN_START << " Saving double values to CSV-file: " << COLOR_END << fileName << std::endl;
101 // Open for writing and appending
102 fileStreams[transformIdentifier].open(fileName, std::ofstream::out | std::ofstream::app);
103 // Write header
104 fileStreams[transformIdentifier] << "time, value\n";
105 }
106}
107
108// 2. TUM
109// Pose3
110void FileLogger::createPose3TumFileStream(std::map<std::string, std::ofstream>& fileStreams, const std::string& savePath,
111 const std::string& transformIdentifier, const std::string& timeString) {
112 if (fileStreams.find(transformIdentifier) == fileStreams.end()) {
113 // If not, create a new file stream for this category
114 std::string fileName = savePath + timeString + "/" + transformIdentifier + ".tum";
115 REGULAR_COUT << GREEN_START << " Saving 6D pose states to TUM-file: " << COLOR_END << fileName << std::endl;
116 // Open for writing and appending
117 fileStreams[transformIdentifier].open(fileName, std::ofstream::out | std::ofstream::app);
118 // Precision
119 fileStreams[transformIdentifier].precision(std::numeric_limits<double>::max_digits10);
120 // Write header
121 fileStreams[transformIdentifier] << "# timestamp tx ty tz qx qy qz qw\n";
122 }
123}
124
125// Write to File
126// 1. CSV
127// Pose3
128void FileLogger::writePose3ToCsvFile(std::map<std::string, std::ofstream>& fileStreams, const gtsam::Pose3& pose,
129 const std::string& transformIdentifier, const double timeStamp, const bool saveCovarianceFlag,
130 const std::optional<Eigen::Matrix<double, 6, 6>>& optionalPoseCovarianceInWorldRos) {
131 fileStreams[transformIdentifier] << std::setprecision(14) << timeStamp << ", " << pose.x() << ", " << pose.y() << ", " << pose.z() << ", "
132 << pose.rotation().toQuaternion().x() << ", " << pose.rotation().toQuaternion().y() << ", "
133 << pose.rotation().toQuaternion().z() << ", " << pose.rotation().toQuaternion().w() << ", "
134 << pose.rotation().roll() << ", " << pose.rotation().pitch() << ", " << pose.rotation().yaw() << "\n";
135 // Write the covariance to the appropriate file
136 if (saveCovarianceFlag) {
137 if (!optionalPoseCovarianceInWorldRos) {
138 throw std::runtime_error("FileLogger: Pose covariance not provided for writing to file.");
139 } else {
140 const auto& poseCovarianceInWorldRos = optionalPoseCovarianceInWorldRos.value();
141 fileStreams[transformIdentifier + "_covariance"]
142 << std::setprecision(14) << timeStamp << ", " << poseCovarianceInWorldRos(0, 0) << ", " << poseCovarianceInWorldRos(0, 1) << ", "
143 << poseCovarianceInWorldRos(0, 2) << ", " << poseCovarianceInWorldRos(0, 3) << ", " << poseCovarianceInWorldRos(0, 4) << ", "
144 << poseCovarianceInWorldRos(0, 5) << ", " << poseCovarianceInWorldRos(1, 0) << ", " << poseCovarianceInWorldRos(1, 1) << ", "
145 << poseCovarianceInWorldRos(1, 2) << ", " << poseCovarianceInWorldRos(1, 3) << ", " << poseCovarianceInWorldRos(1, 4) << ", "
146 << poseCovarianceInWorldRos(1, 5) << ", " << poseCovarianceInWorldRos(2, 0) << ", " << poseCovarianceInWorldRos(2, 1) << ", "
147 << poseCovarianceInWorldRos(2, 2) << ", " << poseCovarianceInWorldRos(2, 3) << ", " << poseCovarianceInWorldRos(2, 4) << ", "
148 << poseCovarianceInWorldRos(2, 5) << ", " << poseCovarianceInWorldRos(3, 0) << ", " << poseCovarianceInWorldRos(3, 1) << ", "
149 << poseCovarianceInWorldRos(3, 2) << ", " << poseCovarianceInWorldRos(3, 3) << ", " << poseCovarianceInWorldRos(3, 4) << ", "
150 << poseCovarianceInWorldRos(3, 5) << ", " << poseCovarianceInWorldRos(4, 0) << ", " << poseCovarianceInWorldRos(4, 1) << ", "
151 << poseCovarianceInWorldRos(4, 2) << ", " << poseCovarianceInWorldRos(4, 3) << ", " << poseCovarianceInWorldRos(4, 4) << ", "
152 << poseCovarianceInWorldRos(4, 5) << ", " << poseCovarianceInWorldRos(5, 0) << ", " << poseCovarianceInWorldRos(5, 1) << ", "
153 << poseCovarianceInWorldRos(5, 2) << ", " << poseCovarianceInWorldRos(5, 3) << ", " << poseCovarianceInWorldRos(5, 4) << ", "
154 << poseCovarianceInWorldRos(5, 5) << "\n";
155 }
156 }
157}
158
159// Latitude, Longitude, Altitude
160void FileLogger::writeLatLonAltToCsvFile(std::map<std::string, std::ofstream>& fileStreams, const gtsam::Point3& point,
161 const std::string& transformIdentifier, const double timeStamp) {
162 fileStreams[transformIdentifier] << std::setprecision(14) << timeStamp << ", " << point.x() << ", " << point.y() << ", " << point.z()
163 << "\n";
164}
165
166// Point3
167void FileLogger::writePoint3ToCsvFile(std::map<std::string, std::ofstream>& fileStreams, const gtsam::Point3& point,
168 const std::string& transformIdentifier, const double timeStamp) {
169 fileStreams[transformIdentifier] << std::setprecision(14) << timeStamp << ", " << point.x() << ", " << point.y() << ", " << point.z()
170 << "\n";
171}
172
173// Imu Bias
174void FileLogger::writeImuBiasToCsvFile(std::map<std::string, std::ofstream>& fileStreams, const gtsam::imuBias::ConstantBias& imuBias,
175 const std::string& stateCategoryIdentifier, const double timeStamp) {
176 fileStreams[stateCategoryIdentifier] << std::setprecision(14) << timeStamp << ", " << imuBias.accelerometer().x() << ", "
177 << imuBias.accelerometer().y() << ", " << imuBias.accelerometer().z() << ", "
178 << imuBias.gyroscope().x() << ", " << imuBias.gyroscope().y() << ", " << imuBias.gyroscope().z()
179 << "\n";
180}
181
182// Double
183void FileLogger::writeDoubleToCsvFile(std::map<std::string, std::ofstream>& fileStreams, const double value,
184 const std::string& transformIdentifier, const double timeStamp) {
185 fileStreams[transformIdentifier] << std::setprecision(14) << timeStamp << ", " << value << "\n";
186}
187
188// 2. TUM
189// Pose3
190void FileLogger::writePose3ToTumFile(std::map<std::string, std::ofstream>& fileStreams, const gtsam::Pose3& pose,
191 const std::string& transformIdentifier, const double timeStamp) {
192 fileStreams[transformIdentifier] << std::setprecision(14) << timeStamp << " " << pose.x() << " " << pose.y() << " " << pose.z() << " "
193 << pose.rotation().toQuaternion().x() << " " << pose.rotation().toQuaternion().y() << " "
194 << pose.rotation().toQuaternion().z() << " " << pose.rotation().toQuaternion().w() << "\n";
195}
196
197} // namespace holistic_fusion
#define REGULAR_COUT
#define COLOR_END
#define GREEN_START
static void writeLatLonAltToCsvFile(std::map< std::string, std::ofstream > &fileStreams, const gtsam::Point3 &point, const std::string &transformIdentifier, const double timeStamp)
static void createLatLonAltCsvFileStream(std::map< std::string, std::ofstream > &fileStreams, const std::string &savePath, const std::string &transformIdentifier, const std::string &timeString)
static void writePose3ToCsvFile(std::map< std::string, std::ofstream > &fileStreams, const gtsam::Pose3 &pose, const std::string &transformIdentifier, const double timeStamp, const bool saveCovarianceFlag, const std::optional< Eigen::Matrix< double, 6, 6 > > &optionalPoseCovarianceInWorldRos=std::nullopt)
static void writeDoubleToCsvFile(std::map< std::string, std::ofstream > &fileStreams, const double value, const std::string &transformIdentifier, const double timeStamp)
static void writePose3ToTumFile(std::map< std::string, std::ofstream > &fileStreams, const gtsam::Pose3 &pose, const std::string &transformIdentifier, const double timeStamp)
static void writePoint3ToCsvFile(std::map< std::string, std::ofstream > &fileStreams, const gtsam::Point3 &point, const std::string &transformIdentifier, const double timeStamp)
static void createPoint3CsvFileStream(std::map< std::string, std::ofstream > &fileStreams, const std::string &savePath, const std::string &transformIdentifier, const std::string &timeString)
static void createImuBiasCsvFileStream(std::map< std::string, std::ofstream > &fileStreams, const std::string &savePath, const std::string &stateCategoryIdentifier, const std::string &timeString)
static void createPose3CsvFileStream(std::map< std::string, std::ofstream > &fileStreams, const std::string &savePath, const std::string &transformIdentifier, const std::string &timeString, const bool saveCovarianceFlag)
static void createDoubleCsvFileStream(std::map< std::string, std::ofstream > &fileStreams, const std::string &savePath, const std::string &transformIdentifier, const std::string &timeString)
static void writeImuBiasToCsvFile(std::map< std::string, std::ofstream > &fileStreams, const gtsam::imuBias::ConstantBias &imuBias, const std::string &stateCategoryIdentifier, const double timeStamp)
static void createPose3TumFileStream(std::map< std::string, std::ofstream > &fileStreams, const std::string &savePath, const std::string &transformIdentifier, const std::string &timeString)