ARGoS
3
A parallel, multi-engine simulator for swarm robotics
|
00001 00007 #include "qtopengl_widget.h" 00008 #include "qtopengl_log_stream.h" 00009 #include "qtopengl_user_functions.h" 00010 #include "qtopengl_main_window.h" 00011 00012 #include <argos3/core/config.h> 00013 #include <argos3/core/utility/plugins/dynamic_loading.h> 00014 #include <argos3/core/utility/logging/argos_log.h> 00015 #include <argos3/core/simulator/simulator.h> 00016 00017 #include <QtCore/QVariant> 00018 #include <QtGui/QAction> 00019 #include <QtGui/QApplication> 00020 #include <QtGui/QDockWidget> 00021 #include <QtGui/QHeaderView> 00022 #include <QtGui/QLCDNumber> 00023 #include <QtGui/QPushButton> 00024 #include <QtGui/QSpinBox> 00025 #include <QtGui/QDoubleSpinBox> 00026 #include <QtGui/QStatusBar> 00027 #include <QtGui/QWidget> 00028 #include <QLabel> 00029 #include <QCloseEvent> 00030 #include <QMessageBox> 00031 #include <QDir> 00032 #include <QFile> 00033 #include <QTextStream> 00034 #include <QToolBar> 00035 #include <QLayout> 00036 #include <QMenuBar> 00037 #include <QSettings> 00038 00039 #include <cstdio> 00040 00041 namespace argos { 00042 00043 /****************************************/ 00044 /****************************************/ 00045 00046 class CQTOpenGLLayout : public QLayout { 00047 00048 public: 00049 00050 CQTOpenGLLayout() : 00051 m_pcQTOpenGLItem(NULL) { 00052 setContentsMargins(0, 0, 0, 0); 00053 } 00054 00055 virtual ~CQTOpenGLLayout() { 00056 if(m_pcQTOpenGLItem != NULL) { 00057 delete m_pcQTOpenGLItem; 00058 } 00059 } 00060 00061 virtual void addItem(QLayoutItem* item) { 00062 if(m_pcQTOpenGLItem != NULL) { 00063 delete m_pcQTOpenGLItem; 00064 } 00065 m_pcQTOpenGLItem = item; 00066 } 00067 virtual int count() const { 00068 return (m_pcQTOpenGLItem != NULL) ? 1 : 0; 00069 } 00070 00071 virtual QLayoutItem* itemAt(int index) const { 00072 return (index == 0) ? m_pcQTOpenGLItem : NULL; 00073 } 00074 00075 virtual QLayoutItem* takeAt(int index) { 00076 if(index == 0) { 00077 QLayoutItem* pcRetVal = m_pcQTOpenGLItem; 00078 m_pcQTOpenGLItem = NULL; 00079 return pcRetVal; 00080 } 00081 else { 00082 return NULL; 00083 } 00084 } 00085 00086 virtual QSize minimumSize () const { 00087 return QSize(320,240); 00088 } 00089 00090 virtual QSize sizeHint () const { 00091 return QSize(640,480); 00092 } 00093 00094 virtual void setGeometry(const QRect& r) { 00095 /* Set the layout geometry */ 00096 QLayout::setGeometry(r); 00097 if(m_pcQTOpenGLItem != NULL) { 00098 /* Calculate the candidate sizes for the QTOpenGL widget */ 00099 /* One is height-driven */ 00100 QRect cCandidate1(r.x(), r.y(), (r.height() * 4) / 3, r.height()); 00101 /* The other is width-driven */ 00102 QRect cCandidate2(r.x(), r.y(), r.width(), (r.width() * 3) / 4); 00103 /* Pick the one that fits the rectangle better */ 00104 if(r.contains(cCandidate1)) { 00105 /* Horizontal padding needed */ 00106 int nPadding = (r.width() - cCandidate1.width()) / 2; 00107 cCandidate1.translate(nPadding, 0); 00108 m_pcQTOpenGLItem->setGeometry(cCandidate1); 00109 } 00110 else { 00111 /* Vertical padding needed */ 00112 int nPadding = (r.height() - cCandidate2.height()) / 2; 00113 cCandidate2.translate(0, nPadding); 00114 m_pcQTOpenGLItem->setGeometry(cCandidate2); 00115 } 00116 } 00117 } 00118 00119 private: 00120 00121 QLayoutItem* m_pcQTOpenGLItem; 00122 00123 }; 00124 00125 /****************************************/ 00126 /****************************************/ 00127 00128 CQTOpenGLMainWindow::CQTOpenGLMainWindow(TConfigurationNode& t_tree) : 00129 m_pcUserFunctions(NULL) { 00130 /* Main window settings */ 00131 std::string strTitle; 00132 GetNodeAttributeOrDefault<std::string>(t_tree, "title", strTitle, "ARGoS v" ARGOS_VERSION "-" ARGOS_RELEASE); 00133 setWindowTitle(tr(strTitle.c_str())); 00134 /* Restore settings, if any */ 00135 ReadSettingsPreCreation(); 00136 /* Add a status bar */ 00137 m_pcStatusbar = new QStatusBar(this); 00138 setStatusBar(m_pcStatusbar); 00139 /* Create actions */ 00140 CreateSimulationActions(); 00141 CreateCameraActions(); 00142 // CreatePOVRayActions(); 00143 CreateHelpActions(); 00144 /* Create the central widget */ 00145 CreateOpenGLWidget(t_tree); 00146 /* Create menus */ 00147 CreateSimulationMenu(); 00148 CreateCameraMenu(); 00149 // CreatePOVRayMenu(); 00150 CreateHelpMenu(); 00151 /* Create toolbars */ 00152 CreateSimulationToolBar(); 00153 CreateCameraToolBar(); 00154 /* Create the message dock window */ 00155 CreateLogMessageDock(); 00156 /* Restore settings, if any */ 00157 ReadSettingsPostCreation(); 00158 /* Creates the signal/slot connections */ 00159 CreateConnections(); 00160 } 00161 00162 /****************************************/ 00163 /****************************************/ 00164 00165 CQTOpenGLMainWindow::~CQTOpenGLMainWindow() { 00166 delete m_pcUserFunctions; 00167 delete m_pcLogStream; 00168 delete m_pcLogErrStream; 00169 if(m_bWasLogColored) { 00170 LOG.EnableColoredOutput(); 00171 LOGERR.EnableColoredOutput(); 00172 } 00173 } 00174 00175 /****************************************/ 00176 /****************************************/ 00177 00178 void CQTOpenGLMainWindow::ReadSettingsPreCreation() { 00179 QSettings cSettings; 00180 cSettings.beginGroup("MainWindow"); 00181 resize(cSettings.value("size", QSize(640,480)).toSize()); 00182 move(cSettings.value("position", QPoint(0,0)).toPoint()); 00183 if(cSettings.contains("icon_dir")) { 00184 m_strIconDir = cSettings.value("icon_dir").toString(); 00185 if(m_strIconDir.at(m_strIconDir.length()-1) != '/') { 00186 m_strIconDir.append("/"); 00187 } 00188 } 00189 else { 00190 m_strIconDir = QString::fromStdString(CSimulator::GetInstance().GetInstallationDirectory()); 00191 m_strIconDir += "/include/argos3/plugins/simulator/visualizations/qt-opengl/icons/"; 00192 } 00193 if(cSettings.contains("texture_dir")) { 00194 m_strTextureDir = cSettings.value("texture_dir").toString(); 00195 if(m_strTextureDir.at(m_strIconDir.length()-1) != '/') { 00196 m_strTextureDir.append("/"); 00197 } 00198 } 00199 else { 00200 m_strTextureDir = QString::fromStdString(CSimulator::GetInstance().GetInstallationDirectory()); 00201 m_strTextureDir += "/include/argos3/plugins/simulator/visualizations/qt-opengl/textures/"; 00202 } 00203 cSettings.endGroup(); 00204 } 00205 00206 /****************************************/ 00207 /****************************************/ 00208 00209 void CQTOpenGLMainWindow::ReadSettingsPostCreation() { 00210 QSettings cSettings; 00211 cSettings.beginGroup("MainWindow"); 00212 restoreState(cSettings.value("docks").toByteArray()); 00213 cSettings.endGroup(); 00214 } 00215 00216 /****************************************/ 00217 /****************************************/ 00218 00219 void CQTOpenGLMainWindow::WriteSettings() { 00220 QSettings cSettings; 00221 cSettings.beginGroup("MainWindow"); 00222 cSettings.setValue("docks", saveState()); 00223 cSettings.setValue("size", size()); 00224 cSettings.setValue("position", pos()); 00225 cSettings.setValue("anti-aliasing", m_pcToggleAntiAliasingAction->isChecked()); 00226 cSettings.setValue("icon_dir", m_strIconDir); 00227 cSettings.setValue("texture_dir", m_strTextureDir); 00228 cSettings.endGroup(); 00229 } 00230 00231 /****************************************/ 00232 /****************************************/ 00233 00234 void CQTOpenGLMainWindow::CreateSimulationActions() { 00235 /* Add the play button */ 00236 QIcon cPlayIcon; 00237 cPlayIcon.addPixmap(QPixmap(m_strIconDir + "/play.png")); 00238 m_pcPlayAction = new QAction(cPlayIcon, tr("&Play"), this); 00239 m_pcPlayAction->setToolTip(tr("Play/pause simulation")); 00240 m_pcPlayAction->setStatusTip(tr("Play/pause simulation")); 00241 m_pcPlayAction->setCheckable(true); 00242 m_pcPlayAction->setShortcut(Qt::Key_P); 00243 /* Add the pause/step button */ 00244 QIcon cStepIcon; 00245 cStepIcon.addPixmap(QPixmap(m_strIconDir + "/step.png")); 00246 m_pcStepAction = new QAction(cStepIcon, tr("&Step"), this); 00247 m_pcStepAction->setToolTip(tr("Step simulation")); 00248 m_pcStepAction->setStatusTip(tr("Step simulation")); 00249 m_pcStepAction->setShortcut(Qt::Key_S); 00250 /* Add the fast forward button */ 00251 QIcon cFastForwardIcon; 00252 cFastForwardIcon.addPixmap(QPixmap(m_strIconDir + "/fast_forward.png")); 00253 m_pcFastForwardAction = new QAction(cFastForwardIcon, tr("&Fast Forward"), this); 00254 m_pcFastForwardAction->setToolTip(tr("Fast forward simulation")); 00255 m_pcFastForwardAction->setStatusTip(tr("Fast forward simulation")); 00256 m_pcFastForwardAction->setCheckable(true); 00257 m_pcFastForwardAction->setShortcut(Qt::Key_F); 00258 /* Add the reset button */ 00259 QIcon cResetIcon; 00260 cResetIcon.addPixmap(QPixmap(m_strIconDir + "/reset.png")); 00261 m_pcResetAction = new QAction(cResetIcon, tr("&Reset"), this); 00262 m_pcResetAction->setToolTip(tr("Reset simulation")); 00263 m_pcResetAction->setStatusTip(tr("Reset simulation")); 00264 m_pcResetAction->setShortcut(Qt::Key_R); 00265 /* Add the capture button */ 00266 QIcon cCaptureIcon; 00267 cCaptureIcon.addPixmap(QPixmap(m_strIconDir + "/record.png")); 00268 m_pcCaptureAction = new QAction(cCaptureIcon, tr("&Capture"), this); 00269 m_pcCaptureAction->setToolTip(tr("Capture frames")); 00270 m_pcCaptureAction->setStatusTip(tr("Capture frames")); 00271 m_pcCaptureAction->setCheckable(true); 00272 m_pcCaptureAction->setShortcut(Qt::Key_C); 00273 /* Add the quit button */ 00274 m_pcQuitAction = new QAction(tr("&Quit"), this); 00275 m_pcQuitAction->setStatusTip(tr("Quit the simulator")); 00276 m_pcQuitAction->setShortcut(Qt::Key_Q); 00277 } 00278 00279 /****************************************/ 00280 /****************************************/ 00281 00282 void CQTOpenGLMainWindow::CreateCameraActions() { 00283 /* Add the switch camera buttons */ 00284 m_pcSwitchCameraActionGroup = new QActionGroup(this); 00285 QIcon cCameraIcon; 00286 cCameraIcon.addPixmap(QPixmap(m_strIconDir + "/camera.png")); 00287 for(UInt32 i = 0; i < 12; ++i) { 00288 QAction* pcAction = new QAction(cCameraIcon, tr(QString("Camera %1").arg(i+1).toAscii().data()), m_pcSwitchCameraActionGroup); 00289 pcAction->setToolTip(tr(QString("Switch to camera %1").arg(i+1).toAscii().data())); 00290 pcAction->setStatusTip(tr(QString("Switch to camera %1").arg(i+1).toAscii().data())); 00291 pcAction->setCheckable(true); 00292 pcAction->setShortcut(Qt::Key_F1 + i); 00293 pcAction->setData(i); 00294 m_pcSwitchCameraActions.push_back(pcAction); 00295 } 00296 m_pcSwitchCameraActions.first()->setChecked(true); 00297 /* Add the toogle anti-aliasing button */ 00298 m_pcToggleAntiAliasingAction = new QAction(tr("&Anti-alias"), this); 00299 m_pcToggleAntiAliasingAction->setStatusTip(tr("Toogle anti-aliasing in OpenGL rendering")); 00300 m_pcToggleAntiAliasingAction->setCheckable(true); 00301 /* Add the show camera XML button */ 00302 m_pcShowCameraXMLAction = new QAction(tr("&Show XML..."), this); 00303 m_pcShowCameraXMLAction->setStatusTip(tr("Show XML configuration for all cameras")); 00304 } 00305 00306 /****************************************/ 00307 /****************************************/ 00308 00309 // void CQTOpenGLMainWindow::CreatePOVRayActions() { 00310 // /* Add the POVRay XML button */ 00311 // QIcon cPOVRayXMLIcon; 00312 // m_pcPOVRayXMLAction = new QAction(cPOVRayXMLIcon, tr("&Edit XML"), this); 00313 // m_pcPOVRayXMLAction->setToolTip(tr("Edit POV-Ray XML configuration")); 00314 // m_pcPOVRayXMLAction->setStatusTip(tr("Edit POV-Ray XML configuration")); 00315 // /* Add the POVRay Preview button */ 00316 // QIcon cPOVRayPreviewIcon; 00317 // m_pcPOVRayPreviewAction = new QAction(cPOVRayPreviewIcon, tr("&Preview"), this); 00318 // m_pcPOVRayPreviewAction->setToolTip(tr("Preview POV-Ray rendering of this scene")); 00319 // m_pcPOVRayPreviewAction->setStatusTip(tr("Preview POV-Ray rendering of this scene")); 00320 // } 00321 00322 /****************************************/ 00323 /****************************************/ 00324 00325 void CQTOpenGLMainWindow::CreateHelpActions() { 00326 /* Add the 'about qt' button */ 00327 m_pcAboutQTAction = new QAction(tr("About &Qt"), this); 00328 m_pcAboutQTAction->setStatusTip(tr("Show the Qt library's About box")); 00329 } 00330 00331 /****************************************/ 00332 /****************************************/ 00333 00334 void CQTOpenGLMainWindow::CreateSimulationToolBar() { 00335 m_pcSimulationToolBar = addToolBar(tr("Simulation")); 00336 m_pcSimulationToolBar->setObjectName("SimulationToolBar"); 00337 m_pcCurrentStepLCD = new QLCDNumber(m_pcSimulationToolBar); 00338 m_pcCurrentStepLCD->setToolTip(tr("Current step")); 00339 m_pcCurrentStepLCD->setNumDigits(6); 00340 m_pcCurrentStepLCD->setSegmentStyle(QLCDNumber::Flat); 00341 m_pcSimulationToolBar->addWidget(m_pcCurrentStepLCD); 00342 m_pcSimulationToolBar->addSeparator(); 00343 m_pcSimulationToolBar->addAction(m_pcPlayAction); 00344 m_pcSimulationToolBar->addAction(m_pcStepAction); 00345 m_pcSimulationToolBar->addAction(m_pcFastForwardAction); 00346 m_pcDrawFrameEvery = new QSpinBox(m_pcSimulationToolBar); 00347 m_pcDrawFrameEvery->setToolTip(tr("Draw frame every X steps when in fast-forward")); 00348 m_pcDrawFrameEvery->setMinimum(1); 00349 m_pcDrawFrameEvery->setMaximum(999); 00350 m_pcDrawFrameEvery->setValue(1); 00351 m_pcSimulationToolBar->addWidget(m_pcDrawFrameEvery); 00352 m_pcSimulationToolBar->addSeparator(); 00353 m_pcSimulationToolBar->addAction(m_pcResetAction); 00354 m_pcSimulationToolBar->addAction(m_pcCaptureAction); 00355 } 00356 00357 /****************************************/ 00358 /****************************************/ 00359 00360 void CQTOpenGLMainWindow::CreateSimulationMenu() { 00361 m_pcSimulationMenu = menuBar()->addMenu(tr("&Simulation")); 00362 m_pcSimulationMenu->addAction(m_pcPlayAction); 00363 m_pcSimulationMenu->addAction(m_pcStepAction); 00364 m_pcSimulationMenu->addAction(m_pcFastForwardAction); 00365 m_pcSimulationMenu->addSeparator(); 00366 m_pcSimulationMenu->addAction(m_pcResetAction); 00367 m_pcSimulationMenu->addAction(m_pcCaptureAction); 00368 m_pcSimulationMenu->addSeparator(); 00369 m_pcSimulationMenu->addAction(m_pcQuitAction); 00370 } 00371 00372 /****************************************/ 00373 /****************************************/ 00374 00375 void CQTOpenGLMainWindow::CreateCameraToolBar() { 00376 m_pcCameraToolBar = new QToolBar(tr("Camera")); 00377 m_pcCameraToolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea | Qt::BottomToolBarArea); 00378 m_pcCameraToolBar->setObjectName("CameraToolBar"); 00379 m_pcCameraToolBar->addActions(m_pcSwitchCameraActions); 00380 m_pcCameraToolBar->addSeparator(); 00381 m_pcFocalLength = new QDoubleSpinBox(m_pcCameraToolBar); 00382 m_pcFocalLength->setToolTip(tr("Set the focal length of the current camera")); 00383 m_pcFocalLength->setSuffix("mm"); 00384 m_pcFocalLength->setDecimals(1); 00385 m_pcFocalLength->setSingleStep(1.0f); 00386 m_pcFocalLength->setRange(1.0f, 999.0f); 00387 m_pcFocalLength->setValue(m_pcOpenGLWidget->GetCamera().GetSetting(0).LensFocalLength * 1000.0f); 00388 m_pcCameraToolBar->addWidget(m_pcFocalLength); 00389 addToolBar(Qt::LeftToolBarArea, m_pcCameraToolBar); 00390 } 00391 00392 /****************************************/ 00393 /****************************************/ 00394 00395 void CQTOpenGLMainWindow::CreateCameraMenu() { 00396 m_pcCameraMenu = menuBar()->addMenu(tr("&Camera")); 00397 m_pcCameraMenu->addActions(m_pcSwitchCameraActions); 00398 m_pcCameraMenu->addAction(m_pcShowCameraXMLAction); 00399 m_pcCameraMenu->addSeparator(); 00400 m_pcCameraMenu->addAction(m_pcToggleAntiAliasingAction); 00401 } 00402 00403 /****************************************/ 00404 /****************************************/ 00405 00406 // void CQTOpenGLMainWindow::CreatePOVRayMenu() { 00407 // m_pcPOVRayMenu = menuBar()->addMenu(tr("&POVRay")); 00408 // m_pcPOVRayMenu->addAction(m_pcPOVRayPreviewAction); 00409 // m_pcPOVRayMenu->addAction(m_pcPOVRayXMLAction); 00410 // } 00411 00412 /****************************************/ 00413 /****************************************/ 00414 00415 void CQTOpenGLMainWindow::CreateHelpMenu() { 00416 m_pcHelpMenu = menuBar()->addMenu(tr("&?")); 00417 m_pcHelpMenu->addAction(m_pcAboutQTAction); 00418 } 00419 00420 /****************************************/ 00421 /****************************************/ 00422 00423 void CQTOpenGLMainWindow::CreateOpenGLWidget(TConfigurationNode& t_tree) { 00424 /* Create user functions */ 00425 m_pcUserFunctions = CreateUserFunctions(t_tree); 00426 /* Initialize OpenGL settings */ 00427 QGLFormat cGLFormat; 00428 cGLFormat.setSampleBuffers(true); 00429 /* Create the widget */ 00430 QWidget* pcPlaceHolder = new QWidget(this); 00431 m_pcOpenGLWidget = new CQTOpenGLWidget(cGLFormat, pcPlaceHolder, this, *m_pcUserFunctions); 00432 m_pcOpenGLWidget->setCursor(QCursor(Qt::OpenHandCursor)); 00433 m_pcOpenGLWidget->GetCamera().Init(t_tree); 00434 m_pcOpenGLWidget->GetFrameGrabData().Init(t_tree); 00435 if(cGLFormat.sampleBuffers()) { 00436 /* Get OpenGL settings */ 00437 QSettings cSettings; 00438 bool bAntiAliasing; 00439 cSettings.beginGroup("MainWindow"); 00440 if(cSettings.contains("anti-aliasing")) { 00441 bAntiAliasing = cSettings.value("anti-aliasing").toBool(); 00442 } 00443 else { 00444 bAntiAliasing = true; 00445 } 00446 cSettings.endGroup(); 00447 m_pcToggleAntiAliasingAction->setChecked(bAntiAliasing); 00448 m_pcOpenGLWidget->SetAntiAliasing(bAntiAliasing); 00449 } 00450 else { 00451 m_pcToggleAntiAliasingAction->setChecked(false); 00452 m_pcToggleAntiAliasingAction->setEnabled(false); 00453 } 00454 /* Invert mouse controls? */ 00455 bool bInvertMouse; 00456 GetNodeAttributeOrDefault(t_tree, "invert_mouse", bInvertMouse, false); 00457 m_pcOpenGLWidget->SetInvertMouse(bInvertMouse); 00458 /* Set the window as the central widget */ 00459 CQTOpenGLLayout* pcQTOpenGLLayout = new CQTOpenGLLayout(); 00460 pcQTOpenGLLayout->addWidget(m_pcOpenGLWidget); 00461 pcPlaceHolder->setLayout(pcQTOpenGLLayout); 00462 setCentralWidget(pcPlaceHolder); 00463 } 00464 00465 /****************************************/ 00466 /****************************************/ 00467 00468 void CQTOpenGLMainWindow::CreateLogMessageDock() { 00469 /* Store the log color flag to be able to restore at exit */ 00470 m_bWasLogColored = LOG.IsColoredOutput(); 00471 /* Create a dockable window */ 00472 m_pcLogDock = new QDockWidget(tr("Log"), this); 00473 m_pcLogDock->setObjectName("LogDockWindow"); 00474 m_pcLogDock->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable); 00475 m_pcLogDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); 00476 /* Create a textual window to be used as a buffer */ 00477 m_pcDockLogBuffer = new QTextEdit(); 00478 m_pcDockLogBuffer->setReadOnly(true); 00479 LOG.Flush(); /* Write all the pending stuff */ 00480 LOG.DisableColoredOutput(); /* Colors are not necessary */ 00481 m_pcDockLogBuffer->append("<b>[t=0]</b> Log started."); /* Write something in the buffer */ 00482 /* Redirect stdout to the buffer */ 00483 m_pcLogStream = new CQTOpenGLLogStream(LOG.GetStream(), m_pcDockLogBuffer); 00484 /* Add the dockable window to the main widget */ 00485 m_pcLogDock->setWidget(m_pcDockLogBuffer); 00486 addDockWidget(Qt::RightDockWidgetArea, m_pcLogDock); 00487 /* Create a dockable window */ 00488 m_pcLogErrDock = new QDockWidget(tr("LogErr"), this); 00489 m_pcLogErrDock->setObjectName("LogErrDockWindow"); 00490 m_pcLogErrDock->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable); 00491 m_pcLogErrDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); 00492 /* Create a textual window to be used as a buffer */ 00493 m_pcDockLogErrBuffer = new QTextEdit(); 00494 m_pcDockLogErrBuffer->setReadOnly(true); 00495 LOGERR.Flush(); /* Write all the pending stuff */ 00496 LOGERR.DisableColoredOutput(); /* Colors are not necessary */ 00497 m_pcDockLogErrBuffer->append("<b>[t=0]</b> LogErr started."); /* Write something in the buffer */ 00498 /* Redirect stderr to the buffer */ 00499 m_pcLogErrStream = new CQTOpenGLLogStream(LOGERR.GetStream(), m_pcDockLogErrBuffer); 00500 m_pcLogErrDock->setWidget(m_pcDockLogErrBuffer); 00501 /* Add the dockable window to the main widget */ 00502 addDockWidget(Qt::RightDockWidgetArea, m_pcLogErrDock); 00503 00504 } 00505 00506 /****************************************/ 00507 /****************************************/ 00508 00509 void CQTOpenGLMainWindow::CreateConnections() { 00510 /* Play/pause button pressed */ 00511 connect(m_pcPlayAction, SIGNAL(triggered(bool)), 00512 m_pcOpenGLWidget, SLOT(PlayPauseSimulation(bool))); 00513 /* Step button pressed */ 00514 connect(m_pcStepAction, SIGNAL(triggered()), 00515 m_pcOpenGLWidget, SLOT(StepSimulation())); 00516 /* Fast forward button pressed */ 00517 connect(m_pcFastForwardAction, SIGNAL(triggered(bool)), 00518 m_pcOpenGLWidget, SLOT(FastForwardPauseSimulation(bool))); 00519 /* Reset button pressed */ 00520 connect(m_pcResetAction, SIGNAL(triggered()), 00521 m_pcOpenGLWidget, SLOT(ResetSimulation())); 00522 connect(m_pcResetAction, SIGNAL(triggered()), 00523 this, SLOT(ResetSimulation())); 00524 /* Capture button toggled */ 00525 connect(m_pcCaptureAction, SIGNAL(triggered(bool)), 00526 m_pcOpenGLWidget, SLOT(SetGrabFrame(bool))); 00527 // /* POV-Ray XML button pressed */ 00528 // connect(m_pcPOVRayXMLAction, SIGNAL(triggered()), 00529 // this, SLOT(POVRaySceneXMLPopUp())); 00530 // /* POV-Ray XML button pressed */ 00531 // connect(m_pcPOVRayPreviewAction, SIGNAL(triggered()), 00532 // this, SLOT(POVRayScenePreview())); 00533 /* 'Draw frame every' spin box value changed */ 00534 connect(m_pcDrawFrameEvery, SIGNAL(valueChanged(int)), 00535 m_pcOpenGLWidget, SLOT(SetDrawFrameEvery(int))); 00536 /* A simulation step has been completed */ 00537 connect(m_pcOpenGLWidget, SIGNAL(StepDone(int)), 00538 m_pcCurrentStepLCD, SLOT(display(int))); 00539 /* The simulation has been completed */ 00540 connect(m_pcOpenGLWidget, SIGNAL(SimulationDone()), 00541 this, SLOT(SimulationDone())); 00542 /* Toggle antialiasing */ 00543 connect(m_pcToggleAntiAliasingAction, SIGNAL(triggered(bool)), 00544 m_pcOpenGLWidget, SLOT(SetAntiAliasing(bool))); 00545 /* Quit the simulator */ 00546 connect(m_pcQuitAction, SIGNAL(triggered()), 00547 qApp, SLOT(quit())); 00548 /* Quit the simulator */ 00549 connect(m_pcAboutQTAction, SIGNAL(triggered()), 00550 qApp, SLOT(aboutQt())); 00551 /* Toggle the camera */ 00552 connect(m_pcSwitchCameraActionGroup, SIGNAL(triggered(QAction*)), 00553 this, SLOT(SwitchCamera(QAction*))); 00554 connect(this, SIGNAL(CameraSwitched(int)), 00555 m_pcOpenGLWidget, SLOT(SetCamera(int))); 00556 /* Camera focal length */ 00557 connect(m_pcFocalLength, SIGNAL(valueChanged(double)), 00558 m_pcOpenGLWidget, SLOT(SetCameraFocalLength(double))); 00559 /* POV-Ray XML button pressed */ 00560 connect(m_pcShowCameraXMLAction, SIGNAL(triggered()), 00561 this, SLOT(CameraXMLPopUp())); 00562 } 00563 00564 /****************************************/ 00565 /****************************************/ 00566 00567 CQTOpenGLUserFunctions* CQTOpenGLMainWindow::CreateUserFunctions(TConfigurationNode& t_tree) { 00568 /* Parse XML for user functions */ 00569 if(NodeExists(t_tree, "user_functions")) { 00570 /* Use the passed user functions */ 00571 /* Get data from XML */ 00572 TConfigurationNode tNode = GetNode(t_tree, "user_functions"); 00573 std::string strLabel, strLibrary; 00574 GetNodeAttribute(tNode, "label", strLabel); 00575 GetNodeAttributeOrDefault(tNode, "library", strLibrary, strLibrary); 00576 try { 00577 /* Load the library */ 00578 if(strLibrary != "") { 00579 CDynamicLoading::LoadLibrary(strLibrary); 00580 } 00581 /* Create the user functions */ 00582 return CFactory<CQTOpenGLUserFunctions>::New(strLabel); 00583 } 00584 catch(CARGoSException& ex) { 00585 THROW_ARGOSEXCEPTION_NESTED("Failed opening QTOpenGL user function library", ex); 00586 } 00587 } 00588 else { 00589 /* Use standard (empty) user functions */ 00590 return new CQTOpenGLUserFunctions; 00591 } 00592 } 00593 00594 /****************************************/ 00595 /****************************************/ 00596 00597 void CQTOpenGLMainWindow::closeEvent(QCloseEvent* pc_event) { 00598 WriteSettings(); 00599 pc_event->accept(); 00600 } 00601 00602 /****************************************/ 00603 /****************************************/ 00604 00605 void CQTOpenGLMainWindow::StopSimulation() { 00606 m_pcOpenGLWidget->StopSimulation(); 00607 } 00608 00609 /****************************************/ 00610 /****************************************/ 00611 00612 void CQTOpenGLMainWindow::SimulationCanProceed(bool b_allowed) { 00613 if(b_allowed) { 00614 m_pcPlayAction->setEnabled(true); 00615 m_pcStepAction->setEnabled(true); 00616 m_pcFastForwardAction->setEnabled(true); 00617 m_pcCaptureAction->setEnabled(true); 00618 } 00619 else { 00620 StopSimulation(); 00621 m_pcPlayAction->setChecked(false); 00622 m_pcPlayAction->setEnabled(false); 00623 m_pcStepAction->setEnabled(false); 00624 m_pcFastForwardAction->setChecked(false); 00625 m_pcFastForwardAction->setEnabled(false); 00626 m_pcCaptureAction->setEnabled(false); 00627 } 00628 } 00629 00630 /****************************************/ 00631 /****************************************/ 00632 00633 void CQTOpenGLMainWindow::SimulationDone() { 00634 m_pcPlayAction->setChecked(false); 00635 m_pcPlayAction->setEnabled(false); 00636 m_pcStepAction->setEnabled(false); 00637 m_pcFastForwardAction->setChecked(false); 00638 m_pcFastForwardAction->setEnabled(false); 00639 m_pcCaptureAction->setEnabled(false); 00640 } 00641 00642 /****************************************/ 00643 /****************************************/ 00644 00645 void CQTOpenGLMainWindow::ResetSimulation() { 00646 m_pcPlayAction->setChecked(false); 00647 m_pcPlayAction->setEnabled(true); 00648 m_pcStepAction->setEnabled(true); 00649 m_pcFastForwardAction->setChecked(false); 00650 m_pcFastForwardAction->setEnabled(true); 00651 m_pcCaptureAction->setEnabled(true); 00652 m_pcCurrentStepLCD->display(0); 00653 m_pcDockLogBuffer->setHtml("<b>[t=0]</b> Log restarted."); 00654 m_pcDockLogErrBuffer->setHtml("<b>[t=0]</b> LogErr restarted."); 00655 emit SimulationReset(); 00656 } 00657 00658 /****************************************/ 00659 /****************************************/ 00660 00661 void CQTOpenGLMainWindow::CameraXMLPopUp() { 00662 /* Set the text window up */ 00663 QTextEdit* pcXMLOutput = new QTextEdit(); 00664 /* Calculate the geometry of the window so that it's 1/4 of the main window 00665 and placed in the exact center of it */ 00666 QRect cGeom = geometry(); 00667 cGeom.setBottomRight(geometry().center()); 00668 cGeom.moveCenter(geometry().center()); 00669 pcXMLOutput->setGeometry(cGeom); 00670 /* This window steals all input */ 00671 pcXMLOutput->setWindowModality(Qt::ApplicationModal); 00672 /* You can't modify its contents (but can copy-paste them) */ 00673 pcXMLOutput->setReadOnly(true); 00674 /* Set nice document name and window title */ 00675 pcXMLOutput->setDocumentTitle("ARGoS XML camera config"); 00676 pcXMLOutput->setWindowTitle("ARGoS XML camera config"); 00677 /* Set the actual text to visualize */ 00678 pcXMLOutput->setPlainText(GetCameraXMLData()); 00679 /* Finally, show the resulting window */ 00680 pcXMLOutput->show(); 00681 } 00682 00683 /****************************************/ 00684 /****************************************/ 00685 00686 // void CQTOpenGLMainWindow::POVRaySceneXMLPopUp() { 00687 // /* Set the text window up */ 00688 // QTextEdit* pcPOVRayOutput = new QTextEdit(); 00689 // /* Calculate the geometry of the window so that it's 1/4 of the main window 00690 // and placed in the exact center of it */ 00691 // QRect cGeom = geometry(); 00692 // cGeom.setBottomRight(geometry().center()); 00693 // cGeom.moveCenter(geometry().center()); 00694 // pcPOVRayOutput->setGeometry(cGeom); 00695 // /* This window steals all input */ 00696 // pcPOVRayOutput->setWindowModality(Qt::ApplicationModal); 00697 // /* You can't modify its contents (but can copy-paste them) */ 00698 // pcPOVRayOutput->setReadOnly(true); 00699 // /* Set nice document name and window title */ 00700 // pcPOVRayOutput->setDocumentTitle("ARGoS-POVRay XML camera config"); 00701 // pcPOVRayOutput->setWindowTitle("ARGoS-POVRay XML camera config"); 00702 // /* Set the actual text to visualize */ 00703 // pcPOVRayOutput->setPlainText(GetPOVRaySceneXMLData()); 00704 // /* Finally, show the resulting window */ 00705 // pcPOVRayOutput->show(); 00706 // } 00707 00708 /****************************************/ 00709 /****************************************/ 00710 00711 QString CQTOpenGLMainWindow::GetCameraXMLData() { 00712 QString strResult("<camera>\n"); 00713 /* Get a reference to the camera */ 00714 CQTOpenGLCamera& cCamera = m_pcOpenGLWidget->GetCamera(); 00715 for(UInt32 i = 0; i < 12; ++i) { 00716 /* Get its position and target */ 00717 const CQTOpenGLCamera::SSettings& sSettings = cCamera.GetSetting(i); 00718 const CVector3& cPos = sSettings.Position; 00719 const CVector3& cLookAt = sSettings.Target; 00720 strResult.append( 00721 QString(" <placement idx=\"%1\" position=\"%2,%3,%4\" look_at=\"%5,%6,%7\" lens_focal_length=\"%8\" />\n") 00722 .arg(i) 00723 .arg(cPos.GetX()) 00724 .arg(cPos.GetY()) 00725 .arg(cPos.GetZ()) 00726 .arg(cLookAt.GetX()) 00727 .arg(cLookAt.GetY()) 00728 .arg(cLookAt.GetZ()) 00729 .arg(sSettings.LensFocalLength * 1000.0f)); 00730 } 00731 strResult.append("</camera>\n"); 00732 return strResult; 00733 } 00734 00735 /****************************************/ 00736 /****************************************/ 00737 00738 // QString CQTOpenGLMainWindow::GetPOVRaySceneXMLData() { 00739 // /* Get the current simulation step */ 00740 // UInt32 unStep = CSimulator::GetInstance().GetSpace().GetSimulationClock(); 00741 // /* Get a reference to the camera */ 00742 // const CQTOpenGLCamera& cCamera = m_pcOpenGLWidget->GetCamera(); 00743 // /* Get its current position and target */ 00744 // const CVector3& cPos = cCamera.GetPosition(); 00745 // const CVector3& cLookAt = cCamera.GetTarget(); 00746 // /* Get the environment node and its contents from the 'povray_render', if defined */ 00747 // TConfigurationNode& tExperiment = CSimulator::GetInstance().GetConfigurationRoot(); 00748 // TConfigurationNode& tVisualization = GetNode(tExperiment, "visualization"); 00749 // QString strPOVRayEnvironment; 00750 // if(NodeExists(tVisualization,"povray_render")) { 00751 // TConfigurationNode& tPOVRayVisualization = GetNode(tVisualization, "povray_render"); 00752 // TConfigurationNode& tPOVRayEnvironment = GetNode(tPOVRayVisualization, "environment"); 00753 // std::string strPOVRayEnvironmentNodeContent = tPOVRayEnvironment.ToString(tPOVRayEnvironment); 00754 // strPOVRayEnvironment = strPOVRayEnvironmentNodeContent.c_str(); 00755 // } 00756 00757 // /* Return the XML portion */ 00758 // return QString( 00759 // "%1\n" 00760 // "<scene step=\"%2\">\n" 00761 // " <camera type=\"normal\"\n" 00762 // " position=\"%3,%4,%5\"\n" 00763 // " look_at=\"%6,%7,%8\"\n" 00764 // " focal_length=\"%9\" />\n" 00765 // "</scene>\n" 00766 // ) 00767 // .arg(strPOVRayEnvironment) 00768 // .arg(unStep) 00769 // .arg(cPos.GetX()) 00770 // .arg(cPos.GetY()) 00771 // .arg(cPos.GetZ()) 00772 // .arg(cLookAt.GetX()) 00773 // .arg(cLookAt.GetY()) 00774 // .arg(cLookAt.GetZ()) 00775 // .arg(cCamera.GetLensFocalLength() * 1000.0f); 00776 // } 00777 00778 /****************************************/ 00779 /****************************************/ 00780 00781 // void CQTOpenGLMainWindow::POVRayScenePreview() { 00782 // try { 00783 // /* Initialize the POV-Ray working directory */ 00784 // QDir cDirectory(QDir::tempPath() + "/argos-povray"); 00785 // /* Erase it if it exists */ 00786 // if(cDirectory.exists()) { 00787 // if(::system(QString("rm -rf %1").arg(cDirectory.absolutePath()).toAscii().data()) != 0) { 00788 // THROW_ARGOSEXCEPTION("Could not remove directory \"" << 00789 // cDirectory.absolutePath().toAscii().data() << "\"."); 00790 // } 00791 // } 00792 // /* Create the directory */ 00793 // if(::system(QString("mkdir %1").arg(cDirectory.absolutePath()).toAscii().data()) != 0) { 00794 // THROW_ARGOSEXCEPTION("Could not create directory \"" << 00795 // cDirectory.absolutePath().toAscii().data() << "\"."); 00796 // } 00797 // /* Now create the XML file that will contain the POV-Ray scene configuration */ 00798 // QFile cPOVRayXMLConf(cDirectory.absolutePath() + "/argos-povray.xml"); 00799 // cPOVRayXMLConf.open(QFile::WriteOnly | QFile::Truncate); 00800 // /* Associate a text stream to perform writing to it */ 00801 // QTextStream cPOVRayXMLConfStream(&cPOVRayXMLConf); 00802 // /* Write the configuration */ 00803 // cPOVRayXMLConfStream << "<povray_render id=\"pov\" output_folder=\"" << cDirectory.absolutePath() << "\">\n"; 00804 // cPOVRayXMLConfStream << GetPOVRaySceneXMLData(); 00805 // cPOVRayXMLConfStream << "</povray_render>\n"; 00806 // cPOVRayXMLConf.close(); 00807 // /* Now parse this file as an ARGoS TConfigurationTree */ 00808 // ticpp::Document tPOVRayXMLConfTree(cPOVRayXMLConf.fileName().toAscii().data()); 00809 // tPOVRayXMLConfTree.LoadFile(); 00810 // /* It's time to create the POV-Ray visualization */ 00811 // CPovrayRender cPOVRayRender; 00812 // cPOVRayRender.Init(*tPOVRayXMLConfTree.FirstChildElement()); 00813 // /* Write the .pov frame file */ 00814 // cPOVRayRender.WriteOneFrame(cDirectory.absolutePath().append("/pov/frame.pov").toAscii().data()); 00815 // /* Eventually, call POV-Ray to render the file */ 00816 // if(::system(QString("cd %1 && ") 00817 // .arg(cDirectory.absolutePath()) 00818 // .append("./render_single_frame_on_pc.sh pov/frame.pov") 00819 // .toAscii().data()) !=0) { 00820 // THROW_ARGOSEXCEPTION("Could not create POV-Ray preview"); 00821 // } 00822 // } 00823 // catch(CARGoSException& ex) { 00824 // QString strError = QString("Error creating POV-Ray preview\n%1").arg(QString(ex.what())); 00825 // QMessageBox::critical(this, 00826 // tr("ARGoS v2.0"), 00827 // strError, 00828 // QMessageBox::Ok); 00829 // } 00830 // } 00831 00832 /****************************************/ 00833 /****************************************/ 00834 00835 void CQTOpenGLMainWindow::SwitchCamera(QAction* pc_action) { 00836 emit CameraSwitched(pc_action->data().toInt()); 00837 m_pcFocalLength->setValue(m_pcOpenGLWidget->GetCamera().GetActiveSettings().LensFocalLength * 1000.0f); 00838 } 00839 00840 /****************************************/ 00841 /****************************************/ 00842 00843 }