Program Listing for File data_logger.h¶
↰ Return to documentation for file (core/data_logger.h)
#pragma once
#include <spdlog/spdlog.h>
#include <Eigen/Dense>
#include <filesystem>
#include <highfive/H5Easy.hpp>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>
#include "lupnt/core/definitions.h"
#include "lupnt/states/state.h"
#define LOG(id, ...) lupnt::DataLogger::LogHelper(id, #__VA_ARGS__, __VA_ARGS__)
namespace lupnt {
class DataLogger {
public:
using MatrixMap = std::unordered_map<std::string, std::vector<Eigen::MatrixXd>>;
using DoubleMap = std::unordered_map<std::string, std::vector<double>>;
using StringMap = std::unordered_map<std::string, std::vector<std::string>>;
public:
static void SetOutputFile(const std::filesystem::path& filename);
static void Log(const std::string& name, double value);
static void Log(const std::string& name, Real value);
static void Log(const std::string& name, const std::string& value);
static void LogState(const std::string& parent, const State& state);
template <typename Derived>
static void Log(const std::string& name, const Eigen::DenseBase<Derived>& value) {
// Forward to the implementation in the .cc file
LogMatrix(name, value.template cast<double>());
}
static void Flush();
template <typename... Args>
static void LogHelper(const std::string& id, const std::string& names, const Args&... args) {
std::istringstream name_stream(names);
std::vector<std::string> name_list;
std::string name;
// Efficiently split the comma-separated names
while (std::getline(name_stream, name, ',')) {
// Trim leading/trailing spaces
name.erase(0, name.find_first_not_of(" \t"));
name.erase(name.find_last_not_of(" \t") + 1);
// Remove final _ if present
if (!name.empty() && name.back() == '_') name.pop_back();
name_list.push_back(name);
}
// Ensure number of names matches number of arguments
constexpr size_t num_args = sizeof...(args);
if (name_list.size() != num_args) {
spdlog::error("Mismatch: Expected {} names but received {} arguments.", name_list.size(),
num_args);
return;
}
// Log each variable with its corresponding name, prefixed by the ID
size_t index = 0;
((Log(id + "/" + name_list[index++], args)), ...);
}
virtual void Log(Real time) = 0;
private:
static void LogMatrix(const std::string& name, const Eigen::MatrixXd& value);
};
} // namespace lupnt