persistence.cpp
Go to the documentation of this file.
1/**
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @author Fabian Reister ( fabian dot reister at kit dot edu )
17 * @date 2022
18 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
19 * GNU General Public License
20 */
21
22#include "persistence.h"
23
24#include <cmath>
25#include <cstdint>
26#include <filesystem>
27#include <fstream>
28#include <optional>
29#include <string>
30#include <vector>
31
32#include <opencv2/core.hpp>
33#include <opencv2/core/eigen.hpp>
34#include <opencv2/core/hal/interface.h>
35#include <opencv2/core/mat.hpp>
36#include <opencv2/imgcodecs.hpp>
37#include <opencv2/imgproc.hpp>
38
39#include <SimoxUtility/json/eigen_conversion.h> // IWYU pragma: keep
40
44
47
48#include <nlohmann/json.hpp>
49
51{
52
54 load(const std::filesystem::path& directory)
55 {
56 // load
57 const auto filename = directory / "costmap.json";
58 std::ifstream ifs(filename);
59 ARMARX_VERBOSE << "Loading costmap info " << filename.string();
60 const nlohmann::json j = nlohmann::json::parse(ifs);
61
62 // params
63 const auto& jParam = j.at("params");
64
65 const Costmap::Parameters params{.binaryGrid = jParam.at("binary_grid"),
66 .cellSize = jParam.at("cell_size")};
67
68 // scene bounds
69 const auto& jSceneBounds = j.at("scene_bounds");
70
71 const std::vector<float> boundsMin = jSceneBounds.at("min");
72 const std::vector<float> boundsMax = jSceneBounds.at("max");
73
74 ARMARX_CHECK_EQUAL(boundsMin.size(), 2);
75 ARMARX_CHECK_EQUAL(boundsMax.size(), 2);
76
77 const SceneBounds sceneBounds{.min = {boundsMin.at(0), boundsMin.at(1)},
78 .max = {boundsMax.at(0), boundsMax.at(1)}};
79
80
81 // grid
82 const std::string gridFilename = j.at("grid_filename");
83 cv::Mat gridMat = cv::imread((directory / gridFilename).string(),
84 cv::IMREAD_ANYCOLOR | cv::IMREAD_ANYDEPTH);
85
86 Eigen::MatrixXf grid;
87 cv::cv2eigen(gridMat, grid);
88
89 // mask, if any
90 std::optional<Costmap::Mask> optMask;
91 if (not j.at("mask_filename").empty())
92 {
93 const std::string maskFilename = j.at("grid_filename");
94 cv::Mat maskMat = cv::imread((directory / maskFilename).string(),
95 cv::IMREAD_ANYCOLOR | cv::IMREAD_ANYDEPTH);
96
98 cv::cv2eigen(maskMat, mask);
99
100 optMask = mask.cast<bool>();
101 }
102
103 Eigen::Isometry2f origin = Eigen::Isometry2f::Identity();
104 if (not j.at("origin").empty())
105 {
106 const Eigen::Matrix3f h = j.at("origin");
107 origin.matrix() = h;
108 }
109
110 return {grid, params, sceneBounds, optMask, origin};
111 }
112
113 bool
114 save(const Costmap& costmap, const std::filesystem::path& directory)
115 {
117
118 ARMARX_INFO << "Storing costmap in directory " << QUOTED(directory.string());
119
120 if (not std::filesystem::exists(directory))
121 {
122 ARMARX_VERBOSE << "Creating directory " << QUOTED(directory.string());
123 std::filesystem::create_directories(directory);
124 }
125
126 nlohmann::json j = {{"params",
127 {{"binary_grid", costmap.params().binaryGrid},
128 {"cell_size", costmap.params().cellSize}}},
129 {"scene_bounds",
130 {{"min",
131 std::vector<float>{costmap.getLocalSceneBounds().min.x(),
132 costmap.getLocalSceneBounds().min.y()}},
133 {"max",
134 std::vector<float>{costmap.getLocalSceneBounds().max.x(),
135 costmap.getLocalSceneBounds().max.y()}}}},
136 {"origin", costmap.origin().matrix()}};
137
138 std::optional<cv::Mat1b> mask;
139 if (costmap.getMask().has_value())
140 {
141 // mask, if any
143 costmap.getMask()->cast<std::uint8_t>();
144 cv::Mat1b m;
145 cv::eigen2cv(maskI, m);
146 mask = m;
147 }
148
149 // grid
150 {
152
153 cv::Mat1f grid;
154 cv::eigen2cv(costmap.getGrid(), grid);
155
156 const std::string gridFilename = "grid.exr";
157 cv::imwrite((directory / gridFilename).string(), grid);
158
159 j["grid_filename"] = gridFilename;
160
161 // for debugging purpose, also save a png image
162 const std::string gridDebuggingFilename = "grid";
163
164 double min;
165 double max;
166 if (mask)
167 {
168 cv::minMaxIdx(grid, &min, &max, 0, 0, mask.value());
169 }
170 else
171 {
172 cv::minMaxIdx(grid, &min, &max);
173 }
174 cv::Mat adjMap;
175 grid.convertTo(adjMap, CV_8UC1, 255 / (max - min), -255 * min / (max - min));
176
177 cv::Mat colorsMap;
178 applyColorMap(adjMap, colorsMap, cv::COLORMAP_JET);
179 cv::Mat maskedColorsMap;
180 if (mask)
181 {
182 colorsMap.copyTo(maskedColorsMap, mask.value());
183 }
184 else
185 {
186 maskedColorsMap = colorsMap;
187 }
188 cv::imwrite((directory / (gridDebuggingFilename + ".png")).string(), maskedColorsMap);
189
191
192 // mask if any
193 if (mask)
194 {
195 const std::string maskFilename = "mask.ppm";
196 cv::imwrite((directory / maskFilename).string(), mask.value());
197
198 j["mask_filename"] = maskFilename;
199 }
200 }
201
202 // save
203 std::ofstream of(directory / "costmap.json");
204 of << j;
205
206 return true;
207 }
208
209
210} // namespace armarx::navigation::algorithms
#define QUOTED(x)
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
This file is part of ArmarX.
Costmap load(const std::filesystem::path &directory)
bool save(const Costmap &costmap, const std::filesystem::path &directory)
std::vector< T > max(const std::vector< T > &v1, const std::vector< T > &v2)
std::vector< T > min(const std::vector< T > &v1, const std::vector< T > &v2)
#define ARMARX_TRACE
Definition trace.h:77