4#include "TinyRobotics/maps/PathSegment.h"
5#include "TinyRobotics/utils/Common.h"
8namespace tinyrobotics {
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
41template <
typename Map,
typename StateT =
CellState,
typename T =
float>
45 size_t write(Map& map, Print& out) {
49 snprintf(buf,
sizeof(buf),
"GridMap x:%d, y:%d, resolution=%g\n",
50 map.getXCount(), map.getYCount(), (
double)map.getResolution());
51 if (n > 0) total += out.print(buf);
52 for (
int x = 0; x < map.getXCount(); ++x) {
53 for (
int y = 0; y < map.getYCount(); ++y) {
55 map.cellToWorld(x, y, coord.x, coord.y);
57 if (map.getCell(x, y, state)) {
58 int n = snprintf(buf,
sizeof(buf),
"%g,%g,%g\n", (
double)coord.x,
59 (
double)coord.y, (
double)state);
60 if (n > 0) total += out.print(buf);
62 int n = snprintf(buf,
sizeof(buf),
"%g,%g,\n", (
double)coord.x,
64 if (n > 0) total += out.print(buf);
73 size_t read(Map& map, Stream& in) {
80 if (!readLine(in, header))
return 0;
81 total += header.length() + 1;
82 if (sscanf(header.c_str(),
"GridMap x:%d, y:%d, resolution=%f", &x, &y,
85 if (x <= 0 || y <= 0 || res <= 0)
return 0;
87 map.setResolution(res);
90 int cellCount = x * y;
92 while (filled < cellCount) {
94 if (!readLine(in, line))
return 0;
95 total += line.length() + 1;
97 int parsed = sscanf(line.c_str(),
"%f,%f,%f", &wx, &wy, &value);
98 if (parsed < 2)
return 0;
99 Coordinate<T> coord(
static_cast<T>(wx),
static_cast<T>(wy));
101 map.setCell(coord, (StateT)value);
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
144template <
typename MapT,
typename CoordinateT =
Coordinate<
float>>
146 using T =
typename CoordinateT::value_type;
148 size_t write(MapT& map, Print& out) {
151 size_t len = map.size();
152 for (size_t i = 0; i < len; ++i) {
153 auto& segment = map[i];
154 auto& from = segment.from;
155 auto& to = segment.to;
156 double cost = segment.cost;
157 bool directed = segment.directed;
158 int n = snprintf(buf,
sizeof(buf),
"%g,%g,%g,%g,%g,%d\n", (
double)from.x,
159 (
double)from.y, (
double)to.x, (
double)to.y, cost,
161 if (n > 0) total += out.print(buf);
167 size_t read(MapT& map, Stream& in) {
170 while (readLine(in, line)) {
171 total += line.length() + 1;
172 float fx, fy, tx, ty, cost = 1.0f;
174 int parsed = sscanf(line.c_str(),
"%f,%f,%f,%f,%f,%d", &fx, &fy, &tx, &ty,
175 &cost, &directedInt);
176 if (parsed < 4)
return 0;
177 CoordinateT from(
static_cast<T>(fx),
static_cast<T>(fy));
178 CoordinateT to(
static_cast<T>(tx),
static_cast<T>(ty));
179 double segCost = (parsed >= 5) ? cost : 1.0;
180 bool directed = (parsed == 6) ? (directedInt != 0) :
false;
181 PathSegment<CoordinateT> segment{from, to, segCost, directed};
182 map.addSegment(segment);
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210template <
typename PointCloudT>
212 using T =
typename PointCloudT::value_type;
216 size_t write(
const PointCloudT& cloud, Print& out) {
220 const auto& b = cloud.bounds();
221 sprintf(buf,
"#PointCloud voxelSize:%g is3d:%d bounds:%g,%g,%g,%g,%g,%g\n",
222 (
double)cloud.voxelSize(), cloud.is3D() ? 1 : 0, (
double)b.min.x,
223 (
double)b.min.y, (
double)b.min.z, (
double)b.max.x, (
double)b.max.y,
225 total += out.print(buf);
227 total += out.print(
"#Points\n");
228 for (
const auto& pt : cloud.points()) {
229 sprintf(buf,
"%g,%g,%g\n", (
double)pt.x, (
double)pt.y, (
double)pt.z);
230 total += out.print(buf);
233 total += out.print(
"#Voxels\n");
234 for (
auto it = cloud.beginVoxels(); it != cloud.endVoxels(); ++it) {
235 sprintf(buf,
"%d,%d,%d\n", it->x, it->y, it->z);
236 total += out.print(buf);
243 size_t read(PointCloudT& cloud, Stream& in) {
247 if (!readLine(in, line))
return 0;
248 total += line.length() + 1;
249 float voxelSize = 0.0f, minx, miny, minz, maxx, maxy, maxz;
251 if (sscanf(line.c_str(),
252 "#PointCloud voxelSize:%f is3d:%d bounds:%f,%f,%f,%f,%f,%f",
253 &voxelSize, &is3d, &minx, &miny, &minz, &maxx, &maxy,
256 cloud.set3D(is3d != 0);
257 cloud.setBounds(minx, miny, minz, maxx, maxy, maxz);
258 cloud.buildVoxelGrid(voxelSize);
260 if (!readLine(in, line))
return 0;
261 total += line.length() + 1;
262 if (line.find(
"#Points") != 0)
return 0;
264 while (readLine(in, line)) {
265 total += line.length() + 1;
266 if (line.find(
"#Voxels") == 0)
break;
267 float x, y, z = 0.0f;
268 int parsed = sscanf(line.c_str(),
"%f,%f,%f", &x, &y, &z);
269 if (parsed < 2)
return 0;
270 cloud.add(
static_cast<T>(x),
static_cast<T>(y),
static_cast<T>(z));
273 while (readLine(in, line)) {
274 total += line.length() + 1;
276 if (sscanf(line.c_str(),
"%d,%d,%d", &vx, &vy, &vz) == 3) {
277 cloud.addVoxel((
float)vx * voxelSize, (
float)vy * voxelSize,
278 (
float)vz * voxelSize);
A generic 3D coordinate class for robotics, navigation, and spatial calculations.
Definition: Coordinate.h:57
Utility class for serializing and deserializing grid maps in CSV format.
Definition: MapSerializer.h:42
Utility class for serializing and deserializing path maps (sequences of segments) in CSV format.
Definition: MapSerializer.h:145
Utility class for serializing and deserializing PointCloud objects, including points,...
Definition: MapSerializer.h:211
CellState
Cell state for occupancy grid mapping (e.g., UNKNOWN, FREE, OCCUPIED).
Definition: Common.h:32