17#include <QtWidgets/QCheckBox>
18#include <QtWidgets/QColorDialog>
19#include <QtWidgets/QComboBox>
20#include <QtWidgets/QMessageBox>
21#include <QtWidgets/QPushButton>
22#include <QtWidgets/QSpinBox>
29#include "modules/tools/visualizer/ui_main_window.h"
33const char* globalTreeItemStyle =
"margin-right:10px";
35const char* aboutMessage =
38 "One Visualization Tool for Presenting Cyber Channel Data\n"
42 "Main View PointCloud view\n"
43 "All Views have right button Menu";
45const char* licenseMessage =
46 "Copyright 2018 The Apollo Authors. All Rights Reserved.\n"
48 "Licensed under the Apache License, Version 2.0 (the \"License\");\n"
49 "you may not use this file except in compliance with the License.\n"
50 "You may obtain a copy of the License at\n"
52 "http://www.apache.org/licenses/LICENSE-2.0\n"
54 "Unless required by applicable law or agreed to in writing, software\n"
55 "distributed under the License is distributed on an \"AS IS\" BASIS,\n"
56 "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
57 "See the License for the specific language governing permissions and\n"
58 "limitations under the License.\n";
60const char* pcTempObjGroupName =
"pointcloud";
61const char* pcVertexPath =
"/apollo/modules/tools/visualizer/shaders/pointcloud.vert";
62const char* pcFragPath =
"/apollo/modules/tools/visualizer/shaders/grid_pointcloud.frag";
63const char* gridVertexPath =
"/apollo/modules/tools/visualizer/shaders/grid.vert";
64const char* gridFragPath =
"/apollo/modules/tools/visualizer/shaders/grid_pointcloud.frag";
65const char* radarVertexPath =
"/apollo/modules/tools/visualizer/shaders/radarpoints.vert";
66const char* radarFragPath =
"/apollo/modules/tools/visualizer/shaders/radarpoints.frag";
68const std::string CompressedImageType(
"apollo.drivers.CompressedImage");
72#define MEMBER_OFFSET(StructType, Member) \
74 reinterpret_cast<char*>(&(reinterpret_cast<StructType*>(1)->Member)) - \
76#define StructPtrByMemberPtr(MemberPtr, StructType, Member) \
77 reinterpret_cast<StructType*>(reinterpret_cast<char*>(MemberPtr) - \
78 MEMBER_OFFSET(StructType, Member))
168 : QMainWindow(parent),
171 open_images_dialog_(nullptr),
174 enable_grid_checkBox_(nullptr),
175 grid_root_item_(nullptr),
177 pointcloud_top_item_(nullptr),
178 pointcloud_comboBox_(new QComboBox),
179 pointcloud_button_(new QPushButton),
180 pointcloud_channel_Reader_(nullptr),
182 pointcloud_reader_mutex_(),
184 pointcloud_shader_(nullptr),
185 grid_shader_(nullptr),
186 radar_points_shader_(nullptr),
187 video_image_viewer_list_(),
188 closed_video_image_viewer_list_(),
190 closed_radarData_list_(),
191 _channelName2TypeMap() {
193 ui_->videoImageGridLayout->setContentsMargins(2, 2, 2, 2);
194 ui_->videoImageWidget->setVisible(
false);
196 ui_->mainToolBar->addAction(ui_->actionAddGrid);
197 ui_->mainToolBar->addAction(ui_->actionPointCloud);
198 ui_->mainToolBar->addSeparator();
199 ui_->mainToolBar->addAction(ui_->actionOpenImage);
200 ui_->mainToolBar->addAction(ui_->actionOpenImages);
201 ui_->mainToolBar->addAction(ui_->actionDelImage);
202 ui_->mainToolBar->addSeparator();
203 ui_->mainToolBar->addAction(ui_->actionPlay);
204 ui_->mainToolBar->addAction(ui_->actionPause);
206 pointcloud_reader_mutex_.lock();
210 tmp <<
"ChannelNames"
212 all_channel_root_ =
new QTreeWidgetItem(tmp);
213 ui_->treeWidget->addTopLevelItem(all_channel_root_);
216 connect(ui_->actionAbout, SIGNAL(triggered(
bool)),
this, SLOT(showMessage()));
217 connect(ui_->actionLicense, SIGNAL(triggered(
bool)),
this,
218 SLOT(showMessage()));
220 pointcloud_button_->setCheckable(
true);
221 pointcloud_button_->setStyleSheet(globalTreeItemStyle);
222 pointcloud_comboBox_->setStyleSheet(globalTreeItemStyle);
224 connect(pointcloud_button_, SIGNAL(clicked(
bool)),
this,
225 SLOT(PlayRenderableObject(
bool)));
226 connect(pointcloud_comboBox_, SIGNAL(currentIndexChanged(
int)),
this,
227 SLOT(ChangePointCloudChannel()));
229 connect(ui_->treeWidget, SIGNAL(itemSelectionChanged()),
this,
230 SLOT(UpdateActions()));
231 connect(ui_->treeWidget, SIGNAL(visibilityChanged(
bool)), ui_->actionGlobal,
232 SLOT(setChecked(
bool)));
233 connect(ui_->actionPlay, SIGNAL(triggered(
bool)),
this, SLOT(PlayPause()));
234 connect(ui_->actionPause, SIGNAL(triggered(
bool)),
this, SLOT(PlayPause()));
239 item->reader_mutex_.unlock();
241 for (
VideoImgProxy* item : closed_video_image_viewer_list_) {
242 item->reader_mutex_.unlock();
244 for (
RadarData* item : radarData_list_) {
245 item->reader_mutex_.unlock();
247 for (
RadarData* item : closed_radarData_list_) {
248 item->reader_mutex_.unlock();
251 pointcloud_reader_mutex_.unlock();
253 if (pointcloud_channel_Reader_) {
254 delete pointcloud_channel_Reader_;
255 pointcloud_channel_Reader_ =
nullptr;
262 for (
VideoImgProxy* item : closed_video_image_viewer_list_) {
266 for (
RadarData* item : radarData_list_) {
270 for (
RadarData* item : closed_radarData_list_) {
278void MainWindow::calculateWH(
void) {
279 int count = video_image_viewer_list_.count();
283 wh.setWidth(ui_->sceneWidget->width() - count * 2 + 2);
285 wh.setWidth(wh.width() / count);
288 for (VideoImgProxy* p : video_image_viewer_list_) {
289 p->video_image_viewer_.setMinimumSize(wh);
290 ui_->videoImageGridLayout->removeWidget(&p->video_image_viewer_);
291 ui_->videoImageGridLayout->addWidget(&p->video_image_viewer_, index / 3,
295 ui_->videoImageWidget->adjustSize();
300 std::shared_ptr<Texture> tex(
new Texture);
301 if (tex ==
nullptr) {
304 VideoImgProxy* ret =
new VideoImgProxy();
307 int index = video_image_viewer_list_.count();
308 ret->video_image_viewer_.set_index(index);
310 ret->video_image_viewer_.setStyleSheet(
"background-color:black;");
311 ret->video_image_viewer_.setVisible(
false);
313 QString imgName = tr(
"Camera%1").arg(index);
315 ret->root_item_.setHidden(
true);
316 ret->root_item_.setText(0, imgName);
317 ret->root_item_.setText(1,
"");
319 ret->channel_name_item_.setText(0,
"ChannelName");
320 ret->action_item_.setText(0,
"Action");
322 ret->action_item_button_.setObjectName(tr(
"pushButton%1").arg(index));
323 ret->action_item_button_.setText(
"Play");
324 ret->action_item_button_.setCheckable(
true);
325 ret->action_item_button_.setStyleSheet(globalTreeItemStyle);
327 ret->channel_name_combobox_.setObjectName(tr(
"comboBox%1").arg(index));
328 ret->channel_name_combobox_.setStyleSheet(globalTreeItemStyle);
330 ret->root_item_.addChild(&ret->channel_name_item_);
331 ret->root_item_.addChild(&ret->action_item_);
333 ret->dynamic_texture_ = tex;
334 ret->video_image_viewer_.SetupDynamicTexture(tex);
336 ret->video_image_viewer_.setSizePolicy(QSizePolicy::Preferred,
337 QSizePolicy::Preferred);
338 ret->video_image_viewer_.addAction(ui_->actionDelImage);
339 ret->reader_mutex_.lock();
345 RadarData* ret =
new RadarData();
348 int index = radarData_list_.count();
349 QString radarName = tr(
"Radar%1").arg(index);
351 ret->root_item_.setHidden(
true);
352 ret->root_item_.setText(0, radarName);
354 ret->channel_name_item_.setText(0,
"ChannelName");
355 ret->action_item_.setText(0,
"Action");
356 ret->enable_checkBox_.setChecked(
true);
358 ret->action_item_button_.setText(
"Play");
359 ret->action_item_button_.setCheckable(
true);
360 ret->action_item_button_.setStyleSheet(globalTreeItemStyle);
362 ret->channel_name_combobox_.setObjectName(tr(
"comboBox%1").arg(index));
363 ret->channel_name_combobox_.setStyleSheet(globalTreeItemStyle);
365 ret->root_item_.addChild(&ret->channel_name_item_);
366 ret->root_item_.addChild(&ret->action_item_);
367 ret->reader_mutex_.lock();
374void MainWindow::ActionAddGrid(
void) {
375 if (grid_shader_ ==
nullptr) {
378 if (grid_shader_ !=
nullptr) {
379 ui_->sceneWidget->AddNewShaderProg(
"grid", grid_shader_);
383 if (grid_root_item_ ==
nullptr) {
384 QTreeWidgetItem* colorChild =
nullptr;
385 QTreeWidgetItem* cellCountChild =
nullptr;
386 QSpinBox* spinbox =
nullptr;
389 if (grid_ ==
nullptr) {
393 if (grid_shader_ ==
nullptr) {
397 enable_grid_checkBox_ =
new QCheckBox(ui_->treeWidget);
398 if (enable_grid_checkBox_ ==
nullptr) {
402 grid_root_item_ =
new QTreeWidgetItem(ui_->treeWidget);
403 if (grid_root_item_ ==
nullptr) {
407 colorChild =
new QTreeWidgetItem(grid_root_item_);
408 if (colorChild ==
nullptr) {
411 grid_root_item_->addChild(colorChild);
412 colorChild->setText(0,
"Color");
413 colorChild->setText(1, tr(
"%1;%2;%3")
416 .arg(grid_->
blue()));
418 spinbox =
new QSpinBox(ui_->treeWidget);
419 if (spinbox ==
nullptr) {
422 spinbox->setMinimum(1);
423 spinbox->setMaximum(100);
424 spinbox->setSingleStep(1);
426 spinbox->setStyleSheet(globalTreeItemStyle);
428 cellCountChild =
new QTreeWidgetItem(grid_root_item_);
429 if (cellCountChild ==
nullptr) {
432 grid_root_item_->addChild(cellCountChild);
433 cellCountChild->setText(0,
"CellCount");
436 if (!ui_->sceneWidget->AddPermanentRenderObj(grid_)) {
440 enable_grid_checkBox_->setText(
"Enable");
441 enable_grid_checkBox_->setChecked(
true);
442 grid_root_item_->setText(0,
"Grid");
443 grid_root_item_->setText(1,
"");
445 ui_->treeWidget->addTopLevelItem(grid_root_item_);
447 ui_->treeWidget->setItemWidget(grid_root_item_, 1, enable_grid_checkBox_);
448 ui_->treeWidget->setItemWidget(cellCountChild, 1, spinbox);
450 connect(enable_grid_checkBox_, SIGNAL(clicked(
bool)),
this,
451 SLOT(EnableGrid(
bool)));
452 connect(ui_->treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,
int)),
453 this, SLOT(EditGridColor(QTreeWidgetItem*,
int)));
454 connect(spinbox, SIGNAL(valueChanged(
int)),
this,
455 SLOT(ChangeGridCellCountBySize(
int)));
459 delete cellCountChild;
465 delete grid_root_item_;
467 delete enable_grid_checkBox_;
471 QMessageBox::warning(
this, tr(
"Error"),
472 tr(
"There is no enough memory for creating Grid!!!"),
478void MainWindow::ChangeGridCellCountBySize(
int v) {
485void MainWindow::EditGridColor(QTreeWidgetItem* item,
int column) {
486 if (column && item !=
nullptr && grid_root_item_ !=
nullptr &&
487 item == grid_root_item_->child(0)) {
488 QStringList rgb = item->text(1).split(
';');
489 QColor color(rgb.at(0).toInt(), rgb.at(1).toInt(), rgb.at(2).toInt());
491 color = QColorDialog::getColor(color,
nullptr, tr(
"set grid color"));
493 if (color.isValid()) {
495 tr(
"%1;%2;%3").arg(color.red()).arg(color.green()).arg(color.blue());
496 item->setText(1, str);
503void MainWindow::EnableRadarPoints(
bool b) {
504 QCheckBox* obj =
static_cast<QCheckBox*
>(sender());
506 ui_->sceneWidget->setTempObjGroupEnabled(r->root_item_.text(0).toStdString(),
510void MainWindow::ActionOpenRadarChannel(
void) {
511 if (radar_points_shader_ ==
nullptr) {
513 tr(radarVertexPath), tr(radarFragPath));
514 if (radar_points_shader_ !=
nullptr) {
515 ui_->sceneWidget->AddNewShaderProg(
"radarpoints", radar_points_shader_);
517 QMessageBox::warning(
518 this, tr(
"NO Shader"),
519 tr(
"There is no suitable shader for Radar Points!!!"),
525 RadarData* radarProxy;
527 if (closed_radarData_list_.empty()) {
528 radarProxy = createRadarData();
530 if (radarProxy ==
nullptr) {
531 QMessageBox::warning(
this, tr(
"No Enough Memory"),
532 tr(
"There is no enough memory!!!\nCannot add new "
533 "image or video channel!"),
538 ui_->treeWidget->addTopLevelItem(&radarProxy->root_item_);
539 ui_->treeWidget->setItemWidget(&radarProxy->root_item_, 1,
540 &radarProxy->enable_checkBox_);
542 ui_->treeWidget->setItemWidget(&radarProxy->channel_name_item_, 1,
543 &radarProxy->channel_name_combobox_);
544 ui_->treeWidget->setItemWidget(&radarProxy->action_item_, 1,
545 &radarProxy->action_item_button_);
547 for (
int i = 0; i < all_channel_root_->childCount(); ++i) {
548 QTreeWidgetItem* child = all_channel_root_->child(i);
549 QString channel = child->text(0);
550 if (channel.contains(
"radar")) {
551 radarProxy->channel_name_combobox_.addItem(channel);
555 radarProxy = closed_radarData_list_.takeFirst();
558 connect(&radarProxy->action_item_button_, SIGNAL(clicked(
bool)),
this,
559 SLOT(openRadarChannel(
bool)));
560 connect(&radarProxy->enable_checkBox_, SIGNAL(clicked(
bool)),
this,
561 SLOT(EnableRadarPoints(
bool)));
562 connect(&radarProxy->channel_name_combobox_, SIGNAL(currentIndexChanged(
int)),
563 this, SLOT(ChangeRadarChannel()));
565 radarData_list_.append(radarProxy);
567 radarProxy->root_item_.setHidden(
false);
569 ui_->treeWidget->setVisible(
true);
570 ui_->actionGlobal->setChecked(
true);
573void MainWindow::openRadarChannel(
bool b) {
574 QPushButton* obj =
static_cast<QPushButton*
>(QObject::sender());
575 RadarData* theVideoImg =
577 DoOpenRadarChannel(b, theVideoImg);
580void MainWindow::DoOpenRadarChannel(
bool b, RadarData* radarProxy) {
582 if (radarProxy->channel_name_combobox_.currentText().isEmpty()) {
583 QMessageBox::warning(
584 this, tr(
"Setup Channel Name"),
585 tr(
"Channel Name cannot be empty!!!\nPlease select one!"),
587 radarProxy->action_item_button_.setChecked(
false);
591 if (!radarProxy->channel_reader_) {
592 radarProxy->channel_reader_ =
595 if (!radarProxy->channel_reader_) {
596 QMessageBox::warning(
this, tr(
"Create cyber Channel Reader"),
597 tr(
"There is no enough memory!!!\nCannot create "
598 "cyber channel reader!"),
605 const std::shared_ptr<apollo::drivers::RadarObstacles>& pdata) {
606 this->RadarRenderCallback(pdata, radarProxy);
609 std::string nodeName(
"Visualizer-");
610 nodeName.append(radarProxy->root_item_.text(0).toStdString());
612 if (!radarProxy->channel_reader_->InstallCallbackAndOpen(
614 radarProxy->channel_name_combobox_.currentText().toStdString(),
616 QMessageBox::warning(
617 this, tr(
"Setup Channel Callback"),
618 tr(
"Channel Callback cannot be installed!!!\nPlease check it!"),
620 delete radarProxy->channel_reader_;
621 radarProxy->channel_reader_ =
nullptr;
623 radarProxy->action_item_button_.setChecked(
false);
628 radarProxy->root_item_.setToolTip(
629 0, radarProxy->channel_name_combobox_.currentText());
631 radarProxy->action_item_button_.setText(
"Stop");
632 radarProxy->channel_name_combobox_.setEnabled(
false);
634 radarProxy->reader_mutex_.unlock();
636 if (!radarProxy->channel_name_combobox_.isEnabled()) {
637 radarProxy->reader_mutex_.lock();
638 radarProxy->action_item_button_.setText(
"Play");
639 radarProxy->channel_name_combobox_.setEnabled(
true);
642 ui_->treeWidget->setCurrentItem(
nullptr);
643 ui_->treeWidget->clearFocus();
646void MainWindow::RadarRenderCallback(
647 const std::shared_ptr<const apollo::drivers::RadarObstacles>& rawData,
649 radar->reader_mutex_.lock();
650 radar->reader_mutex_.unlock();
652 std::cout <<
"-------MainWindow::RadarRenderCallback()-------" << std::endl;
654 if (rawData !=
nullptr) {
658 !ui_->sceneWidget->AddTempRenderableObj(
659 radar->root_item_.text(0).toStdString(), r)) {
663 std::cerr <<
"cannot create RadarPoints Renderable Object" << std::endl;
668void MainWindow::ActionOpenPointCloud(
void) {
669 if (pointcloud_shader_ ==
nullptr) {
672 if (pointcloud_shader_ !=
nullptr) {
673 ui_->sceneWidget->AddNewShaderProg(
"pointcloud", pointcloud_shader_);
675 QMessageBox::warning(
this, tr(
"NO Shader"),
676 tr(
"There is no suitable shader for Pointcloud!!!"),
682 if (pointcloud_top_item_ ==
nullptr) {
683 pointcloud_top_item_ =
new QTreeWidgetItem(ui_->treeWidget);
684 if (pointcloud_top_item_ ==
nullptr) {
688 pointcloud_top_item_->setText(0,
"PointCloud2");
689 pointcloud_top_item_->setText(1,
"");
691 QTreeWidgetItem* item =
new QTreeWidgetItem(pointcloud_top_item_);
692 if (item ==
nullptr) {
693 QMessageBox::warning(
this, tr(
"NO Enough Memory"),
694 tr(
"Cannot create tree item for channel name!!!"),
699 item->setText(0,
"ChannelName");
700 ui_->treeWidget->setItemWidget(item, 1, pointcloud_comboBox_);
702 item =
new QTreeWidgetItem(pointcloud_top_item_);
703 if (item ==
nullptr) {
704 QMessageBox::warning(
this, tr(
"NO Enough Memory"),
705 tr(
"Cannot create tree item for channel Action!!!"),
710 item->setText(0,
"Action");
712 pointcloud_button_->setText(
"Play");
713 ui_->treeWidget->setItemWidget(item, 1, pointcloud_button_);
715 ui_->treeWidget->setVisible(
true);
716 ui_->actionGlobal->setChecked(
true);
720void MainWindow::ActionOpenImages(
void) {
721 if (open_images_dialog_ ==
nullptr) {
723 if (open_images_dialog_ ==
nullptr) {
724 QMessageBox::warning(
this, tr(
"No Enough Memory"),
725 tr(
"There is no enough memory!!!"), QMessageBox::Ok);
728 connect(open_images_dialog_, SIGNAL(accepted()),
this,
729 SLOT(AddVideoImages()));
733 open_images_dialog_->show();
736void MainWindow::AddVideoImages(
void) {
737 int count = open_images_dialog_->
count();
744void MainWindow::ActionOpenImage(
void) {
745 VideoImgProxy* videoImgProxy;
747 if (closed_video_image_viewer_list_.empty()) {
748 videoImgProxy = AddVideoImgViewer();
750 if (videoImgProxy ==
nullptr) {
751 QMessageBox::warning(
this, tr(
"No Enough Memory"),
752 tr(
"There is no enough memory!!!\nCannot add new "
753 "image or video channel!"),
758 videoImgProxy->video_image_viewer_.setParent(ui_->videoImageWidget);
760 ui_->treeWidget->addTopLevelItem(&videoImgProxy->root_item_);
761 ui_->treeWidget->setItemWidget(&videoImgProxy->channel_name_item_, 1,
762 &videoImgProxy->channel_name_combobox_);
763 ui_->treeWidget->setItemWidget(&videoImgProxy->action_item_, 1,
764 &videoImgProxy->action_item_button_);
766 for (
int i = 0; i < all_channel_root_->childCount(); ++i) {
767 QTreeWidgetItem* child = all_channel_root_->child(i);
768 QString channel = child->text(0);
769 if (channel.contains(
"camera")) {
770 videoImgProxy->channel_name_combobox_.addItem(channel);
774 videoImgProxy = closed_video_image_viewer_list_.takeFirst();
777 connect(&videoImgProxy->action_item_button_, SIGNAL(clicked(
bool)),
this,
778 SLOT(PlayVideoImage(
bool)));
779 connect(&videoImgProxy->channel_name_combobox_,
780 SIGNAL(currentIndexChanged(
int)),
this,
781 SLOT(ChangeVideoImgChannel()));
782 connect(&videoImgProxy->video_image_viewer_,
786 video_image_viewer_list_.append(videoImgProxy);
787 videoImgProxy->video_image_viewer_.setVisible(
true);
791 videoImgProxy->video_image_viewer_.StartOrStopUpdate(
true);
792 videoImgProxy->root_item_.setHidden(
false);
794 ui_->videoImageWidget->setVisible(
true);
796 ui_->treeWidget->setVisible(
true);
797 ui_->actionGlobal->setChecked(
true);
802void MainWindow::ActionDelVideoImage(
void) {
803 QTreeWidgetItem* topItem = ui_->treeWidget->currentItem();
804 VideoImgProxy* proxy =
807 DoDeleteVideoImg(proxy);
808 ui_->actionDelImage->setEnabled(
false);
811void MainWindow::CloseVideoImgViewer(
bool b) {
819void MainWindow::DoDeleteVideoImg(VideoImgProxy* proxy) {
820 disconnect(&proxy->action_item_button_, SIGNAL(clicked(
bool)),
this,
821 SLOT(PlayVideoImage(
bool)));
822 disconnect(&proxy->channel_name_combobox_, SIGNAL(currentIndexChanged(
int)),
823 this, SLOT(ChangeVideoImgChannel()));
824 disconnect(&proxy->video_image_viewer_,
828 proxy->action_item_button_.setChecked(
false);
829 DoPlayVideoImage(
false, proxy);
831 proxy->video_image_viewer_.StartOrStopUpdate(
false);
832 proxy->root_item_.setHidden(
true);
833 proxy->video_image_viewer_.setVisible(
false);
834 ui_->videoImageGridLayout->removeWidget(&proxy->video_image_viewer_);
836 video_image_viewer_list_.removeOne(proxy);
837 closed_video_image_viewer_list_.append(proxy);
839 if (video_image_viewer_list_.count()) {
842 ui_->videoImageWidget->setVisible(
false);
846void MainWindow::UpdateActions(
void) {
847 QTreeWidgetItem* item = ui_->treeWidget->currentItem();
848 ui_->actionDelImage->setEnabled(
false);
850 if (!item->parent() && item != pointcloud_top_item_ &&
851 item != all_channel_root_ && item != grid_root_item_) {
852 ui_->actionDelImage->setEnabled(
true);
857void MainWindow::PointCloudReaderCallback(
858 const std::shared_ptr<const apollo::drivers::PointCloud>& pdata) {
859 pointcloud_reader_mutex_.lock();
860 pointcloud_reader_mutex_.unlock();
864 !ui_->sceneWidget->AddTempRenderableObj(pcTempObjGroupName, pc)) {
868 std::cerr <<
"-----Cannot create PointCloud----------" << std::endl;
872void MainWindow::PlayRenderableObject(
bool b) {
874 if (pointcloud_comboBox_->currentText().isEmpty()) {
875 QMessageBox::warning(
876 this, tr(
"Setup Channel Name"),
877 tr(
"Channel Name cannot be empty!!!\nPlease Select it!"),
879 pointcloud_button_->setChecked(
false);
883 if (!pointcloud_channel_Reader_) {
884 pointcloud_channel_Reader_ =
887 if (!pointcloud_channel_Reader_) {
888 QMessageBox::warning(
this, tr(
"Create Cyber Channel Reader"),
889 tr(
"There is no enough memory!!!\nCannot create "
890 "cyber channel reader!"),
892 pointcloud_button_->setChecked(
false);
897 [
this](
const std::shared_ptr<apollo::drivers::PointCloud>& pdata) {
898 this->PointCloudReaderCallback(pdata);
900 std::string nodeName(
"Visualizer-");
901 nodeName.append(pointcloud_top_item_->text(0).toStdString());
903 pointCallback, pointcloud_comboBox_->currentText().toStdString(),
905 QMessageBox::warning(
906 this, tr(
"Setup Channel Callback"),
907 tr(
"Channel Callback cannot be installed!!!\nPlease check it!"),
909 delete pointcloud_channel_Reader_;
910 pointcloud_channel_Reader_ =
nullptr;
912 pointcloud_button_->setChecked(
false);
917 ui_->sceneWidget->setToolTip(pointcloud_comboBox_->currentText());
918 pointcloud_top_item_->setToolTip(0, pointcloud_comboBox_->currentText());
919 pointcloud_comboBox_->setEnabled(
false);
920 pointcloud_button_->setText(tr(
"Stop"));
922 pointcloud_reader_mutex_.unlock();
924 if (!pointcloud_comboBox_->isEnabled()) {
925 pointcloud_reader_mutex_.lock();
926 pointcloud_comboBox_->setEnabled(
true);
927 pointcloud_button_->setText(tr(
"Show"));
931 ui_->treeWidget->setCurrentItem(
nullptr);
932 ui_->treeWidget->clearFocus();
935void MainWindow::ImageReaderCallback(
936 const std::shared_ptr<const apollo::drivers::Image>& imgData,
937 VideoImgProxy* theVideoImgProxy) {
938 theVideoImgProxy->reader_mutex_.lock();
939 if (theVideoImgProxy->dynamic_texture_ !=
nullptr && imgData !=
nullptr) {
940 if (theVideoImgProxy->dynamic_texture_->UpdateData(imgData)) {
941 theVideoImgProxy->video_image_viewer_.SetupDynamicTexture(
942 theVideoImgProxy->dynamic_texture_);
944 std::cerr <<
"--------Cannot update dynamic Texture Data--------"
949 <<
"----Dynamic Texture is nullptr or apollo.drivers.Image is nullptr"
952 theVideoImgProxy->reader_mutex_.unlock();
955void MainWindow::ImageReaderCallback(
956 const std::shared_ptr<const apollo::drivers::CompressedImage>& imgData,
957 VideoImgProxy* theVideoImgProxy) {
958 theVideoImgProxy->reader_mutex_.lock();
959 if (theVideoImgProxy->dynamic_texture_ !=
nullptr && imgData !=
nullptr) {
961 const std::string& data = imgData->data();
962 if (img.loadFromData(
reinterpret_cast<const unsigned char*
>(data.c_str()),
963 static_cast<int>(data.size()))) {
964 if (theVideoImgProxy->dynamic_texture_->UpdateData(img)) {
965 theVideoImgProxy->video_image_viewer_.SetupDynamicTexture(
966 theVideoImgProxy->dynamic_texture_);
968 std::cerr <<
"--------Cannot update dynamic Texture Data--------"
973 <<
"-----------Cannot load compressed image from data with QImage"
978 <<
"----Dynamic Texture is nullptr or apollo.drivers.Image is nullptr"
981 theVideoImgProxy->reader_mutex_.unlock();
984void MainWindow::PlayVideoImage(
bool b) {
985 QPushButton* obj =
static_cast<QPushButton*
>(QObject::sender());
986 VideoImgProxy* theVideoImg =
988 DoPlayVideoImage(b, theVideoImg);
991void MainWindow::DoPlayVideoImage(
bool b, VideoImgProxy* theVideoImg) {
993 if (theVideoImg->channel_name_combobox_.currentText().isEmpty()) {
994 QMessageBox::warning(
995 this, tr(
"Setup Channel Name"),
996 tr(
"Channel Name cannot be empty!!!\nPlease select one!"),
998 theVideoImg->action_item_button_.setChecked(
false);
1002 const std::string channelName =
1003 theVideoImg->channel_name_combobox_.currentText().toStdString();
1004 if (_channelName2TypeMap[channelName] == CompressedImageType)
1005 theVideoImg->isCompressedImage_ =
true;
1007 if (!theVideoImg->image_reader_) {
1008 if (theVideoImg->isCompressedImage_) {
1009 theVideoImg->compressed_image_reader_ =
1012 theVideoImg->image_reader_ =
1016 if (!theVideoImg->image_reader_) {
1017 QMessageBox::warning(
this, tr(
"Create cyber Channel Reader"),
1018 tr(
"There is no enough memory!!!\nCannot create "
1019 "cyber channel reader!"),
1024 std::string nodeName(
"Visualizer-");
1025 nodeName.append(theVideoImg->root_item_.text(0).toStdString());
1029 if (theVideoImg->isCompressedImage_) {
1030 auto videoCallback =
1031 [
this, theVideoImg](
1032 const std::shared_ptr<apollo::drivers::CompressedImage>&
1033 pdata) { this->ImageReaderCallback(pdata, theVideoImg); };
1035 ret = theVideoImg->compressed_image_reader_->InstallCallbackAndOpen(
1036 videoCallback, channelName, nodeName);
1038 auto videoCallback =
1039 [
this, theVideoImg](
1040 const std::shared_ptr<apollo::drivers::Image>& pdata) {
1041 this->ImageReaderCallback(pdata, theVideoImg);
1043 ret = theVideoImg->image_reader_->InstallCallbackAndOpen(
1044 videoCallback, channelName, nodeName);
1047 QMessageBox::warning(
1048 this, tr(
"Setup Channel Callback"),
1049 tr(
"Channel Callback cannot be installed!!!\nPlease check it!"),
1052 theVideoImg->deleteReader();
1053 theVideoImg->action_item_button_.setChecked(
false);
1058 theVideoImg->root_item_.setToolTip(
1059 0, theVideoImg->channel_name_combobox_.currentText());
1060 theVideoImg->video_image_viewer_.setToolTip(
1061 theVideoImg->channel_name_combobox_.currentText());
1063 theVideoImg->action_item_button_.setText(
"Stop");
1064 theVideoImg->channel_name_combobox_.setEnabled(
false);
1066 theVideoImg->reader_mutex_.unlock();
1068 if (!theVideoImg->channel_name_combobox_.isEnabled()) {
1069 theVideoImg->reader_mutex_.lock();
1070 theVideoImg->action_item_button_.setText(
"Play");
1071 theVideoImg->channel_name_combobox_.setEnabled(
true);
1074 ui_->treeWidget->setCurrentItem(
nullptr);
1075 ui_->treeWidget->clearFocus();
1078void MainWindow::ChangePointCloudChannel() {
1079 if (pointcloud_channel_Reader_ !=
nullptr) {
1081 std::string nodeName(
"Visualizer-");
1082 nodeName.append(pointcloud_top_item_->text(0).toStdString());
1084 pointcloud_comboBox_->currentText().toStdString(), nodeName);
1088void MainWindow::ChangeVideoImgChannel() {
1089 QComboBox* obj =
static_cast<QComboBox*
>(QObject::sender());
1090 VideoImgProxy* theVideoImg =
1093 if (theVideoImg->image_reader_ !=
nullptr) {
1094 theVideoImg->deleteReader();
1098void MainWindow::ChangeRadarChannel(
void) {
1099 QComboBox* obj =
static_cast<QComboBox*
>(QObject::sender());
1103 if (radar->channel_reader_ !=
nullptr) {
1104 radar->channel_reader_->CloseChannel();
1105 std::string nodeName(
"Visualizer-");
1106 nodeName.append(radar->root_item_.text(0).toStdString());
1107 radar->channel_reader_->OpenChannel(obj->currentText().toStdString(),
1114 VideoImgProxy* theVideoImg =
1116 theVideoImg->root_item_.setExpanded(
true);
1117 if (ui_->treeWidget->currentItem() == &theVideoImg->root_item_) {
1118 ui_->actionDelImage->setEnabled(
true);
1120 ui_->treeWidget->setCurrentItem(&theVideoImg->root_item_);
1122 ui_->treeWidget->setFocus();
1139 if (_channelName2TypeMap.find(channelName) != _channelName2TypeMap.end()) {
1143 _channelName2TypeMap[channelName] = msgTypeName;
1145 QTreeWidgetItem* child =
new QTreeWidgetItem();
1146 if (child ==
nullptr) {
1147 QMessageBox::warning(
this, tr(
"Error"), tr(
"No Enough for New Channel!!!"),
1152 QString str(channelName.c_str());
1153 child->setText(0, str);
1154 child->setToolTip(0, str);
1157 for (
int i = 0; i < all_channel_root_->childCount(); ++i) {
1158 if (str < all_channel_root_->child(i)->text(0)) {
1159 all_channel_root_->insertChild(i, child);
1165 all_channel_root_->addChild(child);
1167 ui_->treeWidget->setRootIsDecorated(
true);
1169 QString msgType(msgTypeName.c_str());
1170 if (msgType.contains(
"camera", Qt::CaseInsensitive)) {
1172 item->channel_name_combobox_.addItem(str);
1175 for (
VideoImgProxy* item : closed_video_image_viewer_list_) {
1176 item->channel_name_combobox_.addItem(str);
1180 if (msgType.contains(
"pointcloud", Qt::CaseInsensitive)) {
1181 pointcloud_comboBox_->addItem(str);
1184 if (msgType.contains(
"radar", Qt::CaseInsensitive)) {
1185 for (
RadarData* item : radarData_list_) {
1186 item->channel_name_combobox_.addItem(str);
1189 for (
RadarData* item : closed_radarData_list_) {
1190 item->channel_name_combobox_.addItem(str);
1195void MainWindow::PlayPause(
void) {
1196 QObject* obj = QObject::sender();
1198 if (obj == ui_->actionPause) {
1201 if (pointcloud_top_item_) {
1202 pointcloud_button_->setChecked(b);
1203 PlayRenderableObject(b);
1205 for (VideoImgProxy* p : video_image_viewer_list_) {
1206 p->action_item_button_.setChecked(b);
1207 DoPlayVideoImage(b, p);
1209 for (RadarData* item : radarData_list_) {
1210 item->action_item_button_.setChecked(b);
1211 DoOpenRadarChannel(b, item);
1216 QMainWindow::resizeEvent(event);
1220void MainWindow::showMessage() {
1221 QObject* obj = QObject::sender();
1223 if (obj == ui_->actionAbout) {
1224 msg_dialog_->setWindowTitle(tr(
"About"));
1229 if (obj == ui_->actionLicense) {
1230 msg_dialog_->setWindowTitle(tr(
"License"));
1234 msg_dialog_->adjustSize();
1235 msg_dialog_->show();
bool InstallCallbackAndOpen(CyberChannelCallback< T > channelCallback, const std::string &channelName, const std::string &nodeName)
bool OpenChannel(const std::string &channelName, const std::string &nodeName)
int CellCount(void) const
void set_grid_color(const QColor &color)
void SetCellCount(int cellCount)
void resizeEvent(QResizeEvent *) override
void AddNewWriter(const apollo::cyber::proto::RoleAttributes &role)
MainWindow(QWidget *parent=nullptr)
void TopologyChanged(const apollo::cyber::proto::ChangeMsg &change_msg)
void setMessage(const QString &msg)
bool FillData(const std::shared_ptr< const apollo::drivers::PointCloud > &pData)
bool FillData(const std::shared_ptr< const apollo::drivers::RadarObstacles > &pData)
void set_is_renderable(bool b)
void set_shader_program(const std::shared_ptr< QOpenGLShaderProgram > &shaderProgram)
static std::shared_ptr< QOpenGLShaderProgram > CreateShaderProgram(const QString &vertexShaderFileName, const QString &fragShaderFileName)
#define StructPtrByMemberPtr(MemberPtr, StructType, Member)
QTreeWidgetItem root_item_
QPushButton action_item_button_
QTreeWidgetItem channel_name_item_
QCheckBox enable_checkBox_
QTreeWidgetItem action_item_
CyberChannReader< apollo::drivers::RadarObstacles > * channel_reader_
QComboBox channel_name_combobox_
CyberChannReader< apollo::drivers::CompressedImage > * compressed_image_reader_
FixedAspectRatioWidget video_image_viewer_
QTreeWidgetItem action_item_
CyberChannReader< apollo::drivers::Image > * image_reader_
QPushButton action_item_button_
std::shared_ptr< Texture > dynamic_texture_
QComboBox channel_name_combobox_
QTreeWidgetItem root_item_
QTreeWidgetItem channel_name_item_
optional RoleAttributes role_attr
optional OperateType operate_type
optional ChangeType change_type
optional RoleType role_type
optional string channel_name
optional string message_type