ros-visualization / rviz

ROS 3D Robot Visualizer
BSD 3-Clause "New" or "Revised" License
791 stars 459 forks source link

Integrating rviz with mulltiple screens of PyQT. Multiple instances causing lag. #1817

Closed programmeddeath1 closed 4 months ago

programmeddeath1 commented 4 months ago

I am creating a PyQT application where im embedding my rviz simulation into two of my screens in the app. I used the python tutorial to embed it - https://docs.ros.org/en/jade/api/rviz_python_tutorial/html/index.html. The problem is I need to show the same simulation on both the screens. My code is as follows -

class BaseDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.RVIZ_FRAME = rviz.VisualizationFrame()
        self.reader = rviz.YamlConfigReader()
        self.config = rviz.Config()
        self.reader.readFile( self.config, robot_simulation_file )    
class two(BaseDialog):
    def __init__(self):
        simulationLayout = QVBoxLayout()
        simulationLabelLayout = QHBoxLayout()
        simulationLabelLayout.addWidget(QLabel("Robot Simulation"))
        simulationLayout.addLayout(simulationLabelLayout)

        #Init RVIS Frame as None
        # self.robot_sim.frame_sim = None
        # self.init_rviz()
        #Robot Simulation
        self.framerviz = rviz.VisualizationFrame()
        self.framerviz.setSplashPath( "" )
        self.framerviz.initialize()
        reader = rviz.YamlConfigReader()
        config = rviz.Config()
        reader.readFile( config, robot_simulation_file )
        self.framerviz.load( config )
        self.setWindowTitle( config.mapGetChild( "Title" ).getValue() )
        # This disable causes segmentation fault
        # self.framerviz.setMenuBar( None )
        self.framerviz.setStatusBar( None )
        self.framerviz.setHideButtonVisibility( False )        
        self.manager = self.framerviz.getManager()
        self.grid_display = self.manager.getRootDisplayGroup().getDisplayAt( 0 )
        # self.verticalFrame.addWidget(self.framerviz)
        #Robot Simulation
        self.verticalFrame.setLayout(simulationLayout)
        simulationLayout.addWidget(self.framerviz)
class three(BaseDialog):
    def __init__(self):
        mainLayout.addLayout(layout,9)
        simulationLayout = QVBoxLayout()
        simulationLabelLayout = QHBoxLayout()
        simulationLabelLayout.addWidget(self.label_14)
        simulationLayout.addLayout(simulationLabelLayout)

        layout2 = QHBoxLayout()
        mainLayout.addLayout(layout2,1)
        #Rviz to external function 
        # self.init_rviz()
        # self.verticalLayout_5.frame = None
        # # Rviz init code 
        self.verticalLayout_5.frame = self.RVIZ_FRAME
        self.verticalLayout_5.frame.setSplashPath( "" )
        self.verticalLayout_5.frame.initialize()
        self.verticalLayout_5.frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        # reader = rviz.YamlConfigReader()
        # config = rviz.Config()
        # reader.readFile( config, robot_simulation_file )
        self.verticalLayout_5.frame.load( self.config )
        self.setWindowTitle( self.config.mapGetChild( "Title" ).getValue() )
        # self.verticalLayout_5.frame.setMenuBar( None )
        self.verticalLayout_5.frame.setStatusBar( None )
        self.verticalLayout_5.frame.setHideButtonVisibility( False )        
        self.manager = self.verticalLayout_5.frame.getManager()
        self.grid_display = self.manager.getRootDisplayGroup().getDisplayAt( 0 )
        self.verticalLayout_5.addWidget(self.verticalLayout_5.frame)
        simulationLayout.addLayout( self.verticalLayout_5 )

I am running this in the init of both the screens. But the challenge with this is, its in essence loading two different instances on two different screens. Thus when I switch between the screens it keeps incrementally takes more time to render the simulation and thus the screen. Thus after a few times of switching between the screens, the entire screen loading starts lagging. The app becomes extremely heavy and laggy.

Is there a better way to load the same simulation for both the screens? I tried creating the rviz instance in the base class and loading only the config in the individual screens separately. as well as loading everything in the screen class itself. Neither of them work.

Is the lag because I am loading the simulation into each screen init separately and thus it loads newly each time both the screens are clicked?

Ill try and create a minimum reproducible example with just two screens and the render of rviz and try to post here in a few hours.

environment

Compiled against Qt version 5.12.8. Compiled against OGRE version 1.9.0 (Ghadamon).


* System locale - C.UTF-8:
rhaschke commented 4 months ago

Just a short idea (w/o reading all your code): Why do you need to load two different scenes at all? What's the difference between the two render windows? If they are identical, couldn't you simply render the same scene in both windows?

programmeddeath1 commented 4 months ago

Yeah you are right i just need to show the same scene in both the window. One window is for motor control and other is for Camera based control. Only the options around the simulation change. So Basically those are two different screens but with the same simulation to be shown.

I believe I am loading both simulations as different instances and thats probably wrong, can you guide me as to how I can use a single instance of the simulations for both screens.

programmeddeath1 commented 4 months ago

nvm, I used the same scene in both windows, the lag was being caused by a widget issue with PyQT, rviz loads the same simulation and is relatively light weight for what it does with multiple screens.