Apollo 11.0
自动驾驶开放平台
base_map_node.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19#include "cyber/common/file.h"
20#include "cyber/common/log.h"
22
23namespace apollo {
24namespace localization {
25namespace msf {
26
29
31 : map_matrix_(matrix), compression_strategy_(strategy) {}
32
34 if (map_matrix_ != nullptr) {
35 delete map_matrix_;
36 }
37 if (compression_strategy_ != nullptr) {
39 }
40}
41
42void BaseMapNode::Init(const BaseMapConfig* map_config,
43 const MapNodeIndex& index, bool create_map_cells) {
44 map_config_ = map_config;
45 index_ = index;
47 is_reserved_ = false;
48 data_is_ready_ = false;
49 is_changed_ = false;
50 if (create_map_cells) {
52 }
53}
54
56 map_config_ = map_config;
57 map_matrix_->Init(map_config);
58}
59
61 if (is_changed_) {
62 Save();
63 AERROR << "Save Map Node to disk: " << index_ << ".";
64 }
65}
66
68 is_changed_ = false;
69 data_is_ready_ = false;
70 is_reserved_ = false;
72}
73
74// void BaseMapNode::SetCompressionStrategy(compression::CompressionStrategy*
75// strategy) {
76// compression_strategy_ = strategy;
77// return;
78// }
79
82 char buf[1024];
83 std::string path = map_config_->map_folder_path_;
84 if (!EnsureDirectory(path)) {
85 return false;
86 }
87 path = path + "/map";
88 if (!EnsureDirectory(path)) {
89 return false;
90 }
91 snprintf(buf, sizeof(buf), "/%03u", index_.resolution_id_);
92 path = path + buf;
93 if (!EnsureDirectory(path)) {
94 return false;
95 }
96 if (index_.zone_id_ > 0) {
97 path = path + "/north";
98 } else {
99 path = path + "/south";
100 }
101 if (!EnsureDirectory(path)) {
102 return false;
103 }
104 snprintf(buf, sizeof(buf), "/%02d", abs(index_.zone_id_));
105 path = path + buf;
106 if (!EnsureDirectory(path)) {
107 return false;
108 }
109 snprintf(buf, sizeof(buf), "/%08u", index_.m_);
110 path = path + buf;
111 if (!EnsureDirectory(path)) {
112 return false;
113 }
114 snprintf(buf, sizeof(buf), "/%08u", index_.n_);
115 path = path + buf;
116
117 AINFO << "Save node: " << path;
118
119 FILE* file = fopen(path.c_str(), "wb");
120 if (file) {
121 CreateBinary(file);
122 fclose(file);
123 is_changed_ = false;
124 return true;
125 } else {
126 AERROR << "Can't write to file: " << path << ".";
127 return false;
128 }
129}
130
132 char buf[1024];
133 std::string path = map_config_->map_folder_path_;
134 if (!DirectoryExists(path)) {
135 return false;
136 }
137 path = path + "/map";
138 if (!DirectoryExists(path)) {
139 return false;
140 }
141 snprintf(buf, sizeof(buf), "/%03u", index_.resolution_id_);
142 path = path + buf;
143 if (!DirectoryExists(path)) {
144 return false;
145 }
146 if (index_.zone_id_ > 0) {
147 path = path + "/north";
148 } else {
149 path = path + "/south";
150 }
151 if (!DirectoryExists(path)) {
152 return false;
153 }
154 snprintf(buf, sizeof(buf), "/%02d", abs(index_.zone_id_));
155 path = path + buf;
156 if (!DirectoryExists(path)) {
157 return false;
158 }
159 snprintf(buf, sizeof(buf), "/%08u", index_.m_);
160 path = path + buf;
161 if (!DirectoryExists(path)) {
162 return false;
163 }
164 snprintf(buf, sizeof(buf), "/%08u", index_.n_);
165 path = path + buf;
166
167 return Load(path.c_str());
168}
169
170bool BaseMapNode::Load(const char* filename) {
171 data_is_ready_ = false;
172 // char buf[1024];
173
174 FILE* file = fopen(filename, "rb");
175 if (file) {
176 LoadBinary(file);
177 fclose(file);
178 is_changed_ = false;
179 data_is_ready_ = true;
180 return true;
181 } else {
182 AERROR << "Can't find the file: " << filename;
183 return false;
184 }
185}
186
187unsigned int BaseMapNode::LoadBinary(FILE* file) {
188 // Load the header
189 unsigned int header_size = GetHeaderBinarySize();
190 std::vector<unsigned char> buf(header_size);
191 size_t read_size = fread(&buf[0], 1, header_size, file);
192 CHECK_EQ(read_size, header_size);
193 unsigned int processed_size = LoadHeaderBinary(&buf[0]);
194 CHECK_EQ(processed_size, header_size);
195
196 // Load the body
197 buf.resize(file_body_binary_size_);
198 read_size = fread(&buf[0], 1, file_body_binary_size_, file);
199 CHECK_EQ(read_size, file_body_binary_size_);
200 processed_size += LoadBodyBinary(&buf);
201 return processed_size;
202}
203
204unsigned int BaseMapNode::CreateBinary(FILE* file) const {
205 unsigned int buf_size = GetBinarySize();
206 std::vector<unsigned char> buffer;
207 buffer.resize(buf_size);
208
209 unsigned int binary_size = 0;
210 std::vector<unsigned char> body_buffer;
211 CreateBodyBinary(&body_buffer);
212 // CHECK_EQ(processed_size, buf_size);
213
214 // Create header
215 unsigned int header_size = GetHeaderBinarySize();
216 unsigned int processed_size = CreateHeaderBinary(&buffer[0], buf_size);
217 CHECK_EQ(processed_size, header_size);
218
219 unsigned int buffer_bias = processed_size;
220 buf_size -= processed_size;
221 binary_size += processed_size;
222 // Create body
223 CHECK_GE(buf_size, body_buffer.size());
224 memcpy(&buffer[buffer_bias], &body_buffer[0], body_buffer.size());
225 binary_size += static_cast<unsigned int>(body_buffer.size());
226 fwrite(&buffer[0], 1, binary_size, file);
227 return binary_size;
228}
229
230unsigned int BaseMapNode::GetBinarySize() const {
231 // It is uncompressed binary size.
233}
234
235unsigned int BaseMapNode::LoadHeaderBinary(unsigned char* buf) {
236 unsigned int target_size = GetHeaderBinarySize();
237 unsigned int* p = reinterpret_cast<unsigned int*>(buf);
239 ++p;
240 int* pp = reinterpret_cast<int*>(p);
241 index_.zone_id_ = *pp;
242 ++pp;
243 p = reinterpret_cast<unsigned int*>(pp);
244 index_.m_ = *p;
245 ++p;
246 index_.n_ = *p;
247 ++p;
248 // left_top_corner_ = GetLeftTopCorner(*map_config_, index_);
251 return target_size;
252}
253
254unsigned int BaseMapNode::CreateHeaderBinary(unsigned char* buf,
255 unsigned int buf_size) const {
256 unsigned int target_size = GetHeaderBinarySize();
257 if (buf_size >= target_size) {
258 unsigned int* p = reinterpret_cast<unsigned int*>(buf);
260 ++p;
261 int* pp = reinterpret_cast<int*>(p);
262 *pp = index_.zone_id_;
263 ++pp;
264 p = reinterpret_cast<unsigned int*>(pp);
265 *p = index_.m_;
266 ++p;
267 *p = index_.n_;
268 ++p;
269 *p = file_body_binary_size_; // Set it before call this function!
270 }
271 return target_size;
272}
273
275 return static_cast<int>(sizeof(unsigned int) // index_.resolution_id_
276 + sizeof(int) // index_.zone_id_
277 + sizeof(unsigned int) // index_.m_
278 + sizeof(unsigned int) // index_.n_
279 + sizeof(unsigned int)); // the body size in file.
280}
281
282// unsigned int BaseMapNode::CreateBodyBinary(
283// std::vector<unsigned char> &buf) const {
284// // Compute the binary body size
285// unsigned int body_size = GetBodyBinarySize();
286// buf.resize(body_size);
287// return map_matrix_->CreateBinary(&buf[0], body_size);
288// }
289
290// unsigned int BaseMapNode::GetBodyBinarySize() const {
291// return map_matrix_->GetBinarySize();
292// }
293
294unsigned int BaseMapNode::LoadBodyBinary(std::vector<unsigned char>* buf) {
295 if (compression_strategy_ == nullptr) {
296 return map_matrix_->LoadBinary(&((*buf)[0]));
297 }
298 std::vector<unsigned char> buf_uncompressed;
299 int ret = compression_strategy_->Decode(buf, &buf_uncompressed);
300 if (ret < 0) {
301 AERROR << "compression Decode error: " << ret;
302 return 0;
303 }
304 AERROR << "map node compress ratio: "
305 << static_cast<float>(buf->size()) /
306 static_cast<float>(buf_uncompressed.size());
307 return map_matrix_->LoadBinary(&buf_uncompressed[0]);
308}
309
311 std::vector<unsigned char>* buf) const {
312 if (compression_strategy_ == nullptr) {
313 unsigned int body_size = GetBodyBinarySize();
314 buf->resize(body_size);
315 map_matrix_->CreateBinary(&((*buf)[0]), body_size);
316 file_body_binary_size_ = static_cast<unsigned int>(buf->size());
317 return static_cast<unsigned int>(buf->size());
318 }
319 std::vector<unsigned char> buf_uncompressed;
320 // Compute the uncompression binary body size
321 unsigned int body_size = GetBodyBinarySize();
322 buf_uncompressed.resize(body_size);
323 map_matrix_->CreateBinary(&buf_uncompressed[0], body_size);
324 compression_strategy_->Encode(&buf_uncompressed, buf);
325 file_body_binary_size_ = static_cast<unsigned int>(buf->size());
326 return static_cast<unsigned int>(buf->size());
327}
328
329unsigned int BaseMapNode::GetBodyBinarySize() const {
330 return map_matrix_->GetBinarySize();
331}
332
333// bool BaseMapNode::GetCoordinate(const idl::car::core::numerical::Vector2D&
334// coordinate,
335// unsigned int& x, unsigned int& y) const {
336// const idl::car::core::numerical::Vector2D& left_top_corner =
337// GetLeftTopCorner(); int off_x = static_cast<int>((coordinate[0] -
338// left_top_corner[0])/GetMapResolution()); int off_y =
339// static_cast<int>((coordinate[1] -
340// left_top_corner[1])/GetMapResolution()); if (off_x >= 0 && off_x <
341// this->map_config_->map_node_size_x_ &&
342// off_y >= 0 && off_y < this->map_config_->map_node_size_y_) {
343// x = static_cast<unsigned int>(off_x);
344// y = static_cast<unsigned int>(off_y);
345// return true;
346// }
347// else {
348// return false;
349// }
350// }
351
352bool BaseMapNode::GetCoordinate(const Eigen::Vector2d& coordinate,
353 unsigned int* x, unsigned int* y) const {
354 const Eigen::Vector2d& left_top_corner = GetLeftTopCorner();
355 int off_x = static_cast<int>((coordinate[0] - left_top_corner[0]) /
357 int off_y = static_cast<int>((coordinate[1] - left_top_corner[1]) /
359 if (off_x >= 0 &&
360 off_x < static_cast<int>(this->map_config_->map_node_size_x_) &&
361 off_y >= 0 &&
362 off_y < static_cast<int>(this->map_config_->map_node_size_y_)) {
363 *x = static_cast<unsigned int>(off_x);
364 *y = static_cast<unsigned int>(off_y);
365 return true;
366 } else {
367 return false;
368 }
369}
370
371// bool BaseMapNode::GetCoordinate(const idl::car::core::numerical::Vector3D&
372// coordinate,
373// unsigned int& x, unsigned int& y) const {
374// idl::car::core::numerical::Vector2D coord2d;
375// coord2d.init(coordinate.get_data());
376// return GetCoordinate(coord2d, x, y);
377// }
378
379bool BaseMapNode::GetCoordinate(const Eigen::Vector3d& coordinate,
380 unsigned int* x, unsigned int* y) const {
381 Eigen::Vector2d coord2d(coordinate[0], coordinate[1]);
382 return GetCoordinate(coord2d, x, y);
383}
384
385// idl::car::core::numerical::Vector2D BaseMapNode::GetCoordinate(
386// unsigned int x, unsigned int y) const {
387// const idl::car::core::numerical::Vector2D& left_top_corner =
388// GetLeftTopCorner(); idl::car::core::numerical::Vector2D coord;
389// coord[0] = left_top_corner[0] + x * GetMapResolution();
390// coord[1] = left_top_corner[1] + y * GetMapResolution();
391// return coord;
392// }
393
394Eigen::Vector2d BaseMapNode::GetCoordinate(unsigned int x,
395 unsigned int y) const {
396 const Eigen::Vector2d& left_top_corner = GetLeftTopCorner();
397 Eigen::Vector2d coord(
398 left_top_corner[0] + static_cast<float>(x) * GetMapResolution(),
399 left_top_corner[1] + static_cast<float>(y) * GetMapResolution());
400 return coord;
401}
402
403// idl::car::core::numerical::Vector2D BaseMapNode::GetLeftTopCorner(
404// const BaseMapConfig& config, const MapNodeIndex& index) {
405// idl::car::core::numerical::Vector2D coord;
406// coord[0] = config.map_range_.get_min_x() +
407// config.map_node_size_x_*config.map_resolutions_[index.resolution_id_]*index.n_;
408// coord[1] = config.map_range_.get_min_y() +
409// config.map_node_size_y_*config.map_resolutions_[index.resolution_id_]*index.m_;
410// assert(coord[0] < config.map_range_.get_max_x());
411// assert(coord[1] < config.map_range_.get_max_y());
412// return coord;
413// }
414
415Eigen::Vector2d BaseMapNode::GetLeftTopCorner(const BaseMapConfig& config,
416 const MapNodeIndex& index) {
417 Eigen::Vector2d coord;
418 coord[0] = config.map_range_.GetMinX() +
419 static_cast<float>(config.map_node_size_x_) *
420 config.map_resolutions_[index.resolution_id_] *
421 static_cast<float>(index.n_);
422 coord[1] = config.map_range_.GetMinY() +
423 static_cast<float>(config.map_node_size_y_) *
424 config.map_resolutions_[index.resolution_id_] *
425 static_cast<float>(index.m_);
426 DCHECK_LT(coord[0], config.map_range_.GetMaxX());
427 DCHECK_LT(coord[1], config.map_range_.GetMaxY());
428 return coord;
429}
430
432 char buf[1024];
433 std::string path = map_config_->map_folder_path_;
434 if (!EnsureDirectory(path)) {
435 return false;
436 }
437 path = path + "/image";
438 if (!EnsureDirectory(path)) {
439 return false;
440 }
441 snprintf(buf, sizeof(buf), "/%03u", index_.resolution_id_);
442 path = path + buf;
443 if (!EnsureDirectory(path)) {
444 return false;
445 }
446 if (index_.zone_id_ > 0) {
447 path = path + "/north";
448 } else {
449 path = path + "/south";
450 }
451 if (!EnsureDirectory(path)) {
452 return false;
453 }
454 snprintf(buf, sizeof(buf), "/%02d", abs(index_.zone_id_));
455 path = path + buf;
456 if (!EnsureDirectory(path)) {
457 return false;
458 }
459 snprintf(buf, sizeof(buf), "/%08u", index_.m_);
460 path = path + buf;
461 if (!EnsureDirectory(path)) {
462 return false;
463 }
464 snprintf(buf, sizeof(buf), "/%08u.png", index_.n_);
465 path = path + buf;
466 bool success0 = SaveIntensityImage(path);
467 return success0;
468}
469
470bool BaseMapNode::SaveIntensityImage(const std::string& path) const {
471 cv::Mat image;
473 bool success = cv::imwrite(path, image);
474 return success;
475}
476
477} // namespace msf
478} // namespace localization
479} // namespace apollo
The options of the reflectance map.
std::vector< float > map_resolutions_
The pixel resolutions in the map in meters.
std::string map_folder_path_
The map folder path.
Rect2D< double > map_range_
The minimum and maximum UTM range in the map.
unsigned int map_node_size_y_
The map node size in pixels.
unsigned int map_node_size_x_
The map node size in pixels.
The data structure of the map cells in a map node.
virtual unsigned int CreateBinary(unsigned char *buf, unsigned int buf_size) const =0
Create the binary.
virtual void GetIntensityImg(cv::Mat *intensity_img) const =0
get intensity image of node.
virtual void Reset(const BaseMapConfig *config)=0
Reset map cells data.
virtual unsigned int GetBinarySize() const =0
Get the binary size of the object.
virtual unsigned int LoadBinary(unsigned char *buf)=0
Load the map cell from a binary chunk.
virtual void Init(const BaseMapConfig *config)=0
Initialize the map matrix.
const Eigen::Vector2d & GetLeftTopCorner() const
Get the left top corner of the map node.
virtual unsigned int CreateBinary(FILE *file) const
Create the binary.
BaseMapMatrix * map_matrix_
The data structure of the map datas, which is a matrix.
virtual void Init(const BaseMapConfig *map_config, const MapNodeIndex &index, bool create_map_cells=true)
Initialize the map node.
MapNodeIndex index_
The index of this node.
unsigned int file_body_binary_size_
The body binary size in file.
BaseMapNode(BaseMapMatrix *matrix, CompressionStrategy *strategy)
Construct a map node.
virtual void ResetMapNode()
Reset map cells data.
virtual unsigned int LoadBinary(FILE *file)
Load the map cell from a binary chunk.
bool SaveIntensityImage() const
Save intensity image of node.
virtual unsigned int CreateHeaderBinary(unsigned char *buf, unsigned int buf_size) const
Create the binary header.
virtual void InitMapMatrix(const BaseMapConfig *map_config)
Initialize the map matrix.
bool is_changed_
Has the map node been changed.
virtual ~BaseMapNode()
Destruct a map node.
virtual void Finalize()
call before deconstruction or reset.
bool is_reserved_
If the node is reserved in map.
CompressionStrategy * compression_strategy_
@bried The compression strategy.
bool Load()
Load the map node from the disk.
bool Save()
Save the map node to the disk.
virtual unsigned int LoadHeaderBinary(unsigned char *buf)
Load the map node header from a binary chunk.
virtual unsigned int GetBodyBinarySize() const
Get the size of the body in bytes.
const BaseMapConfig * map_config_
The map settings.
virtual unsigned int LoadBodyBinary(std::vector< unsigned char > *buf)
Load the map node body from a binary chunk.
virtual unsigned int CreateBodyBinary(std::vector< unsigned char > *buf) const
Create the binary body.
Eigen::Vector2d left_top_corner_
The left top corner of the map node in the global coordinate system.
float GetMapResolution() const
Get the resolution of this map nodex.
virtual unsigned int GetBinarySize() const
Get the binary size of the object.
bool GetCoordinate(const Eigen::Vector2d &coordinate, unsigned int *x, unsigned int *y) const
Given the global coordinate, get the local 2D coordinate of the map cell matrix.
virtual unsigned int GetHeaderBinarySize() const
Get the size of the header in bytes.
virtual int Decode(BufferStr *buf, BufferStr *buf_uncompressed)=0
virtual int Encode(BufferStr *buf, BufferStr *buf_compressed)=0
unsigned int m_
The map node ID at the northing direction.
unsigned int n_
The map node ID at the easting direction.
unsigned int resolution_id_
The ID of the resolution.
T GetMaxY() const
Get the max y of the rectangle.
Definition rect2d.h:88
T GetMaxX() const
Get the max x of the rectangle.
Definition rect2d.h:83
T GetMinX() const
Get the min x of the rectangle.
Definition rect2d.h:73
T GetMinY() const
Get the min y of the rectangle.
Definition rect2d.h:78
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
bool DirectoryExists(const std::string &directory_path)
Check if the directory specified by directory_path exists and is indeed a directory.
Definition file.cc:207
bool EnsureDirectory(const std::string &directory_path)
Check if a specified directory specified by directory_path exists.
Definition file.cc:285
class register implement
Definition arena_queue.h:37