mirror of
https://github.com/introlab/rtabmap.git
synced 2026-10-04 17:17:47 +08:00
Added dialogs when starting/stopping sensors/detection. Fixed nullptr bug on MainWindow::handleEvents
This commit is contained in:
@@ -52,6 +52,10 @@ int main(int argc, char* argv[])
|
|||||||
ULogger::setLevel(ULogger::kWarning);
|
ULogger::setLevel(ULogger::kWarning);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
// STA (single-threaded apartment) is required for the native file dialogs / File Explorer
|
||||||
|
// (see commit d75cc04, "Fixed File Explorer hanging (Qt 5.12)"). Do NOT switch to MTA
|
||||||
|
// (CoInitializeEx COINIT_MULTITHREADED): it deadlocks the
|
||||||
|
// native file dialogs.
|
||||||
CoInitialize(nullptr);
|
CoInitialize(nullptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <QtCore/QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
#include <QProgressDialog>
|
||||||
#include <QGraphicsEllipseItem>
|
#include <QGraphicsEllipseItem>
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
#include <QtCore/QBuffer>
|
#include <QtCore/QBuffer>
|
||||||
@@ -958,7 +959,7 @@ bool MainWindow::handleEvent(UEvent* anEvent)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Q_EMIT cameraInfoReceived(sensorEvent->info());
|
Q_EMIT cameraInfoReceived(sensorEvent->info());
|
||||||
if (_odomThread == 0 && (_sensorCapture->odomProvided()) && _preferencesDialog->isRGBDMode())
|
if (_odomThread == 0 && _sensorCapture && _sensorCapture->odomProvided() && _preferencesDialog->isRGBDMode())
|
||||||
{
|
{
|
||||||
OdometryInfo odomInfo;
|
OdometryInfo odomInfo;
|
||||||
odomInfo.reg.covariance = sensorEvent->info().odomCovariance;
|
odomInfo.reg.covariance = sensorEvent->info().odomCovariance;
|
||||||
@@ -5932,6 +5933,18 @@ void MainWindow::startDetection()
|
|||||||
Camera * camera = 0;
|
Camera * camera = 0;
|
||||||
Lidar * lidar = 0;
|
Lidar * lidar = 0;
|
||||||
|
|
||||||
|
// Creating the sensors below opens the devices (createLidar/createCamera/createOdomSensor ->
|
||||||
|
// init(), a few seconds for ZED/RealSense) on the GUI thread; show a busy dialog (min==max==0
|
||||||
|
// => indeterminate) so the window isn't just frozen. Hidden once all sensors are created below.
|
||||||
|
QProgressDialog progress(tr("Starting detection..."), QString(), 0, 0, this);
|
||||||
|
progress.setWindowModality(Qt::ApplicationModal);
|
||||||
|
progress.setCancelButton(0);
|
||||||
|
progress.setMinimumDuration(0);
|
||||||
|
progress.setValue(0);
|
||||||
|
progress.show();
|
||||||
|
QApplication::processEvents();
|
||||||
|
QApplication::processEvents(); // make sure it is drawn
|
||||||
|
|
||||||
if(_preferencesDialog->getLidarSourceDriver() != PreferencesDialog::kSrcUndef)
|
if(_preferencesDialog->getLidarSourceDriver() != PreferencesDialog::kSrcUndef)
|
||||||
{
|
{
|
||||||
lidar = _preferencesDialog->createLidar();
|
lidar = _preferencesDialog->createLidar();
|
||||||
@@ -5989,6 +6002,8 @@ void MainWindow::startDetection()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progress.hide(); // all sensors created/opened
|
||||||
|
|
||||||
_sensorCapture = new SensorCaptureThread(lidar, camera, odomSensor, extrinsics, poseTimeOffset, scaleFactor, waitTime, parameters);
|
_sensorCapture = new SensorCaptureThread(lidar, camera, odomSensor, extrinsics, poseTimeOffset, scaleFactor, waitTime, parameters);
|
||||||
|
|
||||||
_sensorCapture->setOdomAsGroundTruth(_preferencesDialog->isOdomSensorAsGt());
|
_sensorCapture->setOdomAsGroundTruth(_preferencesDialog->isOdomSensorAsGt());
|
||||||
@@ -6229,6 +6244,24 @@ void MainWindow::stopDetection()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ULOGGER_DEBUG("");
|
ULOGGER_DEBUG("");
|
||||||
|
|
||||||
|
// Closing the camera runs on the GUI thread in "delete _sensorCapture" below (via
|
||||||
|
// ~SensorCaptureThread -> ~Camera::close()) and can block for a while - e.g. the first 2-3
|
||||||
|
// RealSense closes per launch stall ~20s in the Motion Module stop() (librealsense warm-up).
|
||||||
|
// Show a busy dialog (min==max==0 => indeterminate) so the window isn't just frozen. It is
|
||||||
|
// declared here so it stays visible across the joins/deletes and closes on scope exit.
|
||||||
|
QProgressDialog progress(tr("Stopping detection..."), QString(), 0, 0, this);
|
||||||
|
if(_sensorCapture)
|
||||||
|
{
|
||||||
|
progress.setWindowModality(Qt::ApplicationModal);
|
||||||
|
progress.setCancelButton(0);
|
||||||
|
progress.setMinimumDuration(0);
|
||||||
|
progress.setValue(0);
|
||||||
|
progress.show();
|
||||||
|
QApplication::processEvents();
|
||||||
|
QApplication::processEvents(); // make sure it is drawn
|
||||||
|
}
|
||||||
|
|
||||||
// kill the processes
|
// kill the processes
|
||||||
if(_imuThread)
|
if(_imuThread)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <QtGui/QStandardItemModel>
|
#include <QtGui/QStandardItemModel>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QProgressDialog>
|
#include <QProgressDialog>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <functional>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QStatusBar>
|
#include <QStatusBar>
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
@@ -7745,7 +7747,20 @@ void PreferencesDialog::setSLAMMode(bool enabled)
|
|||||||
|
|
||||||
void PreferencesDialog::testOdometry()
|
void PreferencesDialog::testOdometry()
|
||||||
{
|
{
|
||||||
|
// One progress dialog, reused for both the (slow) camera init and the (slow) close.
|
||||||
|
// Declared here so it outlives cameraThread below and stays visible while cameraThread's
|
||||||
|
// destructor closes the device at function scope end.
|
||||||
|
QProgressDialog progress(tr("Starting camera..."), QString(), 0, 0, this);
|
||||||
|
progress.setWindowModality(Qt::ApplicationModal);
|
||||||
|
progress.setCancelButton(0);
|
||||||
|
progress.setMinimumDuration(0);
|
||||||
|
progress.setValue(0);
|
||||||
|
progress.show();
|
||||||
|
QApplication::processEvents();
|
||||||
|
QApplication::processEvents(); // make sure it is drawn
|
||||||
|
|
||||||
Camera * camera = this->createCamera();
|
Camera * camera = this->createCamera();
|
||||||
|
progress.hide();
|
||||||
if(!camera)
|
if(!camera)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -7861,6 +7876,7 @@ void PreferencesDialog::testOdometry()
|
|||||||
}
|
}
|
||||||
|
|
||||||
odomViewer->exec();
|
odomViewer->exec();
|
||||||
|
UDEBUG("Dialog closed, stopping sensor...");
|
||||||
|
|
||||||
// Tear down the pipes first so no more events are routed to the threads/viewer being
|
// Tear down the pipes first so no more events are routed to the threads/viewer being
|
||||||
// destroyed, then stop the threads, then delete the viewer. This avoids delivering
|
// destroyed, then stop the threads, then delete the viewer. This avoids delivering
|
||||||
@@ -7877,6 +7893,14 @@ void PreferencesDialog::testOdometry()
|
|||||||
{
|
{
|
||||||
imuThread->join(true);
|
imuThread->join(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reuse the same dialog for the close. The device close() runs in cameraThread's destructor
|
||||||
|
// at function scope end (not in join()), so 'progress' stays visible across it. On Windows
|
||||||
|
// the first 2-3 RealSense closes per launch stall ~20s in the Motion Module stop().
|
||||||
|
progress.setLabelText(tr("Closing camera..."));
|
||||||
|
progress.show();
|
||||||
|
QApplication::processEvents();
|
||||||
|
QApplication::processEvents(); // make sure it is drawn
|
||||||
cameraThread.join(true);
|
cameraThread.join(true);
|
||||||
odomThread.join(true);
|
odomThread.join(true);
|
||||||
|
|
||||||
@@ -7900,7 +7924,21 @@ void PreferencesDialog::testCamera()
|
|||||||
window->resize(1280, 480+QPushButton().minimumHeight());
|
window->resize(1280, 480+QPushButton().minimumHeight());
|
||||||
window->registerToEventsManager();
|
window->registerToEventsManager();
|
||||||
|
|
||||||
|
// One progress dialog, reused for both the (slow) camera init and the (slow) close.
|
||||||
|
// min==max==0 => indeterminate/busy bar. Declared in this outer scope so it outlives
|
||||||
|
// cameraThread below and stays visible while cameraThread's destructor closes the device.
|
||||||
|
QProgressDialog progress(tr("Starting camera..."), QString(), 0, 0, this);
|
||||||
|
progress.setWindowModality(Qt::ApplicationModal);
|
||||||
|
progress.setCancelButton(0);
|
||||||
|
progress.setMinimumDuration(0);
|
||||||
|
progress.setValue(0);
|
||||||
|
progress.show();
|
||||||
|
QApplication::processEvents();
|
||||||
|
QApplication::processEvents(); // make sure it is drawn
|
||||||
|
|
||||||
|
// createCamera() init()s the device on the GUI thread (required by ZED) and takes a few seconds.
|
||||||
Camera * camera = this->createCamera();
|
Camera * camera = this->createCamera();
|
||||||
|
progress.hide();
|
||||||
if(camera)
|
if(camera)
|
||||||
{
|
{
|
||||||
SensorCaptureThread cameraThread(camera, this->getAllParameters());
|
SensorCaptureThread cameraThread(camera, this->getAllParameters());
|
||||||
@@ -7945,8 +7983,18 @@ void PreferencesDialog::testCamera()
|
|||||||
|
|
||||||
cameraThread.start();
|
cameraThread.start();
|
||||||
window->exec();
|
window->exec();
|
||||||
|
UDEBUG("Dialog closed, stopping sensor...");
|
||||||
UEventsManager::removePipe(&cameraThread, window, "SensorEvent");
|
UEventsManager::removePipe(&cameraThread, window, "SensorEvent");
|
||||||
cameraThread.join(true);
|
|
||||||
|
// Reuse the same dialog for the close. The device close() runs in cameraThread's
|
||||||
|
// destructor at scope end (not in join()), so 'progress' - declared in the outer scope -
|
||||||
|
// stays visible across it. On Windows the first 2-3 RealSense closes per launch stall
|
||||||
|
// ~20s in the Motion Module stop() (librealsense warm-up); this keeps the user informed.
|
||||||
|
progress.setLabelText(tr("Closing camera..."));
|
||||||
|
progress.show();
|
||||||
|
QApplication::processEvents();
|
||||||
|
QApplication::processEvents(); // make sure it is drawn
|
||||||
|
cameraThread.join(true); // cameraThread's destructor (scope end) closes the device
|
||||||
// deleteLater() (not delete): defer destruction to the event loop so Qt finishes
|
// deleteLater() (not delete): defer destruction to the event loop so Qt finishes
|
||||||
// tearing down the OpenGL widget's context and window-proc subclass and drains
|
// tearing down the OpenGL widget's context and window-proc subclass and drains
|
||||||
// pending activation messages first.
|
// pending activation messages first.
|
||||||
@@ -8428,7 +8476,20 @@ void PreferencesDialog::testLidar()
|
|||||||
window->registerToEventsManager();
|
window->registerToEventsManager();
|
||||||
window->setDecimation(1);
|
window->setDecimation(1);
|
||||||
|
|
||||||
|
// One progress dialog, reused for both the (slow) sensor init and the (slow) close.
|
||||||
|
// Declared in this outer scope so it outlives lidarThread below and stays visible while
|
||||||
|
// lidarThread's destructor closes the device.
|
||||||
|
QProgressDialog progress(tr("Starting sensor..."), QString(), 0, 0, this);
|
||||||
|
progress.setWindowModality(Qt::ApplicationModal);
|
||||||
|
progress.setCancelButton(0);
|
||||||
|
progress.setMinimumDuration(0);
|
||||||
|
progress.setValue(0);
|
||||||
|
progress.show();
|
||||||
|
QApplication::processEvents();
|
||||||
|
QApplication::processEvents(); // make sure it is drawn
|
||||||
|
|
||||||
Lidar * lidar = this->createLidar();
|
Lidar * lidar = this->createLidar();
|
||||||
|
progress.hide();
|
||||||
if(lidar)
|
if(lidar)
|
||||||
{
|
{
|
||||||
SensorCaptureThread lidarThread(lidar, this->getAllParameters());
|
SensorCaptureThread lidarThread(lidar, this->getAllParameters());
|
||||||
@@ -8447,8 +8508,17 @@ void PreferencesDialog::testLidar()
|
|||||||
|
|
||||||
lidarThread.start();
|
lidarThread.start();
|
||||||
window->exec();
|
window->exec();
|
||||||
|
UDEBUG("Dialog closed, stopping sensor...");
|
||||||
UEventsManager::removePipe(&lidarThread, window, "SensorEvent");
|
UEventsManager::removePipe(&lidarThread, window, "SensorEvent");
|
||||||
lidarThread.join(true);
|
|
||||||
|
// Reuse the same dialog for the close. The device close() runs in lidarThread's
|
||||||
|
// destructor at scope end (not in join()), so 'progress' - declared in the outer
|
||||||
|
// scope - stays visible across it.
|
||||||
|
progress.setLabelText(tr("Closing sensor..."));
|
||||||
|
progress.show();
|
||||||
|
QApplication::processEvents();
|
||||||
|
QApplication::processEvents(); // make sure it is drawn
|
||||||
|
lidarThread.join(true); // lidarThread's destructor (scope end) closes the device
|
||||||
// deleteLater() (not delete): see testCamera() - avoids a dangling OpenGL platform
|
// deleteLater() (not delete): see testCamera() - avoids a dangling OpenGL platform
|
||||||
// window that crashes in QWindowsWindow::alertWindow when Preferences later closes.
|
// window that crashes in QWindowsWindow::alertWindow when Preferences later closes.
|
||||||
window->deleteLater();
|
window->deleteLater();
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ void sighandler(int sig)
|
|||||||
int main(int argc, char * argv[])
|
int main(int argc, char * argv[])
|
||||||
{
|
{
|
||||||
ULogger::setType(ULogger::kTypeConsole);
|
ULogger::setType(ULogger::kTypeConsole);
|
||||||
ULogger::setLevel(ULogger::kInfo);
|
ULogger::setLevel(ULogger::kDebug);
|
||||||
//ULogger::setPrintTime(false);
|
//ULogger::setPrintTime(false);
|
||||||
//ULogger::setPrintWhere(false);
|
//ULogger::setPrintWhere(false);
|
||||||
|
|
||||||
@@ -272,7 +272,7 @@ int main(int argc, char * argv[])
|
|||||||
UERROR("Not built with ZED sdk support...");
|
UERROR("Not built with ZED sdk support...");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
camera = new rtabmap::CameraStereoZed(deviceId.empty()?0:uStr2Int(deviceId), -1, 1, 100, false, rate);
|
camera = new rtabmap::CameraStereoZed(deviceId.empty()?0:uStr2Int(deviceId), -1, 1, 0, 100, false, rate);
|
||||||
}
|
}
|
||||||
else if (driver == 9)
|
else if (driver == 9)
|
||||||
{
|
{
|
||||||
@@ -523,5 +523,6 @@ int main(int argc, char * argv[])
|
|||||||
cameraViewer.exec();
|
cameraViewer.exec();
|
||||||
cameraThread.join(true);
|
cameraThread.join(true);
|
||||||
}
|
}
|
||||||
|
printf("Exiting cleanly.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -404,13 +404,16 @@ int main (int argc, char * argv[])
|
|||||||
{
|
{
|
||||||
printf("The camera is not calibrated! You should calibrate the camera first.\n");
|
printf("The camera is not calibrated! You should calibrate the camera first.\n");
|
||||||
delete camera;
|
delete camera;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("Failed to initialize the camera! Please select another driver (see \"--help\").\n");
|
printf("Failed to initialize the camera! Please select another driver (see \"--help\").\n");
|
||||||
delete camera;
|
delete camera;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Exiting cleanly.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user