/** * This file is part of ORB-SLAM3 * * Copyright (C) 2017-2020 Carlos Campos, Richard Elvira, Juan J. Gómez Rodríguez, José M.M. Montiel and Juan D. Tardós, University of Zaragoza. * Copyright (C) 2014-2016 Raúl Mur-Artal, José M.M. Montiel and Juan D. Tardós, University of Zaragoza. * * ORB-SLAM3 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public * License as published by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ORB-SLAM3 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with ORB-SLAM3. * If not, see . */ #include "Viewer.h" #include #include namespace ORB_SLAM3 { Viewer::Viewer(System* pSystem, FrameDrawer *pFrameDrawer, MapDrawer *pMapDrawer, Tracking *pTracking, const string &strSettingPath): both(false), mpSystem(pSystem), mpFrameDrawer(pFrameDrawer),mpMapDrawer(pMapDrawer), mpTracker(pTracking), mbFinishRequested(false), mbFinished(true), mbStopped(true), mbStopRequested(false) { cv::FileStorage fSettings(strSettingPath, cv::FileStorage::READ); float fps = fSettings["Camera.fps"]; if(fps<1) fps=30; mT = 1e3/fps; mImageWidth = fSettings["Camera.width"]; mImageHeight = fSettings["Camera.height"]; if(mImageWidth<1 || mImageHeight<1) { mImageWidth = 640; mImageHeight = 480; } mViewpointX = fSettings["Viewer.ViewpointX"]; mViewpointY = fSettings["Viewer.ViewpointY"]; mViewpointZ = fSettings["Viewer.ViewpointZ"]; mViewpointF = fSettings["Viewer.ViewpointF"]; mbStopTrack = false; } void Viewer::Run() { mbFinished = false; mbStopped = false; pangolin::CreateWindowAndBind("ORB-SLAM3: Map Viewer",1024,768); // 3D Mouse handler requires depth testing to be enabled glEnable(GL_DEPTH_TEST); // Issue specific OpenGl we might need glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); pangolin::CreatePanel("menu").SetBounds(0.0,1.0,0.0,pangolin::Attach::Pix(175)); pangolin::Var menuFollowCamera("menu.Follow Camera",true,true); pangolin::Var menuCamView("menu.Camera View",false,false); pangolin::Var menuTopView("menu.Top View",false,false); // pangolin::Var menuSideView("menu.Side View",false,false); pangolin::Var menuShowPoints("menu.Show Points",true,true); pangolin::Var menuShowKeyFrames("menu.Show KeyFrames",true,true); pangolin::Var menuShowGraph("menu.Show Graph",false,true); pangolin::Var menuShowInertialGraph("menu.Show Inertial Graph",true,true); pangolin::Var menuLocalizationMode("menu.Localization Mode",false,true); pangolin::Var menuReset("menu.Reset",false,false); pangolin::Var menuStepByStep("menu.Step By Step",false,true); // false, true pangolin::Var menuStep("menu.Step",false,false); // Define Camera Render Object (for view / scene browsing) pangolin::OpenGlRenderState s_cam( pangolin::ProjectionMatrix(1024,768,mViewpointF,mViewpointF,512,389,0.1,1000), pangolin::ModelViewLookAt(mViewpointX,mViewpointY,mViewpointZ, 0,0,0,0.0,-1.0, 0.0) ); // Add named OpenGL viewport to window and provide 3D Handler pangolin::View& d_cam = pangolin::CreateDisplay() .SetBounds(0.0, 1.0, pangolin::Attach::Pix(175), 1.0, -1024.0f/768.0f) .SetHandler(new pangolin::Handler3D(s_cam)); pangolin::OpenGlMatrix Twc, Twr; Twc.SetIdentity(); pangolin::OpenGlMatrix Ow; // Oriented with g in the z axis Ow.SetIdentity(); pangolin::OpenGlMatrix Twwp; // Oriented with g in the z axis, but y and x from camera Twwp.SetIdentity(); cv::namedWindow("ORB-SLAM3: Current Frame"); bool bFollow = true; bool bLocalizationMode = false; bool bStepByStep = false; bool bCameraView = true; if(mpTracker->mSensor == mpSystem->MONOCULAR || mpTracker->mSensor == mpSystem->STEREO || mpTracker->mSensor == mpSystem->RGBD) { menuShowGraph = true; } while(1) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); mpMapDrawer->GetCurrentOpenGLCameraMatrix(Twc,Ow,Twwp); if(mbStopTrack) { menuStepByStep = true; mbStopTrack = false; } if(menuFollowCamera && bFollow) { if(bCameraView) s_cam.Follow(Twc); else s_cam.Follow(Ow); } else if(menuFollowCamera && !bFollow) { if(bCameraView) { s_cam.SetProjectionMatrix(pangolin::ProjectionMatrix(1024,768,mViewpointF,mViewpointF,512,389,0.1,1000)); s_cam.SetModelViewMatrix(pangolin::ModelViewLookAt(mViewpointX,mViewpointY,mViewpointZ, 0,0,0,0.0,-1.0, 0.0)); s_cam.Follow(Twc); } else { s_cam.SetProjectionMatrix(pangolin::ProjectionMatrix(1024,768,3000,3000,512,389,0.1,1000)); s_cam.SetModelViewMatrix(pangolin::ModelViewLookAt(0,0.01,10, 0,0,0,0.0,0.0, 1.0)); s_cam.Follow(Ow); } bFollow = true; } else if(!menuFollowCamera && bFollow) { bFollow = false; } if(menuCamView) { menuCamView = false; bCameraView = true; s_cam.SetProjectionMatrix(pangolin::ProjectionMatrix(1024,768,mViewpointF,mViewpointF,512,389,0.1,10000)); s_cam.SetModelViewMatrix(pangolin::ModelViewLookAt(mViewpointX,mViewpointY,mViewpointZ, 0,0,0,0.0,-1.0, 0.0)); s_cam.Follow(Twc); } if(menuTopView && mpMapDrawer->mpAtlas->isImuInitialized()) { menuTopView = false; bCameraView = false; /*s_cam.SetProjectionMatrix(pangolin::ProjectionMatrix(1024,768,3000,3000,512,389,0.1,1000)); s_cam.SetModelViewMatrix(pangolin::ModelViewLookAt(0,0.01,10, 0,0,0,0.0,0.0, 1.0));*/ s_cam.SetProjectionMatrix(pangolin::ProjectionMatrix(1024,768,3000,3000,512,389,0.1,10000)); s_cam.SetModelViewMatrix(pangolin::ModelViewLookAt(0,0.01,50, 0,0,0,0.0,0.0, 1.0)); s_cam.Follow(Ow); } /*if(menuSideView && mpMapDrawer->mpAtlas->isImuInitialized()) { s_cam.SetProjectionMatrix(pangolin::ProjectionMatrix(1024,768,3000,3000,512,389,0.1,10000)); s_cam.SetModelViewMatrix(pangolin::ModelViewLookAt(0.0,0.1,30.0,0,0,0,0.0,0.0,1.0)); s_cam.Follow(Twwp); }*/ if(menuLocalizationMode && !bLocalizationMode) { mpSystem->ActivateLocalizationMode(); bLocalizationMode = true; } else if(!menuLocalizationMode && bLocalizationMode) { mpSystem->DeactivateLocalizationMode(); bLocalizationMode = false; } if(menuStepByStep && !bStepByStep) { mpTracker->SetStepByStep(true); bStepByStep = true; } else if(!menuStepByStep && bStepByStep) { mpTracker->SetStepByStep(false); bStepByStep = false; } if(menuStep) { mpTracker->mbStep = true; menuStep = false; } d_cam.Activate(s_cam); glClearColor(1.0f,1.0f,1.0f,1.0f); mpMapDrawer->DrawCurrentCamera(Twc); if(menuShowKeyFrames || menuShowGraph || menuShowInertialGraph) mpMapDrawer->DrawKeyFrames(menuShowKeyFrames,menuShowGraph, menuShowInertialGraph); if(menuShowPoints) mpMapDrawer->DrawMapPoints(); pangolin::FinishFrame(); cv::Mat toShow; cv::Mat im = mpFrameDrawer->DrawFrame(true); if(both){ cv::Mat imRight = mpFrameDrawer->DrawRightFrame(); cv::hconcat(im,imRight,toShow); } else{ toShow = im; } cv::imshow("ORB-SLAM3: Current Frame",toShow); cv::waitKey(mT); if(menuReset) { menuShowGraph = true; menuShowInertialGraph = true; menuShowKeyFrames = true; menuShowPoints = true; menuLocalizationMode = false; if(bLocalizationMode) mpSystem->DeactivateLocalizationMode(); bLocalizationMode = false; bFollow = true; menuFollowCamera = true; //mpSystem->Reset(); mpSystem->ResetActiveMap(); menuReset = false; } if(Stop()) { while(isStopped()) { usleep(3000); } } if(CheckFinish()) break; } SetFinish(); } void Viewer::RequestFinish() { unique_lock lock(mMutexFinish); mbFinishRequested = true; } bool Viewer::CheckFinish() { unique_lock lock(mMutexFinish); return mbFinishRequested; } void Viewer::SetFinish() { unique_lock lock(mMutexFinish); mbFinished = true; } bool Viewer::isFinished() { unique_lock lock(mMutexFinish); return mbFinished; } void Viewer::RequestStop() { unique_lock lock(mMutexStop); if(!mbStopped) mbStopRequested = true; } bool Viewer::isStopped() { unique_lock lock(mMutexStop); return mbStopped; } bool Viewer::Stop() { unique_lock lock(mMutexStop); unique_lock lock2(mMutexFinish); if(mbFinishRequested) return false; else if(mbStopRequested) { mbStopped = true; mbStopRequested = false; return true; } return false; } void Viewer::Release() { unique_lock lock(mMutexStop); mbStopped = false; } void Viewer::SetTrackingPause() { mbStopTrack = true; } }