Apollo 11.0
自动驾驶开放平台
base_map.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 <vector>
20
21#include "cyber/common/log.h"
22#include "cyber/task/task.h"
24
25namespace apollo {
26namespace localization {
27namespace msf {
28
30 : map_config_(map_config),
31 map_node_cache_lvl1_(nullptr),
32 map_node_cache_lvl2_(nullptr),
33 map_node_pool_(nullptr) {}
34
38 map_node_cache_lvl1_ = nullptr;
39 }
42 map_node_cache_lvl2_ = nullptr;
43 }
44}
45
60
62 BaseMapNode* node = nullptr;
63 map_node_cache_lvl1_->Get(index, &node);
64 return node;
65}
66
68 BaseMapNode* node = nullptr;
69 // try get from cacheL1
70 if (map_node_cache_lvl1_->Get(index, &node)) {
71 return node;
72 }
73
74 // try get from cacheL2
75 boost::unique_lock<boost::recursive_mutex> lock(map_load_mutex_);
76 if (map_node_cache_lvl2_->Get(index, &node)) {
77 node->SetIsReserved(true);
78
79 map_node_cache_lvl1_->Put(index, node);
80 return node;
81 }
82 lock.unlock();
83
84 // load from disk
85 AERROR << "GetMapNodeSafe: This node don't exist in cache! ";
86 AERROR << "load this node from disk now! index = " << index;
87 LoadMapNodeThreadSafety(index, true);
88 boost::unique_lock<boost::recursive_mutex> lock2(map_load_mutex_);
89 map_node_cache_lvl2_->Get(index, &node);
90 lock2.unlock();
91
92 map_node_cache_lvl1_->Put(index, node);
93 return node;
94}
95
97bool BaseMap::IsMapNodeExist(const MapNodeIndex& index) const {
98 return map_node_cache_lvl1_->IsExist(index);
99}
100
101bool BaseMap::SetMapFolderPath(const std::string folder_path) {
102 map_config_->map_folder_path_ = folder_path;
103
104 // Try to load the config
105 std::string config_path = map_config_->map_folder_path_ + "/config.xml";
106 if (system::IsExists(config_path)) {
107 map_config_->Load(config_path);
108 return true;
109 } else {
110 return false;
111 }
112}
113
114void BaseMap::AddDataset(const std::string dataset_path) {
115 map_config_->map_datasets_.push_back(dataset_path);
116 std::string config_path = map_config_->map_folder_path_ + "/config.xml";
117 map_config_->Save(config_path);
118}
119
120void BaseMap::LoadMapNodes(std::set<MapNodeIndex>* map_ids) {
121 CHECK_LE(map_ids->size(), map_node_cache_lvl1_->Capacity());
122 // check in cacheL1
123 typename std::set<MapNodeIndex>::iterator itr = map_ids->begin();
124 while (itr != map_ids->end()) {
125 if (map_node_cache_lvl1_->IsExist(*itr)) {
126 // std::cout << "LoadMapNodes find in L1 cache" << std::endl;
127 boost::unique_lock<boost::recursive_mutex> lock(map_load_mutex_);
128 map_node_cache_lvl2_->IsExist(*itr); // fresh lru list
129 lock.unlock();
130 itr = map_ids->erase(itr);
131 } else {
132 ++itr;
133 }
134 }
135
136 // check in cacheL2
137 itr = map_ids->begin();
138 BaseMapNode* node = nullptr;
139 boost::unique_lock<boost::recursive_mutex> lock(map_load_mutex_);
140 while (itr != map_ids->end()) {
141 if (map_node_cache_lvl2_->Get(*itr, &node)) {
142 // std::cout << "LoadMapNodes find in L2 cache" << std::endl;
143 node->SetIsReserved(true);
144 map_node_cache_lvl1_->Put(*itr, node);
145 itr = map_ids->erase(itr);
146 } else {
147 ++itr;
148 }
149 }
150 lock.unlock();
151
152 // load from disk sync
153 std::vector<std::future<void>> load_futures;
154 itr = map_ids->begin();
155 while (itr != map_ids->end()) {
156 AERROR << "Preload map node failed!";
157 load_futures.emplace_back(
158 cyber::Async(&BaseMap::LoadMapNodeThreadSafety, this, *itr, true));
159 ++itr;
160 }
161
162 for (auto& future : load_futures) {
163 if (future.valid()) {
164 future.get();
165 }
166 }
167 // check in cacheL2 again
168 itr = map_ids->begin();
169 node = nullptr;
170 boost::unique_lock<boost::recursive_mutex> lock2(map_load_mutex_);
171 while (itr != map_ids->end()) {
172 if (map_node_cache_lvl2_->Get(*itr, &node)) {
173 AINFO << "LoadMapNodes: preload missed, load this node in main thread.\n"
174 << *itr;
175 node->SetIsReserved(true);
176 map_node_cache_lvl1_->Put(*itr, node);
177 itr = map_ids->erase(itr);
178 } else {
179 ++itr;
180 }
181 }
182 lock2.unlock();
183
184 ACHECK(map_ids->empty());
185}
186
187void BaseMap::PreloadMapNodes(std::set<MapNodeIndex>* map_ids) {
188 DCHECK_LE(map_ids->size(), map_node_cache_lvl2_->Capacity());
189 // check in cacheL2
190 typename std::set<MapNodeIndex>::iterator itr = map_ids->begin();
191 while (itr != map_ids->end()) {
192 boost::unique_lock<boost::recursive_mutex> lock(map_load_mutex_);
193 bool is_exist = map_node_cache_lvl2_->IsExist(*itr);
194 lock.unlock();
195 if (is_exist) {
196 itr = map_ids->erase(itr);
197 } else {
198 ++itr;
199 }
200 }
201
202 // check whether in already preloading index set
203 itr = map_ids->begin();
204 auto preloading_itr = map_preloading_task_index_.end();
205 while (itr != map_ids->end()) {
206 boost::unique_lock<boost::recursive_mutex> lock(map_load_mutex_);
207 preloading_itr = map_preloading_task_index_.find(*itr);
208 lock.unlock();
209 if (preloading_itr !=
210 map_preloading_task_index_.end()) { // already preloading
211 itr = map_ids->erase(itr);
212 } else {
213 ++itr;
214 }
215 }
216
217 // load form disk sync
218 std::vector<std::future<void>> preload_futures;
219 itr = map_ids->begin();
220 AINFO << "Preload map node size: " << map_ids->size();
221 while (itr != map_ids->end()) {
222 AINFO << "Preload map node: " << *itr << std::endl;
223 boost::unique_lock<boost::recursive_mutex> lock3(map_load_mutex_);
224 map_preloading_task_index_.insert(*itr);
225 lock3.unlock();
226 preload_futures.emplace_back(
227 cyber::Async(&BaseMap::LoadMapNodeThreadSafety, this, *itr, false));
228 ++itr;
229 }
230}
231
233 map_node_pool_ = map_node_pool;
234}
235
236void BaseMap::LoadMapNodeThreadSafety(MapNodeIndex index, bool is_reserved) {
237 BaseMapNode* map_node = nullptr;
238 while (map_node == nullptr) {
239 map_node = map_node_pool_->AllocMapNode();
240 if (map_node == nullptr) {
241 boost::unique_lock<boost::recursive_mutex> lock(map_load_mutex_);
242 BaseMapNode* node_remove = map_node_cache_lvl2_->ClearOne();
243 if (node_remove) {
244 map_node_pool_->FreeMapNode(node_remove);
245 }
246 }
247 }
248 map_node->Init(map_config_, index, false);
249 if (!map_node->Load()) {
250 AERROR << "Created map node: " << index;
251 } else {
252 AERROR << " Loaded map node: " << index;
253 }
254 map_node->SetIsReserved(is_reserved);
255
256 boost::unique_lock<boost::recursive_mutex> lock(map_load_mutex_);
257 BaseMapNode* node_remove = map_node_cache_lvl2_->Put(index, map_node);
258 // if the node already added into cacheL2, erase it from preloading set
259 auto itr = map_preloading_task_index_.find(index);
260 if (itr != map_preloading_task_index_.end()) {
262 }
263 if (node_remove) {
264 map_node_pool_->FreeMapNode(node_remove);
265 }
266}
267
268void BaseMap::PreloadMapArea(const Eigen::Vector3d& location,
269 const Eigen::Vector3d& trans_diff,
270 unsigned int resolution_id, unsigned int zone_id) {
271 CHECK_NOTNULL(map_node_pool_);
272
273 int x_direction = trans_diff[0] > 0 ? 1 : -1;
274 int y_direction = trans_diff[1] > 0 ? 1 : -1;
275
276 std::set<MapNodeIndex> map_ids;
277 float map_pixel_resolution =
278 this->map_config_->map_resolutions_[resolution_id];
280 Eigen::Vector3d pt_top_left;
281 pt_top_left[0] =
282 location[0] - (static_cast<float>(this->map_config_->map_node_size_x_) *
283 map_pixel_resolution / 2.0f);
284 pt_top_left[1] =
285 location[1] - (static_cast<float>(this->map_config_->map_node_size_y_) *
286 map_pixel_resolution / 2.0f);
287 pt_top_left[2] = 0;
289 *(this->map_config_), pt_top_left, resolution_id, zone_id);
290 map_ids.insert(map_id);
291
293 Eigen::Vector3d pt_top_center;
294 pt_top_center[0] = location[0];
295 pt_top_center[1] = pt_top_left[1];
296 pt_top_center[2] = 0;
297 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt_top_center,
298 resolution_id, zone_id);
299 map_ids.insert(map_id);
300
302 Eigen::Vector3d pt_top_right;
303 pt_top_right[0] =
304 location[0] + (static_cast<float>(this->map_config_->map_node_size_x_) *
305 map_pixel_resolution / 2.0);
306 pt_top_right[1] = pt_top_left[1];
307 pt_top_right[2] = 0;
308 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt_top_right,
309 resolution_id, zone_id);
310 map_ids.insert(map_id);
311
313 Eigen::Vector3d pt_middle_left;
314 pt_middle_left[0] = pt_top_left[0];
315 pt_middle_left[1] = location[1];
316 pt_middle_left[2] = 0;
317 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt_middle_left,
318 resolution_id, zone_id);
319 map_ids.insert(map_id);
320
322 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), location,
323 resolution_id, zone_id);
324 map_ids.insert(map_id);
325
327 Eigen::Vector3d pt_middle_right;
328 pt_middle_right[0] = pt_top_right[0];
329 pt_middle_right[1] = pt_middle_left[1];
330 pt_middle_right[2] = 0;
331 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt_middle_right,
332 resolution_id, zone_id);
333 map_ids.insert(map_id);
334
336 Eigen::Vector3d pt_bottom_left;
337 pt_bottom_left[0] = pt_top_left[0];
338 pt_bottom_left[1] =
339 location[1] + (static_cast<float>(this->map_config_->map_node_size_y_) *
340 map_pixel_resolution / 2.0);
341 pt_bottom_left[2] = 0;
342 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt_bottom_left,
343 resolution_id, zone_id);
344 map_ids.insert(map_id);
345
347 Eigen::Vector3d pt_bottom_center;
348 pt_bottom_center[0] = pt_top_center[0];
349 pt_bottom_center[1] = pt_bottom_left[1];
350 pt_bottom_center[2] = 0;
351 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt_bottom_center,
352 resolution_id, zone_id);
353 map_ids.insert(map_id);
354
356 Eigen::Vector3d pt_bottom_right;
357 pt_bottom_right[0] = pt_top_right[0];
358 pt_bottom_right[1] = pt_bottom_left[1];
359 pt_bottom_right[2] = 0;
360 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt_bottom_right,
361 resolution_id, zone_id);
362 map_ids.insert(map_id);
363
364 for (int i = -1; i < 2; ++i) {
365 Eigen::Vector3d pt;
366 pt[0] = location[0] + x_direction * 1.5 *
368 map_pixel_resolution;
369 pt[1] = location[1] + static_cast<double>(i) *
371 map_pixel_resolution;
372 pt[2] = 0;
373 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt,
374 resolution_id, zone_id);
375 map_ids.insert(map_id);
376 }
377 for (int i = -1; i < 2; ++i) {
378 Eigen::Vector3d pt;
379 pt[0] = location[0] + static_cast<double>(i) *
381 map_pixel_resolution;
382 pt[1] = location[1] + y_direction * 1.5 *
384 map_pixel_resolution;
385 pt[2] = 0;
386 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt,
387 resolution_id, zone_id);
388 map_ids.insert(map_id);
389 }
390 {
391 Eigen::Vector3d pt;
392 pt[0] = location[0] + x_direction * 1.5 *
394 map_pixel_resolution;
395 pt[1] = location[1] + y_direction * 1.5 *
397 map_pixel_resolution;
398 pt[2] = 0;
399 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt,
400 resolution_id, zone_id);
401 map_ids.insert(map_id);
402 }
403
404 this->PreloadMapNodes(&map_ids);
405}
406
407bool BaseMap::LoadMapArea(const Eigen::Vector3d& seed_pt3d,
408 unsigned int resolution_id, unsigned int zone_id,
409 int filter_size_x, int filter_size_y) {
410 CHECK_NOTNULL(map_node_pool_);
411 std::set<MapNodeIndex> map_ids;
412 float map_pixel_resolution =
413 this->map_config_->map_resolutions_[resolution_id];
415 Eigen::Vector3d pt_top_left;
416 pt_top_left[0] = seed_pt3d[0] -
417 (static_cast<float>(this->map_config_->map_node_size_x_) *
418 map_pixel_resolution / 2.0f) -
419 static_cast<float>(filter_size_x / 2) * map_pixel_resolution;
420 pt_top_left[1] = seed_pt3d[1] -
421 (static_cast<float>(this->map_config_->map_node_size_y_) *
422 map_pixel_resolution / 2.0f) -
423 static_cast<float>(filter_size_y / 2) * map_pixel_resolution;
424 pt_top_left[2] = 0;
426 *(this->map_config_), pt_top_left, resolution_id, zone_id);
427 map_ids.insert(map_id);
428
430 Eigen::Vector3d pt_top_center;
431 pt_top_center[0] = seed_pt3d[0];
432 pt_top_center[1] = pt_top_left[1];
433 pt_top_center[2] = 0;
434 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt_top_center,
435 resolution_id, zone_id);
436 map_ids.insert(map_id);
437
439 Eigen::Vector3d pt_top_right;
440 pt_top_right[0] =
441 seed_pt3d[0] +
442 (static_cast<float>(this->map_config_->map_node_size_x_) *
443 map_pixel_resolution / 2.0f) +
444 static_cast<float>(filter_size_x / 2) * map_pixel_resolution;
445 pt_top_right[1] = pt_top_left[1];
446 pt_top_left[2] = 0;
447 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt_top_right,
448 resolution_id, zone_id);
449 map_ids.insert(map_id);
450
452 Eigen::Vector3d pt_middle_left;
453 pt_middle_left[0] = pt_top_left[0];
454 pt_middle_left[1] = seed_pt3d[1];
455 pt_middle_left[2] = 0;
456 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt_middle_left,
457 resolution_id, zone_id);
458 map_ids.insert(map_id);
459
461 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), seed_pt3d,
462 resolution_id, zone_id);
463 map_ids.insert(map_id);
464
466 Eigen::Vector3d pt_middle_right;
467 pt_middle_right[0] = pt_top_right[0];
468 pt_middle_right[1] = seed_pt3d[1];
469 pt_middle_right[2] = 0;
470 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt_middle_right,
471 resolution_id, zone_id);
472 map_ids.insert(map_id);
473
475 Eigen::Vector3d pt_bottom_left;
476 pt_bottom_left[0] = pt_top_left[0];
477 pt_bottom_left[1] =
478 seed_pt3d[1] +
479 (static_cast<float>(this->map_config_->map_node_size_y_) *
480 map_pixel_resolution / 2.0f) +
481 static_cast<float>(filter_size_y / 2) * map_pixel_resolution;
482 pt_bottom_left[2] = 0;
483 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt_bottom_left,
484 resolution_id, zone_id);
485 map_ids.insert(map_id);
486
488 Eigen::Vector3d pt_bottom_center;
489 pt_bottom_center[0] = seed_pt3d[0];
490 pt_bottom_center[1] = pt_bottom_left[1];
491 pt_bottom_center[2] = 0;
492 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt_bottom_center,
493 resolution_id, zone_id);
494 map_ids.insert(map_id);
495
497 Eigen::Vector3d pt_bottom_right;
498 pt_bottom_right[0] = pt_top_right[0];
499 pt_bottom_right[1] = pt_bottom_left[1];
500 pt_bottom_right[2] = 0;
501 map_id = MapNodeIndex::GetMapNodeIndex(*(this->map_config_), pt_bottom_right,
502 resolution_id, zone_id);
503 map_ids.insert(map_id);
504
505 this->LoadMapNodes(&map_ids);
506 return true;
507}
508
509} // namespace msf
510} // namespace localization
511} // namespace apollo
The options of the reflectance map.
std::vector< float > map_resolutions_
The pixel resolutions in the map in meters.
std::vector< std::string > map_datasets_
The datasets that contributed to the map.
bool Load(const std::string file_path)
Load the map option from a XML file.
std::string map_folder_path_
The map folder path.
bool Save(const std::string file_path)
Save the map option to a XML file.
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 memory pool for the data structure of BaseMapNode.
BaseMapNode * AllocMapNode()
Get a MapNode object from memory pool.
void FreeMapNode(BaseMapNode *map_node)
Release MapNode object to memory pool.
The data structure of a Node in the map.
virtual void Init(const BaseMapConfig *map_config, const MapNodeIndex &index, bool create_map_cells=true)
Initialize the map node.
bool Load()
Load the map node from the disk.
void SetIsReserved(bool is_reserved)
Set if the map node is reserved.
void AddDataset(const std::string dataset_path)
Add a dataset path to the map config.
Definition base_map.cc:114
virtual bool LoadMapArea(const Eigen::Vector3d &seed_pt3d, unsigned int resolution_id, unsigned int zone_id, int filter_size_x, int filter_size_y)
Load map nodes for the location calculate of this frame.
Definition base_map.cc:407
virtual ~BaseMap()
The destructor.
Definition base_map.cc:35
BaseMapConfig * map_config_
The map settings.
Definition base_map.h:105
MapNodeCache< MapNodeIndex, BaseMapNode >::DestroyFunc destroy_func_lvl2_
Definition base_map.h:110
virtual void InitMapNodeCaches(int cacheL1_size, int cahceL2_size)
Init load threadpool and preload threadpool.
Definition base_map.cc:46
void AttachMapNodePool(BaseMapNodePool *p_map_node_pool)
Attach map node pointer.
Definition base_map.cc:232
boost::recursive_mutex map_load_mutex_
The mutex for preload map node.
Definition base_map.h:120
bool SetMapFolderPath(const std::string folder_path)
Set the directory of the map.
Definition base_map.cc:101
MapNodeCache< MapNodeIndex, BaseMapNode > * map_node_cache_lvl2_
brief The dynamic map node preloading thread pool pointer.
Definition base_map.h:114
void LoadMapNodes(std::set< MapNodeIndex > *map_ids)
Load map node by index.
Definition base_map.cc:120
std::set< MapNodeIndex > map_preloading_task_index_
@bried Keep the index of preloading nodes.
Definition base_map.h:118
void PreloadMapNodes(std::set< MapNodeIndex > *map_ids)
Load map node by index.
Definition base_map.cc:187
BaseMapNodePool * map_node_pool_
The map node memory pool pointer.
Definition base_map.h:116
bool IsMapNodeExist(const MapNodeIndex &index) const
Check if the map node in the cache.
Definition base_map.cc:97
BaseMap(BaseMapConfig *map_config)
The constructor.
Definition base_map.cc:29
BaseMapNode * GetMapNodeSafe(const MapNodeIndex &index)
Return the map node, if it's not in the cache, safely load it.
Definition base_map.cc:67
void LoadMapNodeThreadSafety(MapNodeIndex index, bool is_reserved=false)
Load map node by index, thread_safety.
Definition base_map.cc:236
MapNodeCache< MapNodeIndex, BaseMapNode >::DestroyFunc destroy_func_lvl1_
Definition base_map.h:109
virtual void PreloadMapArea(const Eigen::Vector3d &location, const Eigen::Vector3d &trans_diff, unsigned int resolution_id, unsigned int zone_id)
Preload map nodes for the next frame location calculation.
Definition base_map.cc:268
MapNodeCache< MapNodeIndex, BaseMapNode > * map_node_cache_lvl1_
The cache for map node preload.
Definition base_map.h:112
BaseMapNode * GetMapNode(const MapNodeIndex &index)
Get the map node, if it's not in the cache, return false.
Definition base_map.cc:61
The data structure of the LRUCache.
static MapNodeIndex GetMapNodeIndex(const BaseMapConfig &option, const Eigen::Vector3d &coordinate, unsigned int resolution_id, int zone_id)
Construct a map node index, given a global coordinate, eigen version.
static bool IsExists(const std::string &path)
Determine if the file or directory exists.
#define ACHECK(cond)
Definition log.h:80
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
class register implement
Definition arena_queue.h:37