3#include <glim/util/config.hpp>
9#include <spdlog/spdlog.h>
10#include <nlohmann/json.hpp>
13#include <Eigen/Geometry>
15#include <glim/util/convert_to_string.hpp>
27 static std::optional<OutType> convert(
const InType& in) {
return in; }
29 static InType invert(
const OutType& value) {
return value; }
33template <
typename T,
int N,
int M>
34struct traits<Eigen::Matrix<T, N, M>> {
35 using InType = std::vector<double>;
36 using OutType = Eigen::Matrix<T, N, M>;
38 static std::optional<OutType> convert(
const InType& in) {
39 if (in.size() != N * M) {
42 return Eigen::Map<const OutType>(in.data());
45 static std::vector<double> invert(
const OutType& value) {
return std::vector<double>(value.data(), value.data() + N * M); }
50struct traits<Eigen::Quaternion<T>> {
51 using InType = std::vector<double>;
52 using OutType = Eigen::Quaternion<T>;
54 static std::optional<OutType> convert(
const InType& in) {
59 return OutType(in.data()).normalized();
62 static std::vector<double> invert(
const OutType& value) {
return std::vector<double>{value.x(), value.y(), value.z(), value.w()}; }
67struct traits<Eigen::Transform<T, 3, Eigen::Isometry>> {
68 using InType = std::vector<double>;
69 using OutType = Eigen::Transform<T, 3, Eigen::Isometry>;
71 static std::optional<OutType> convert(
const InType& in) {
76 OutType se3 = OutType::Identity();
77 se3.translation() = Eigen::Map<const Eigen::Matrix<T, 3, 1>>(in.data());
78 se3.linear() = Eigen::Quaternion<T>(in.data() + 3).normalized().toRotationMatrix();
82 static std::vector<double> invert(
const OutType& value) {
83 Eigen::Matrix<T, 3, 1> t = value.translation();
84 Eigen::Quaternion<T> q(value.linear());
85 return std::vector<double>{t.x(), t.y(), t.z(), q.x(), q.y(), q.z(), q.w()};
90struct traits<std::vector<Eigen::Isometry3d>> {
91 using InType = std::vector<double>;
92 using OutType = std::vector<Eigen::Isometry3d>;
94 static std::optional<OutType> convert(
const InType& in) {
99 OutType poses(in.size() / 7);
100 for (
int i = 0; i < poses.size(); i++) {
101 poses[i].setIdentity();
102 poses[i].translation() << in[i * 7], in[i * 7 + 1], in[i * 7 + 2];
103 poses[i].linear() = Eigen::Quaterniond(in[i * 7 + 6], in[i * 7 + 3], in[i * 7 + 4], in[i * 7 + 5]).normalized().toRotationMatrix();
109 static std::vector<double> invert(
const OutType& value) {
110 std::vector<double> values(value.size() * 7);
111 for (
int i = 0; i < value.size(); i++) {
112 Eigen::Vector3d t = value[i].translation();
113 Eigen::Quaterniond q(value[i].linear());
115 values[i * 7] = t.x();
116 values[i * 7 + 1] = t.y();
117 values[i * 7 + 2] = t.z();
118 values[i * 7 + 3] = q.x();
119 values[i * 7 + 4] = q.y();
120 values[i * 7 + 5] = q.z();
121 values[i * 7 + 6] = q.w();
131std::optional<T>
Config::param(
const std::string& module_name,
const std::string& param_name)
const {
132 const auto& json = std::any_cast<const nlohmann::json&>(config);
134 auto module = json.find(module_name);
135 if (module == json.end()) {
139 auto parameter =
module->find(param_name);
140 if (parameter == module->end()) {
144 return traits<T>::convert(parameter->get<
typename traits<T>::InType>());
148T
Config::param(
const std::string& module_name,
const std::string& param_name,
const T& default_value)
const {
149 auto found = param<T>(module_name, param_name);
151 spdlog::warn(
"param {}/{} not found", module_name, param_name);
152 spdlog::warn(
"use default_value={}", convert_to_string(default_value));
153 return default_value;
156 spdlog::debug(
"param {}/{}={}", module_name, param_name, convert_to_string(found.value()));
157 return found.value();
162 auto found = param<T>(module_name, param_name);
164 spdlog::critical(
"param {}/{} not found", module_name, param_name);
168 spdlog::debug(
"param {}/{}={}", module_name, param_name, convert_to_string(found.value()));
174 auto& json = std::any_cast<nlohmann::json&>(config);
176 json[module_name][param_name] = traits<T>::invert(value);
182std::optional<T>
Config::param_nested(
const std::vector<std::string>& nested_module_names,
const std::string& param_name)
const {
183 const auto& json = std::any_cast<const nlohmann::json&>(config);
185 nlohmann::json::const_iterator itr = json.find(nested_module_names[0]);
186 if (itr == json.end()) {
190 for (
int i = 1; i < nested_module_names.size(); i++) {
191 const auto next = itr->find(nested_module_names[i]);
192 if (next == itr->end()) {
199 auto parameter = itr->find(param_name);
200 if (parameter == itr->end()) {
204 return traits<T>::convert(parameter->get<
typename traits<T>::InType>());
208T
Config::param_nested(
const std::vector<std::string>& nested_module_names,
const std::string& param_name,
const T& default_value)
const {
209 auto found = param_nested<T>(nested_module_names, param_name);
211 std::stringstream param_name;
212 for (
const auto& module_name : nested_module_names) {
213 param_name << module_name <<
"/";
215 spdlog::warn(
"param {} not found", param_name.str());
216 spdlog::warn(
"use default_value={}", convert_to_string(default_value));
217 return default_value;
220 return found.value();
225 auto found = param_nested<T>(nested_module_names, param_name);
227 std::stringstream param_name;
228 for (
const auto& module_name : nested_module_names) {
229 param_name << module_name <<
"/";
231 spdlog::critical(
"param {} not found", param_name.str());
237#define DEFINE_CONFIG_IO_SPECIALIZATION(TYPE) \
238 template std::optional<TYPE> Config::param(const std::string& module_name, const std::string& param_name) const; \
239 template TYPE Config::param(const std::string&, const std::string&, const TYPE&) const; \
240 template TYPE Config::param_cast(const std::string&, const std::string&) const; \
241 template std::optional<TYPE> Config::param_nested(const std::vector<std::string>& nested_module_names, const std::string& param_name) const; \
242 template TYPE Config::param_nested(const std::vector<std::string>&, const std::string&, const TYPE&) const; \
243 template TYPE Config::param_cast_nested(const std::vector<std::string>&, const std::string&) const; \
244 template bool Config::override_param(const std::string&, const std::string&, const TYPE&);
T param_cast(const std::string &module_name, const std::string ¶m_name) const
Get a parameter.
Definition config_impl.hpp:161
std::optional< T > param(const std::string &module_name, const std::string ¶m_name) const
Get a parameter.
Definition config_impl.hpp:131
std::optional< T > param_nested(const std::vector< std::string > &nested_module_names, const std::string ¶m_name) const
Get a parameter from a nested module.
Definition config_impl.hpp:182
bool override_param(const std::string &module_name, const std::string ¶m_name, const T &value)
Override a parameter value.
Definition config_impl.hpp:173
T param_cast_nested(const std::vector< std::string > &nested_module_names, const std::string ¶m_name) const
Get a parameter.
Definition config_impl.hpp:224