21#include <boost/filesystem.hpp>
27namespace localization {
33#define PI 3.1415926535897932346
35unsigned char color_table[3][3] = {{0, 0, 255}, {0, 255, 0}, {255, 0, 0}};
38 "modules/localization/msf/local_tool/local_visualization/img/red_car.png",
39 "modules/localization/msf/local_tool/local_visualization/img/green_car.png",
40 "modules/localization/msf/local_tool/local_visualization/img/blue_car.png"};
52 auto found_iter = _map.find(key);
53 if (found_iter == _map.end()) {
57 _list.splice(_list.begin(), _list, found_iter->second);
58 *image = found_iter->second->second;
63 auto found_iter = _map.find(key);
64 if (found_iter != _map.end()) {
66 _list.splice(_list.begin(), _list, found_iter->second);
67 found_iter->second->second = image;
71 if (_map.size() == _capacity) {
73 _list.back().second.release();
75 _map.erase(key_to_del);
77 _list.emplace_front(key, image);
78 _map[key] = _list.begin();
83 : map_image_cache_(20),
84 image_window_(1024, 1024, CV_8UC3, cv::Scalar(0, 0, 0)),
85 big_window_(3072, 3072, CV_8UC3),
86 tips_window_(48, 1024, CV_8UC3, cv::Scalar(0, 0, 0)) {}
89 const std::string &map_visual_folder,
91 const unsigned int resolution_id,
93 const Eigen::Affine3d &extrinsic,
94 const unsigned int loc_info_num) {
95 map_folder_ = map_folder;
96 map_visual_folder_ = map_visual_folder;
97 map_param_ = map_param;
98 velodyne_extrinsic_ = extrinsic;
99 loc_info_num_ = loc_info_num;
100 expected_car_loc_id_ = loc_info_num;
102 trajectory_groups_.resize(loc_info_num_);
104 for (
unsigned int i = 0; i < loc_info_num_; i++) {
106 if (tem_mat.empty()) {
107 is_draw_car_ =
false;
110 car_img_mats_.push_back(tem_mat);
114 AERROR <<
"Invalid resolution id.";
119 resolution_id_ = resolution_id;
128 Preprocess(map_folder, map_visual_folder);
130 std::string params_file = image_visual_resolution_path_ +
"/param.txt";
131 bool success = InitOtherParams(params_file);
133 AERROR <<
"Init other params failed.";
136 cv::namedWindow(window_name_, cv::WINDOW_NORMAL);
137 cv::resizeWindow(window_name_, 1024, 1024);
146 const ::apollo::common::EigenVector3dVec &cloud) {
148 AERROR <<
"Visualziation should be init first.";
152 if (loc_infos.size() != loc_info_num_) {
153 AERROR <<
"Please check the localization info num.";
157 cur_loc_infos_ = std::move(loc_infos);
159 if (!UpdateCarLocId(expected_car_loc_id_)) {
160 if (!UpdateCarLocId(car_loc_id_)) {
161 if (!UpdateCarLocId()) {
165 if (expected_car_loc_id_ == loc_info_num_) {
166 expected_car_loc_id_ = car_loc_id_;
171 UpdateTrajectoryGroups();
177 auto_play_ = auto_play;
180void VisualizationEngine::Preprocess(
const std::string &map_folder,
181 const std::string &map_visual_folder) {
182 std::string image_path = map_folder_ +
"/image";
183 std::string image_visual_path = map_visual_folder;
185 snprintf(buf,
sizeof(buf),
"/%03u", resolution_id_);
186 image_visual_resolution_path_ = image_visual_path + buf;
187 AINFO <<
"image_visual_resolution_path: " << image_visual_resolution_path_;
188 std::string image_resolution_path = image_path + buf;
189 AINFO <<
"image_resolution_path: " << image_resolution_path;
191 if (!EnsureDirectory(image_visual_path)) {
192 AERROR <<
"image_visual_path: " << image_visual_path
193 <<
" cannot be created.";
197 if (DirectoryExists(image_visual_resolution_path_)) {
198 AINFO <<
"image_visual_resolution_path: " << image_visual_resolution_path_
199 <<
"already exists.";
202 if (!EnsureDirectory(image_visual_resolution_path_)) {
203 AERROR <<
"image_visual_resolution_path: " << image_visual_resolution_path_
204 <<
" cannot be created.";
208 boost::filesystem::path image_resolution_path_boost(image_resolution_path);
210 std::vector<std::string> map_bin_path;
211 boost::filesystem::recursive_directory_iterator end_iter;
212 boost::filesystem::recursive_directory_iterator iter(
213 image_resolution_path_boost);
214 for (; iter != end_iter; ++iter) {
215 if (!boost::filesystem::is_directory(*iter)) {
216 if (iter->path().extension() ==
".png") {
217 map_bin_path.push_back(iter->path().string());
220 std::string tmp = iter->path().string();
221 tmp = tmp.substr(image_resolution_path.length(), tmp.length());
222 tmp = image_visual_resolution_path_ + tmp;
227 if (map_bin_path.empty()) {
231 GenerateMutiResolutionImages(map_bin_path,
232 static_cast<int>(image_resolution_path.length()),
233 image_visual_resolution_path_);
236void VisualizationEngine::Draw() {
240 SetViewCenter(car_pose_.translation()[0], car_pose_.translation()[1]);
243 MapImageKey iamge_key;
244 CoordToImageKey(_view_center, &iamge_key);
247 for (
int i = -1; i <= 1; ++i) {
248 for (
int j = -1; j <= 1; ++j) {
249 MapImageKey key = iamge_key;
250 key.node_north_id += i * cur_stride_;
251 key.node_east_id += j * cur_stride_;
252 if (LoadImageToCache(key)) {
253 map_image_cache_.
Get(key, &subMat_[i + 1][j + 1]);
255 subMat_[i + 1][j + 1] =
256 cv::Mat(1024, 1024, CV_8UC3, cv::Scalar(0, 0, 0));
261 for (
int i = 0; i < 3; ++i) {
262 for (
int j = 0; j < 3; ++j) {
263 subMat_[i][j].copyTo(
264 big_window_(cv::Rect(j * 1024, i * 1024, 1024, 1024)));
268 cv::Point map_grid_index =
269 CoordToMapGridIndex(_view_center, resolution_id_, cur_stride_);
270 cv::Point node_grid_index = MapGridIndexToNodeGridIndex(map_grid_index);
271 cv::Point bias = node_grid_index - map_grid_index;
273 DrawTrajectory(bias);
278 int width =
static_cast<int>(1024 * cur_scale_) / cur_stride_;
280 int left_top_x = node_grid_index.x + 1024 - dis;
281 int left_top_y = node_grid_index.y + 1024 - dis;
283 cv::resize(big_window_(cv::Rect(left_top_x, left_top_y, width, width)),
284 image_window_, cv::Size(1024, 1024), 0, 0, cv::INTER_LINEAR);
285 cv::flip(image_window_, image_window_, 0);
291 cv::namedWindow(window_name_, cv::WINDOW_NORMAL);
293 cv::imshow(window_name_, image_window_);
299 ProcessKey(cv::waitKey(waitTime));
302void VisualizationEngine::DrawTrajectory(
const cv::Point &bias) {
303 AINFO <<
"Draw trajectory.";
304 if (cur_level_ == 0 && is_draw_trajectory_) {
305 unsigned int i = (car_loc_id_ + 1) % loc_info_num_;
306 for (
unsigned int k = 0; k < loc_info_num_; k++) {
307 std::map<double, Eigen::Vector2d> &trj = trajectory_groups_[i];
309 i = (i + 1) % loc_info_num_;
315 std::map<double, Eigen::Vector2d>::iterator iter = trj.end();
317 const Eigen::Vector2d &loc_2d = iter->second;
318 lt = CoordToMapGridIndex(loc_2d, resolution_id_, cur_stride_);
319 lt = lt + bias + cv::Point(1024, 1024);
321 if (lt.x >= 0 && lt.y >= 0 && lt.x < 1024 * 3 && lt.y < 1024 * 3) {
325 cv::circle(big_window_, lt, 4, cv::Scalar(b, g, r), 1);
329 while (iter != trj.begin() && count < 500) {
331 const Eigen::Vector2d &loc_2d = iter->second;
332 lt = CoordToMapGridIndex(loc_2d, resolution_id_, cur_stride_);
333 lt = lt + bias + cv::Point(1024, 1024);
335 if (lt.x >= 0 && lt.y >= 0 && lt.x < 1024 * 3 && lt.y < 1024 * 3) {
340 cv::circle(big_window_, lt, 3, cv::Scalar(b, g, r), 1);
341 cv::line(big_window_, pre_lt, lt, cv::Scalar(b, g, r), 1);
349 i = (i + 1) % loc_info_num_;
354void VisualizationEngine::DrawLoc(
const cv::Point &bias) {
355 AINFO <<
"Draw loc.";
356 if (cur_level_ == 0) {
357 unsigned int i = (car_loc_id_ + 1) % loc_info_num_;
358 for (
unsigned int k = 0; k < loc_info_num_; k++) {
359 LocalizatonInfo &loc_info = cur_loc_infos_[i];
361 const Eigen::Translation3d &loc = loc_info.location;
363 Eigen::Vector2d loc_2d;
367 lt = CoordToMapGridIndex(loc_2d, resolution_id_, cur_stride_);
368 lt = lt + bias + cv::Point(1024, 1024);
370 if (lt.x >= 0 && lt.y >= 0 && lt.x < 1024 * 3 && lt.y < 1024 * 3) {
371 if (is_draw_car_ && loc_info.is_has_attitude) {
372 const Eigen::Quaterniond &quatd = loc_info.attitude;
373 double quaternion[] = {quatd.w(), quatd.x(), quatd.y(), quatd.z()};
374 double euler_angle[3] = {0};
375 QuaternionToEuler(quaternion, euler_angle);
376 euler_angle[0] = euler_angle[0] * 180 /
PI;
377 euler_angle[1] = euler_angle[1] * 180 /
PI;
378 euler_angle[2] = euler_angle[2] * 180 /
PI;
382 double yaw = euler_angle[2];
385 cv::resize(car_img_mats_[i], mat_tem, cv::Size(48, 24), 0, 0,
392 RotateImg(mat_tem, &rotated_mat, yaw - 90);
394 lt - cv::Point(rotated_mat.cols / 2, rotated_mat.rows / 2);
396 car_lt + cv::Point(rotated_mat.cols, rotated_mat.rows);
397 if (car_lt.x >= 0 && car_lt.y >= 0 && car_rb.x <= 1024 * 3 &&
398 car_rb.y <= 1024 * 3) {
400 cv::cvtColor(rotated_mat, mat_mask, cv::COLOR_BGR2GRAY);
402 big_window_(cv::Rect(car_lt.x, car_lt.y, rotated_mat.cols,
410 cv::circle(big_window_, lt, 4, cv::Scalar(b, g, r), 1);
414 i = (i + 1) % loc_info_num_;
419void VisualizationEngine::DrawStd(
const cv::Point &bias) {
420 AINFO <<
"Draw std.";
421 if (cur_level_ == 0 && is_draw_std_) {
422 unsigned int i = (car_loc_id_ + 1) % loc_info_num_;
423 for (
unsigned int k = 0; k < loc_info_num_; k++) {
424 LocalizatonInfo &loc_info = cur_loc_infos_[i];
425 if (loc_info.is_has_std) {
427 const Eigen::Translation3d &loc = loc_info.location;
428 const Eigen::Vector3d &
std = loc_info.std_var;
429 Eigen::Vector2d loc_2d;
433 lt = CoordToMapGridIndex(loc_2d, resolution_id_, cur_stride_);
434 lt = lt + bias + cv::Point(1024, 1024);
436 if (lt.x >= 0 && lt.y >= 0 && lt.x < 1024 * 3 && lt.y < 1024 * 3) {
441 cv::Size size(
static_cast<int>(std::sqrt(
std[0]) * 200.0 + 1.0),
442 static_cast<int>(std::sqrt(
std[1]) * 200.0 + 1.0));
443 cv::ellipse(big_window_, lt, size, 0, 0, 360, cv::Scalar(b, g, r), 2,
448 i = (i + 1) % loc_info_num_;
453void VisualizationEngine::DrawCloud(
const cv::Point &bias) {
454 if (!cur_loc_infos_[car_loc_id_].is_has_attitude) {
458 AINFO <<
"Draw cloud.";
459 if (cur_level_ == 0) {
460 CloudToMat(car_pose_, velodyne_extrinsic_, cloud_, &cloud_img_,
463 lt = CoordToMapGridIndex(cloud_img_lt_coord_, resolution_id_, cur_stride_);
464 lt = lt + bias + cv::Point(1024, 1024);
466 cv::Point rb = lt + cv::Point(1024, 1024);
467 if (lt.x >= 0 && lt.y >= 0 && rb.x <= 1024 * 3 && rb.y <= 1024 * 3) {
468 cloud_img_.copyTo(big_window_(cv::Rect(lt.x, lt.y, 1024, 1024)),
475void VisualizationEngine::DrawLegend() {
476 AINFO <<
"Draw legend.";
477 int fontFace = cv::FONT_HERSHEY_SIMPLEX;
478 double fontScale = 0.6;
483 for (
unsigned int i = 0; i < loc_info_num_; i++) {
484 LocalizatonInfo &loc_info = cur_loc_infos_[i];
485 if (!loc_info.is_valid) {
489 std::string text = loc_info.description;
490 textSize = cv::getTextSize(text, fontFace, fontScale, thickness, &baseline);
491 cv::Point textOrg(790, (15 + textSize.height) * (i + 1));
492 cv::putText(image_window_, text, textOrg, fontFace, fontScale,
493 cv::Scalar(255, 0, 0), thickness, 8);
500 cv::Point(755, (15 + textSize.height) * (i + 1) - textSize.height / 2),
501 8, cv::Scalar(b, g, r), 3);
505void VisualizationEngine::DrawInfo() {
506 AINFO <<
"Draw info.";
507 LocalizatonInfo &loc_info = cur_loc_infos_[car_loc_id_];
509 int fontFace = cv::FONT_HERSHEY_SIMPLEX;
510 double fontScale = 0.8;
519 snprintf(info,
sizeof(info),
"Frame: %d.", loc_info.frame_id);
521 textSize = cv::getTextSize(text, fontFace, fontScale, thickness, &baseline);
522 cv::Point textOrg(10, 10 + textSize.height);
523 cv::putText(image_window_, text, textOrg, fontFace, fontScale,
524 cv::Scalar(255, 0, 0), thickness, 8);
527 snprintf(info,
sizeof(info),
"Timestamp: %lf.", loc_info.timestamp);
529 textSize = cv::getTextSize(text, fontFace, fontScale, thickness, &baseline);
530 textOrg = cv::Point(10, 2 * (10 + textSize.height));
531 cv::putText(image_window_, text, textOrg, fontFace, fontScale,
532 cv::Scalar(255, 0, 0), thickness, 8);
535void VisualizationEngine::DrawTips() {
536 AINFO <<
"Draw tips.";
538 tips_window_.setTo(cv::Scalar(0, 0, 0));
540 int fontFace = cv::FONT_HERSHEY_SIMPLEX;
541 double fontScale = 0.5;
550 snprintf(info,
sizeof(info),
551 "e: zoom out; q: zoom in; m: max scale; n: origin scale; w: up; s: "
552 "down; a: move left; d: move right; r: move center");
554 textSize = cv::getTextSize(text, fontFace, fontScale, thickness, &baseline);
555 cv::Point textOrg(5, 5 + textSize.height);
556 cv::putText(tips_window_, text, textOrg, fontFace, fontScale,
557 cv::Scalar(255, 255, 255), thickness, 8);
559 snprintf(info,
sizeof(info),
560 "f: follow car/free view; p: play/pause; c: change current loc; 1: "
561 "draw car/not; 2: draw trajectory/not; others: next");
563 textSize = cv::getTextSize(text, fontFace, fontScale, thickness, &baseline);
564 textOrg = cv::Point(5, 2 * (5 + textSize.height));
565 cv::putText(tips_window_, text, textOrg, fontFace, fontScale,
566 cv::Scalar(255, 255, 255), thickness, 8);
568 tips_window_.copyTo(image_window_(cv::Rect(0, 976, 1024, 48)));
571void VisualizationEngine::UpdateLevel() {
572 if (cur_scale_ > max_stride_ * 1.5) {
573 SetScale(max_stride_ * 1.5);
575 if (cur_scale_ < 0.5) {
581 double radius = cur_scale_ / 2;
582 while (radius >= 1.0) {
589void VisualizationEngine::GenerateMutiResolutionImages(
590 const std::vector<std::string> &src_files,
const int base_path_length,
591 const std::string &dst_folder) {
592 int x_min = std::numeric_limits<int>::max();
594 int y_min = std::numeric_limits<int>::max();
596 for (
size_t i = 0; i < src_files.size(); ++i) {
597 int len =
static_cast<int>(src_files[i].length());
599 int y = std::stoi(src_files[i].substr(len - 21, 8));
600 int x = std::stoi(src_files[i].substr(len - 12, 8));
602 x_min = x < x_min ? x : x_min;
603 x_max = x > x_max ? x : x_max;
604 y_min = y < y_min ? y : y_min;
605 y_max = y > y_max ? y : y_max;
613 while (range < x_max - x_min || range < y_max - y_min) {
619 for (
unsigned int i = 0; i < src_files.size(); i++) {
620 std::string p = src_files[i].substr(
621 base_path_length, src_files[i].length() - 4 - base_path_length);
623 cv::Mat tmp = cv::imread(src_files[i]);
624 cv::imwrite(p +
"_0.png", tmp);
628 std::string image_visual_path_dst = src_files[0].substr(
629 base_path_length, src_files[0].length() - 22 - base_path_length);
630 image_visual_path_dst = dst_folder + image_visual_path_dst;
635 for (
int lvl = 1; lvl < level; lvl++) {
636 int nstep = 2 * step;
637 for (pt_x = x_min; pt_x < x_max; pt_x += nstep) {
638 for (pt_y = y_min; pt_y < y_max; pt_y += nstep) {
642 cv::Mat large(2048, 2048, CV_8UC3, cv::Scalar(0, 0, 0));
645 for (
int i = 0; i < 2; i++) {
646 for (
int j = 0; j < 2; j++) {
647 snprintf(ss,
sizeof(ss),
"%s/%08d/%08d_%d.png",
648 image_visual_path_dst.c_str(), pt_y + i * step,
649 pt_x + j * step, lvl - 1);
652 cv::Mat img = cv::imread(ss);
653 img.copyTo(large(cv::Rect(j * 1024, i * 1024, 1024, 1024)));
658 snprintf(ss,
sizeof(ss),
"%s/%08d/%08d_%d.png",
659 image_visual_path_dst.c_str(), pt_y, pt_x, lvl);
660 cv::resize(large, small, cv::Size(1024, 1024), 0, 0,
662 cv::imwrite(ss, small);
670 std::fstream outf(dst_folder +
"/param.txt", std::ios::out);
671 outf << x_min <<
" " << y_min << std::endl;
672 outf << x_max <<
" " << y_max << std::endl;
673 outf << level << std::endl;
674 outf << image_visual_path_dst.substr(
676 image_visual_path_dst.length() - dst_folder.length() - 3)
681bool VisualizationEngine::InitOtherParams(
const std::string ¶ms_file) {
687 std::string path =
"";
689 std::ifstream inf(params_file);
690 if (!inf.is_open()) {
691 AERROR <<
"Open params file failed.";
695 inf >> x_min >> y_min >> x_max >> y_max >> level >> path;
702 InitOtherParams(x_min, y_min, x_max, y_max, level, path);
707void VisualizationEngine::InitOtherParams(
const int x_min,
const int y_min,
708 const int x_max,
const int y_max,
710 const std::string &path) {
711 lt_node_index_.x = x_min;
712 lt_node_index_.y = y_min;
716 double init_center_x = (
static_cast<double>(x_max + x_min) / 2 *
720 double init_center_y = (
static_cast<double>(y_max + y_min) / 2 *
724 SetViewCenter(init_center_x, init_center_y);
727 for (
int i = 1; i < level; ++i) {
731 image_visual_leaf_path_ = image_visual_resolution_path_ + path;
732 AINFO <<
"image_visual_leaf_path: " << image_visual_leaf_path_;
735void VisualizationEngine::CloudToMat(
736 const Eigen::Affine3d &cur_pose,
const Eigen::Affine3d &velodyne_extrinsic,
737 const ::apollo::common::EigenVector3dVec &cloud, cv::Mat *cloud_img,
738 cv::Mat *cloud_img_mask) {
741 Eigen::Vector3d cen = car_pose_.translation();
742 cloud_img_lt_coord_[0] = cen[0] - map_param_.
map_resolutions[resolution_id_] *
743 (
static_cast<float>(img_width) / 2.0f);
744 cloud_img_lt_coord_[1] = cen[1] - map_param_.
map_resolutions[resolution_id_] *
745 (
static_cast<float>(img_height) / 2.0f);
747 cloud_img_.setTo(cv::Scalar(0, 0, 0));
748 cloud_img_mask_.setTo(cv::Scalar(0));
750 for (
unsigned int i = 0; i < cloud.size(); i++) {
751 const Eigen::Vector3d &pt = cloud[i];
752 Eigen::Vector3d pt_global = cur_pose * velodyne_extrinsic * pt;
754 int col =
static_cast<int>((pt_global[0] - cloud_img_lt_coord_[0]) /
756 int row =
static_cast<int>((pt_global[1] - cloud_img_lt_coord_[1]) /
758 if (col < 0 || row < 0 ||
767 cloud_img->at<cv::Vec3b>(row, col) = cv::Vec3b(b, g, r);
768 cloud_img_mask->at<
unsigned char>(row, col) = 1;
772void VisualizationEngine::CoordToImageKey(
const Eigen::Vector2d &coord,
774 key->level = cur_level_;
777 key->zone_id = zone_id_;
778 int n =
static_cast<int>((coord[0] - map_param_.
map_min_x) /
781 int m =
static_cast<int>((coord[1] - map_param_.
map_min_y) /
787 int max_m =
static_cast<unsigned int>(
792 if (n >= 0 && m >= 0 && n < max_n && m < max_m) {
793 key->node_north_id = m;
794 key->node_east_id = n;
799 m =
static_cast<int>(key->node_north_id) - lt_node_index_.y;
801 m = m - (cur_stride_ - 1);
803 key->node_north_id = m / cur_stride_ * cur_stride_ + lt_node_index_.y;
805 n =
static_cast<int>(key->node_east_id) - lt_node_index_.x;
807 n = n - (cur_stride_ - 1);
809 key->node_east_id = n / cur_stride_ * cur_stride_ + lt_node_index_.x;
812cv::Point VisualizationEngine::CoordToMapGridIndex(
813 const Eigen::Vector2d &coord,
const unsigned int resolution_id,
816 p.x =
static_cast<int>((coord[0] - map_param_.
map_min_x) /
818 p.y =
static_cast<int>((coord[1] - map_param_.
map_min_y) /
822 pr.x = p.x - lt_node_grid_index_.x;
823 pr.y = p.y - lt_node_grid_index_.y;
824 pr.x = pr.x / stride;
825 pr.y = pr.y / stride;
830cv::Point VisualizationEngine::MapGridIndexToNodeGridIndex(
const cv::Point &p) {
840bool VisualizationEngine::LoadImageToCache(
const MapImageKey &key) {
843 if (!map_image_cache_.
Get(key, &img)) {
845 snprintf(path,
sizeof(path),
"%s/%02d/%08d/%08d_%d.png",
846 image_visual_leaf_path_.c_str(), key.zone_id, key.node_north_id,
847 key.node_east_id, key.level);
849 img = cv::imread(path);
850 AINFO <<
"visualizer load: " << path;
851 map_image_cache_.
Set(key, img);
860void VisualizationEngine::RotateImg(
const cv::Mat &in_img, cv::Mat *out_img,
862 int width = (in_img.cols > in_img.rows) ? in_img.cols : in_img.rows;
864 cv::Mat mat_tem(width, width, CV_8UC3);
865 mat_tem.setTo(cv::Scalar(0, 0, 0));
867 mat_tem(cv::Rect(width / 2 - in_img.cols / 2, width / 2 - in_img.rows / 2,
868 in_img.cols, in_img.rows)));
869 cv::Point2f pt(
static_cast<float>(width) / 2.0f,
870 static_cast<float>(width) / 2.0f);
871 cv::Mat rotation_mat = cv::getRotationMatrix2D(pt, angle, 1.0);
872 cv::warpAffine(mat_tem, *out_img, rotation_mat, cv::Size(width, width));
875void VisualizationEngine::SetViewCenter(
const double center_x,
876 const double center_y) {
877 _view_center[0] = center_x;
878 _view_center[1] = center_y;
881void VisualizationEngine::UpdateViewCenter(
const double move_x,
882 const double move_y) {
883 _view_center[0] += move_x;
884 _view_center[1] += move_y;
887void VisualizationEngine::SetScale(
const double scale) { cur_scale_ = scale; }
889void VisualizationEngine::UpdateScale(
const double factor) {
890 cur_scale_ *= factor;
893bool VisualizationEngine::UpdateCarLocId() {
894 for (
unsigned int i = 0; i < loc_info_num_ - 1; i++) {
895 unsigned int tem_car_loc_id = (car_loc_id_ + i + 1) % loc_info_num_;
896 if (cur_loc_infos_[tem_car_loc_id].is_valid) {
897 car_loc_id_ = tem_car_loc_id;
898 car_pose_ = cur_loc_infos_[car_loc_id_].pose;
905bool VisualizationEngine::UpdateCarLocId(
const unsigned int car_loc_id) {
906 if (car_loc_id >= loc_info_num_) {
910 if (cur_loc_infos_[car_loc_id].is_valid) {
911 car_loc_id_ = car_loc_id;
912 car_pose_ = cur_loc_infos_[car_loc_id_].pose;
919bool VisualizationEngine::UpdateTrajectoryGroups() {
920 for (
unsigned int i = 0; i < loc_info_num_; i++) {
921 if (cur_loc_infos_[i].is_valid) {
923 LocalizatonInfo &loc_info = cur_loc_infos_[i];
924 loc[0] = loc_info.location.x();
925 loc[1] = loc_info.location.y();
926 std::map<double, Eigen::Vector2d> &trajectory = trajectory_groups_[i];
927 trajectory[loc_info.timestamp] = loc;
934void VisualizationEngine::ProcessKey(
int key) {
936 char c_key =
static_cast<char>(key);
949 UpdateViewCenter(0, move);
954 UpdateViewCenter(-move, 0);
959 UpdateViewCenter(0, -move);
964 UpdateViewCenter(move, 0);
974 SetScale(max_stride_);
979 const Eigen::Vector3d &loc = car_pose_.translation();
980 SetViewCenter(loc[0], loc[1]);
985 follow_car_ = !follow_car_;
990 auto_play_ = !auto_play_;
995 expected_car_loc_id_ = car_loc_id_;
1000 is_draw_car_ = !is_draw_car_;
1004 is_draw_trajectory_ = !is_draw_trajectory_;
bool Get(const MapImageKey &key, cv::Mat *image)
void Set(const MapImageKey &key, const cv::Mat &image)
bool Init(const std::string &map_folder, const std::string &map_visual_folder, const VisualMapParam &map_param, const unsigned int resolution_id, const int zone_id, const Eigen::Affine3d &extrinsic, const unsigned int loc_info_num=1)
void SetAutoPlay(bool auto_play)
void Visualize(::apollo::common::EigenVector< LocalizatonInfo > &&loc_infos, const ::apollo::common::EigenVector3dVec &cloud)
std::vector< EigenType, Eigen::aligned_allocator< EigenType > > EigenVector
bool PathExists(const std::string &path)
Check if the path exists.
bool DirectoryExists(const std::string &directory_path)
Check if the directory specified by directory_path exists and is indeed a directory.
bool EnsureDirectory(const std::string &directory_path)
Check if a specified directory specified by directory_path exists.
uint32_t width
Width of point cloud
const char car_img_path[3][1024]
unsigned char color_table[3][3]
The key structure of a map image .
unsigned int node_north_id
unsigned int node_east_id
bool operator<(const MapImageKey &key) const
The data structure to store parameters of a map
unsigned int map_node_size_y
The map node size in pixels.
std::vector< float > map_resolutions
The pixel resolutions in the map in meters.
double map_min_x
The minimum and maximum UTM range in the map.
unsigned int map_node_size_x
The map node size in pixels.
The engine for localization visualization.