ctrl-utils
json.h
1 
10 #ifndef CTRL_UTILS_JSON_H_
11 #define CTRL_UTILS_JSON_H_
12 
13 #include <exception> // std::runtime_error
14 #include <nlohmann/json.hpp>
15 
16 #include "eigen.h"
17 #include "string.h"
18 
19 namespace ctrl_utils {
20 
21 template <>
22 inline std::string ToString(const nlohmann::json& value) {
23  return value.dump();
24 }
25 
26 template <>
27 inline nlohmann::json FromString(const std::string& str) {
28  return nlohmann::json::parse(str);
29 }
30 
31 } // namespace ctrl_utils
32 
33 namespace Eigen {
34 
35 template <typename Derived>
36 void to_json(nlohmann::json& json, const Eigen::DenseBase<Derived>& matrix) {
37  json = nlohmann::json::array();
38 
39  if (matrix.cols() == 1) {
40  for (int i = 0; i < matrix.rows(); i++) {
41  json.push_back(matrix(i));
42  }
43  return;
44  }
45 
46  for (int i = 0; i < matrix.rows(); i++) {
47  json.emplace_back(nlohmann::json::array());
48  nlohmann::json& json_i = json[i];
49  for (int j = 0; j < matrix.cols(); j++) {
50  json_i.push_back(matrix(i, j));
51  }
52  }
53 }
54 
55 template <typename Derived>
56 void from_json(const nlohmann::json& json, Eigen::DenseBase<Derived>& matrix) {
57  if (json.type() != nlohmann::json::value_t::array) {
58  throw std::runtime_error("Eigen::from_json(): Json type is not an array.");
59  }
60 
61  if (json.empty() ||
62  (json[0].type() == nlohmann::json::value_t::array && json[0].empty())) {
63  if (matrix.size() != 0) {
64  throw std::runtime_error("Eigen::from_json(): Json array is empty.");
65  }
66  return;
67  }
68 
69  const int kNumRows = json.size();
70  if (json[0].type() != nlohmann::json::value_t::array) {
71  if (matrix.size() == 0) {
72  matrix.resize(kNumRows);
73  } else if (matrix.rows() != kNumRows) {
74  throw std::runtime_error(
75  "Eigen::from_json(): Json array is not the same size.");
76  }
77  for (int i = 0; i < kNumRows; i++) {
78  matrix(i) = json[i];
79  }
80  return;
81  }
82 
83  const int kNumCols = json[0].size();
84  if (matrix.size() == 0) {
85  matrix.resize(kNumRows, kNumCols);
86  } else if (matrix.rows() != kNumRows || matrix.cols() != kNumCols) {
87  throw std::runtime_error(
88  "Eigen::from_json(): Json array is not the same size.");
89  }
90 
91  for (int i = 0; i < kNumRows; i++) {
92  const nlohmann::json& json_i = json[i];
93  for (int j = 0; j < kNumCols; j++) {
94  matrix(i, j) = json_i[j];
95  }
96  }
97 }
98 
99 template <typename Derived>
100 void to_json(nlohmann::json& json, const Eigen::QuaternionBase<Derived>& quat) {
101  json["w"] = quat.w();
102  json["x"] = quat.x();
103  json["y"] = quat.y();
104  json["z"] = quat.z();
105 }
106 
107 template <typename Derived>
108 void from_json(const nlohmann::json& json,
109  Eigen::QuaternionBase<Derived>& quat) {
110  quat.w() = json["w"].get<typename Derived::Scalar>();
111  quat.x() = json["x"].get<typename Derived::Scalar>();
112  quat.y() = json["y"].get<typename Derived::Scalar>();
113  quat.z() = json["z"].get<typename Derived::Scalar>();
114  quat.normalize();
115 }
116 
117 inline void to_json(nlohmann::json& json, const Eigen::Isometry3d& T) {
118  json["pos"] = T.translation();
119  json["ori"] = Eigen::Quaterniond(T.linear());
120 }
121 
122 inline void from_json(const nlohmann::json& json, Eigen::Isometry3d& T) {
123  const Eigen::Vector3d pos = json["pos"].get<Eigen::Vector3d>();
124  const Eigen::Quaterniond ori = json["ori"].get<Eigen::Quaterniond>();
125  T = Eigen::Translation3d(pos) * ori;
126 }
127 
128 } // namespace Eigen
129 
130 #endif // CTRL_UTILS_JSON_H_
Definition: ctrl_utils.cc:18
nlohmann::json FromString(const std::string &str)
Definition: json.h:27