diff --git a/guilib/include/rtabmap/gui/CloudViewer.h b/guilib/include/rtabmap/gui/CloudViewer.h index 2927428b..535f06e1 100644 --- a/guilib/include/rtabmap/gui/CloudViewer.h +++ b/guilib/include/rtabmap/gui/CloudViewer.h @@ -196,6 +196,7 @@ public: void setTrajectoryShown(bool shown); void setTrajectorySize(unsigned int value); void clearTrajectory(); + void resetCamera(); void removeAllClouds(); //including meshes bool removeCloud(const std::string & id); //including mesh diff --git a/guilib/include/rtabmap/gui/MainWindow.h b/guilib/include/rtabmap/gui/MainWindow.h index c6b0dc37..9ac1f6de 100644 --- a/guilib/include/rtabmap/gui/MainWindow.h +++ b/guilib/include/rtabmap/gui/MainWindow.h @@ -180,6 +180,7 @@ private slots: void setAspectRatio480p(); void setAspectRatio720p(); void setAspectRatio1080p(); + void setAspectRatioCustom(); void exportGridMap(); void exportScans(); void exportClouds(); @@ -227,7 +228,7 @@ private: void saveFigures(); void loadFigures(); void exportPoses(int format); - QString captureScreen(); + QString captureScreen(bool cacheInRAM = false); std::map::Ptr > getClouds( const std::map & poses, @@ -304,6 +305,8 @@ private: QString _graphSavingFileName; QMap _exportPosesFileName; bool _autoScreenCaptureOdomSync; + bool _autoScreenCaptureRAM; + QMap _autoScreenCaptureCachedImages; QVector _refIds; QVector _loopClosureIds; diff --git a/guilib/include/rtabmap/gui/PreferencesDialog.h b/guilib/include/rtabmap/gui/PreferencesDialog.h index 8a2bdedc..c6e6159f 100644 --- a/guilib/include/rtabmap/gui/PreferencesDialog.h +++ b/guilib/include/rtabmap/gui/PreferencesDialog.h @@ -117,7 +117,7 @@ public: void saveWindowGeometry(const QWidget * window); void loadWindowGeometry(QWidget * window); void saveMainWindowState(const QMainWindow * mainWindow); - void loadMainWindowState(QMainWindow * mainWindow, bool & maximized); + void loadMainWindowState(QMainWindow * mainWindow, bool & maximized, bool & statusBarShown); void saveWidgetState(const QWidget * widget); void loadWidgetState(QWidget * widget); diff --git a/guilib/src/CloudViewer.cpp b/guilib/src/CloudViewer.cpp index d471dbc7..06d0b544 100644 --- a/guilib/src/CloudViewer.cpp +++ b/guilib/src/CloudViewer.cpp @@ -889,6 +889,37 @@ void CloudViewer::clearTrajectory() this->update(); } +void CloudViewer::resetCamera() +{ + _lastCameraOrientation= _lastCameraPose = cv::Vec3f(0,0,0); + if((_aFollowCamera->isChecked() || _aLockCamera->isChecked()) && !_lastPose.isNull()) + { + // reset relative to last current pose + if(_aLockViewZ->isChecked()) + { + _visualizer->setCameraPosition( + _lastPose.x()-1, _lastPose.y(), _lastPose.z(), + _lastPose.x(), _lastPose.y(), _lastPose.z(), + 0, 0, 1); + } + else + { + _visualizer->setCameraPosition( + _lastPose.x()-1, _lastPose.y(), _lastPose.z(), + _lastPose.x(), _lastPose.y(), _lastPose.z(), + _lastPose.r31(), _lastPose.r32(), _lastPose.r33()); + } + } + else + { + _visualizer->setCameraPosition( + -1, 0, 0, + 0, 0, 0, + 0, 0, 1); + } + this->update(); +} + void CloudViewer::removeAllClouds() { _addedClouds.clear(); @@ -1506,33 +1537,7 @@ void CloudViewer::handleAction(QAction * a) } else if(a == _aResetCamera) { - _lastCameraOrientation= _lastCameraPose = cv::Vec3f(0,0,0); - if((_aFollowCamera->isChecked() || _aLockCamera->isChecked()) && !_lastPose.isNull()) - { - // reset relative to last current pose - if(_aLockViewZ->isChecked()) - { - _visualizer->setCameraPosition( - _lastPose.x()-1, _lastPose.y(), _lastPose.z(), - _lastPose.x(), _lastPose.y(), _lastPose.z(), - 0, 0, 1); - } - else - { - _visualizer->setCameraPosition( - _lastPose.x()-1, _lastPose.y(), _lastPose.z(), - _lastPose.x(), _lastPose.y(), _lastPose.z(), - _lastPose.r31(), _lastPose.r32(), _lastPose.r33()); - } - } - else - { - _visualizer->setCameraPosition( - -1, 0, 0, - 0, 0, 0, - 0, 0, 1); - } - this->update(); + this->resetCamera(); } else if(a == _aShowGrid) { diff --git a/guilib/src/MainWindow.cpp b/guilib/src/MainWindow.cpp index a57cf406..949e82af 100644 --- a/guilib/src/MainWindow.cpp +++ b/guilib/src/MainWindow.cpp @@ -145,6 +145,7 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) : _likelihoodCurve(0), _rawLikelihoodCurve(0), _autoScreenCaptureOdomSync(false), + _autoScreenCaptureRAM(false), _firstCall(true) { UDEBUG(""); @@ -174,20 +175,7 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) : this->setObjectName("MainWindow"); //Setup dock widgets position if it is the first time the application is started. - //if(!QFile::exists(PreferencesDialog::getIniFilePath())) - { - _ui->dockWidget_posterior->setVisible(false); - _ui->dockWidget_likelihood->setVisible(false); - _ui->dockWidget_rawlikelihood->setVisible(false); - _ui->dockWidget_statsV2->setVisible(false); - _ui->dockWidget_console->setVisible(false); - _ui->dockWidget_loopClosureViewer->setVisible(false); - _ui->dockWidget_mapVisibility->setVisible(false); - _ui->dockWidget_graphViewer->setVisible(false); - //_ui->dockWidget_odometry->setVisible(false); - //_ui->dockWidget_cloudViewer->setVisible(false); - //_ui->dockWidget_imageView->setVisible(false); - } + setDefaultViews(); _ui->widget_mainWindow->setVisible(false); @@ -204,7 +192,8 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) : _preferencesDialog->init(); // Restore window geometry - _preferencesDialog->loadMainWindowState(this, _savedMaximized); + bool statusBarShown = false; + _preferencesDialog->loadMainWindowState(this, _savedMaximized, statusBarShown); _preferencesDialog->loadWindowGeometry(_preferencesDialog); _preferencesDialog->loadWindowGeometry(_exportDialog); _preferencesDialog->loadWindowGeometry(_postProcessingDialog); @@ -285,6 +274,10 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) : QAction * a = _ui->menuShow_view->addAction("Progress dialog"); a->setCheckable(false); connect(a, SIGNAL(triggered(bool)), _initProgressDialog, SLOT(show())); + QAction * statusBarAction = _ui->menuShow_view->addAction("Status bar"); + statusBarAction->setCheckable(true); + statusBarAction->setChecked(statusBarShown); + connect(statusBarAction, SIGNAL(toggled(bool)), this->statusBar(), SLOT(setVisible(bool))); // connect actions with custom slots connect(_ui->actionSave_GUI_config, SIGNAL(triggered()), this, SLOT(saveConfigGUI())); @@ -325,6 +318,7 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) : connect(_ui->action480p, SIGNAL(triggered()), this, SLOT(setAspectRatio480p())); connect(_ui->action720p, SIGNAL(triggered()), this, SLOT(setAspectRatio720p())); connect(_ui->action1080p, SIGNAL(triggered()), this, SLOT(setAspectRatio1080p())); + connect(_ui->actionCustom, SIGNAL(triggered()), this, SLOT(setAspectRatioCustom())); connect(_ui->actionSave_point_cloud, SIGNAL(triggered()), this, SLOT(exportClouds())); connect(_ui->actionExport_2D_scans_ply_pcd, SIGNAL(triggered()), this, SLOT(exportScans())); connect(_ui->actionExport_2D_Grid_map_bmp_png, SIGNAL(triggered()), this, SLOT(exportGridMap())); @@ -416,6 +410,7 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) : connect(_postProcessingDialog, SIGNAL(configChanged()), this, SLOT(configGUIModified())); connect(_ui->toolBar->toggleViewAction(), SIGNAL(toggled(bool)), this, SLOT(configGUIModified())); connect(_ui->toolBar, SIGNAL(orientationChanged(Qt::Orientation)), this, SLOT(configGUIModified())); + connect(statusBarAction, SIGNAL(toggled(bool)), this, SLOT(configGUIModified())); QList dockWidgets = this->findChildren(); for(int i=0; iactionAuto_screen_capture->isChecked() && _autoScreenCaptureOdomSync) { - this->captureScreen(); + this->captureScreen(_autoScreenCaptureRAM); } } @@ -1330,7 +1325,7 @@ void MainWindow::processStats(const rtabmap::Statistics & stat) _ui->statsToolBox->updateStat("/Gui refresh stats/ms", stat.refImageId(), elapsedTime); if(_ui->actionAuto_screen_capture->isChecked() && !_autoScreenCaptureOdomSync) { - this->captureScreen(); + this->captureScreen(_autoScreenCaptureRAM); } if(!_preferencesDialog->isImagesKept()) @@ -2562,26 +2557,41 @@ void MainWindow::changeMappingMode() emit mappingModeChanged(_ui->actionSLAM_mode->isChecked()); } -QString MainWindow::captureScreen() +QString MainWindow::captureScreen(bool cacheInRAM) { - QString targetDir = _preferencesDialog->getWorkingDirectory() + QDir::separator() + "ScreensCaptured"; - QDir dir; - if(!dir.exists(targetDir)) - { - dir.mkdir(targetDir); - } - targetDir += QDir::separator(); - targetDir += "Main_window"; - if(!dir.exists(targetDir)) - { - dir.mkdir(targetDir); - } - targetDir += QDir::separator(); QString name = (QDateTime::currentDateTime().toString("yyMMddhhmmsszzz") + ".png"); _ui->statusbar->clearMessage(); QPixmap figure = QPixmap::grabWidget(this); - figure.save(targetDir + name); - QString msg = tr("Screen captured \"%1\"").arg(targetDir + name); + + QString targetDir = _preferencesDialog->getWorkingDirectory() + QDir::separator() + "ScreensCaptured"; + QString msg; + if(cacheInRAM) + { + msg = tr("Screen captured \"%1\"").arg(name); + QByteArray bytes; + QBuffer buffer(&bytes); + buffer.open(QIODevice::WriteOnly); + figure.save(&buffer, "PNG"); + _autoScreenCaptureCachedImages.insert(name, bytes); + } + else + { + QDir dir; + if(!dir.exists(targetDir)) + { + dir.mkdir(targetDir); + } + targetDir += QDir::separator(); + targetDir += "Main_window"; + if(!dir.exists(targetDir)) + { + dir.mkdir(targetDir); + } + targetDir += QDir::separator(); + + figure.save(targetDir + name); + msg = tr("Screen captured \"%1\"").arg(targetDir + name); + } _ui->statusbar->showMessage(msg, _preferencesDialog->getTimeLimit()*500); _ui->widget_console->appendMsg(msg); @@ -4131,6 +4141,9 @@ void MainWindow::setDefaultViews() _ui->dockWidget_imageView->setVisible(true); _ui->toolBar->setVisible(_state != kMonitoring && _state != kMonitoringPaused); _ui->toolBar_2->setVisible(true); + _ui->statusbar->setVisible(false); + this->setAspectRatio720p(); + _ui->widget_cloudViewer->resetCamera(); } void MainWindow::selectScreenCaptureFormat(bool checked) @@ -4151,12 +4164,56 @@ void MainWindow::selectScreenCaptureFormat(bool checked) { _autoScreenCaptureOdomSync = true; } + + if(_state != kMonitoring && _state != kMonitoringPaused) + { + int r = QMessageBox::question(this, tr("Hard drive or RAM?"), tr("Save in RAM? Images will be saved on disk when clicking auto screen capture again."), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); + if(r == QMessageBox::No || r == QMessageBox::Yes) + { + _autoScreenCaptureRAM = r == QMessageBox::Yes; + } + else + { + _ui->actionAuto_screen_capture->setChecked(false); + } + } } else { _ui->actionAuto_screen_capture->setChecked(false); } } + else if(_autoScreenCaptureCachedImages.size()) + { + QString targetDir = _preferencesDialog->getWorkingDirectory() + QDir::separator() + "ScreensCaptured"; + QDir dir; + if(!dir.exists(targetDir)) + { + dir.mkdir(targetDir); + } + targetDir += QDir::separator(); + targetDir += "Main_window"; + if(!dir.exists(targetDir)) + { + dir.mkdir(targetDir); + } + targetDir += QDir::separator(); + + _initProgressDialog->resetProgress(); + _initProgressDialog->show(); + _initProgressDialog->setMaximumSteps(_autoScreenCaptureCachedImages.size()); + int i=0; + for(QMap::iterator iter=_autoScreenCaptureCachedImages.begin(); iter!=_autoScreenCaptureCachedImages.end(); ++iter) + { + QPixmap figure; + figure.loadFromData(iter.value(), "PNG"); + figure.save(targetDir + iter.key(), "PNG"); + _initProgressDialog->appendText(tr("Saved image \"%1\" (%2/%3).").arg(targetDir + iter.key()).arg(++i).arg(_autoScreenCaptureCachedImages.size())); + _initProgressDialog->incrementStep(); + } + _autoScreenCaptureCachedImages.clear(); + _initProgressDialog->setValue(_initProgressDialog->maximumSteps()); + } } void MainWindow::takeScreenshot() @@ -4230,6 +4287,20 @@ void MainWindow::setAspectRatio1080p() this->setAspectRatio((1080*16)/9, 1080); } +void MainWindow::setAspectRatioCustom() +{ + bool ok; + int width = QInputDialog::getInt(this, tr("Aspect ratio"), tr("Width (pixels):"), this->geometry().width(), 100, 10000, 100, &ok); + if(ok) + { + int height = QInputDialog::getInt(this, tr("Aspect ratio"), tr("Height (pixels):"), this->geometry().height(), 100, 10000, 100, &ok); + if(ok) + { + this->setAspectRatio(width, height); + } + } +} + void MainWindow::exportGridMap() { double gridCellSize = 0.05; diff --git a/guilib/src/PreferencesDialog.cpp b/guilib/src/PreferencesDialog.cpp index b2c01544..be3e2d2c 100644 --- a/guilib/src/PreferencesDialog.cpp +++ b/guilib/src/PreferencesDialog.cpp @@ -40,6 +40,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include #include "ui_preferencesDialog.h" @@ -2047,12 +2048,13 @@ void PreferencesDialog::saveMainWindowState(const QMainWindow * mainWindow) settings.beginGroup(mainWindow->objectName()); settings.setValue("state", mainWindow->saveState()); settings.setValue("maximized", mainWindow->isMaximized()); + settings.setValue("status_bar", mainWindow->statusBar()->isVisible()); settings.endGroup(); // "MainWindow" settings.endGroup(); // rtabmap } } -void PreferencesDialog::loadMainWindowState(QMainWindow * mainWindow, bool & maximized) +void PreferencesDialog::loadMainWindowState(QMainWindow * mainWindow, bool & maximized, bool & statusBarShown) { if(!mainWindow->objectName().isNull()) { @@ -2068,6 +2070,8 @@ void PreferencesDialog::loadMainWindowState(QMainWindow * mainWindow, bool & ma mainWindow->restoreState(bytes); } maximized = settings.value("maximized", false).toBool(); + statusBarShown = settings.value("status_bar", false).toBool(); + mainWindow->statusBar()->setVisible(statusBarShown); settings.endGroup(); // "MainWindow" settings.endGroup(); // rtabmap } diff --git a/guilib/src/ui/mainWindow.ui b/guilib/src/ui/mainWindow.ui index 0222ab10..f87bf20d 100644 --- a/guilib/src/ui/mainWindow.ui +++ b/guilib/src/ui/mainWindow.ui @@ -238,6 +238,8 @@ + + @@ -1265,6 +1267,11 @@ g2o (*.g2o) + + + Custom... + +