My custom rqt plugin freezes after some time
Hi. I implemented a custom rqt plugin in Python. It updates 9 QLabel strings based on the data from the 2 topics that I created. Looks like it works, however after maybe 30s the gui is not updated anymore and I have to move the window in order to make it alive again. The frequency of publishing to both topics is 5 Hz. Does anyone have a clue what might be the problem?
my_plugin.py:
import os
import rospy
import rospkg
from std_msgs.msg import Int32MultiArray, String
import time
from qt_gui.plugin import Plugin
from python_qt_binding import loadUi
from python_qt_binding.QtWidgets import QWidget
class MyPlugin(Plugin):
def __init__(self, context):
super(MyPlugin, self).__init__(context)
# Give QObjects reasonable names
self.setObjectName('MyPlugin')
# Process standalone plugin command-line arguments
from argparse import ArgumentParser
parser = ArgumentParser()
# Add argument(s) to the parser.
parser.add_argument("-q", "--quiet", action="store_true",
dest="quiet",
help="Put plugin in silent mode")
args, unknowns = parser.parse_known_args(context.argv())
if not args.quiet:
print 'arguments: ', args
print 'unknowns: ', unknowns
# Create QWidget
self._widget = QWidget()
# Get path to UI file which should be in the "resource" folder of this package
ui_file = os.path.join(rospkg.RosPack().get_path('rqt_mypkg'), 'resource', 'MyPlugin.ui')
# Extend the widget with all attributes and children from UI file
loadUi(ui_file, self._widget)
# Give QObjects reasonable names
self._widget.setObjectName('MyPluginUi')
# Show _widget.windowTitle on left-top of each plugin (when
# it's set in _widget). This is useful when you open multiple
# plugins at once. Also if you open multiple instances of your
# plugin at once, these lines add number to make it easy to
# tell from pane to pane.
if context.serial_number() > 1:
self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number()))
# Add widget to the user interface
context.add_widget(self._widget)
#Subscriber
self.sub_status = rospy.Subscriber('/random_status', String, self.callback_string, queue_size=20)
self.sub = rospy.Subscriber("/random_ints", Int32MultiArray, self.callback, queue_size=20)
def shutdown_plugin(self):
# TODO unregister all publishers here
pass
def callback(self, msg):
self._widget.label_10.setText(repr(msg.data[0]))
self._widget.label_12.setText(repr(msg.data[1]))
self._widget.label_14.setText(repr(msg.data[2]))
self._widget.label_15.setText(repr(msg.data[3]))
self._widget.label_17.setText(repr(msg.data[4]))
self._widget.label_19.setText(repr(msg.data[5]))
self._widget.label_21.setText(repr(msg.data[6]))
self._widget.label_23.setText(repr(msg.data[7]))
def callback_string(self, msg):
self._widget.label_2.setText(msg.data)
def save_settings(self, plugin_settings, instance_settings):
# TODO save intrinsic configuration, usually using:
# instance_settings.set_value(k, v)
pass
def restore_settings(self, plugin_settings, instance_settings):
# TODO restore intrinsic configuration, usually using:
# v = instance_settings.value(k)
pass
#def trigger_configuration(self):
# Comment in to signal that the plugin has a way to configure
# This will enable a setting button (gear icon) in each dock widget title bar
# Usually used to open a modal configuration dialog
MyPlugin.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>913</width>
<height>527</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QGraphicsView" name="graphicsView">
<property name="geometry">
<rect>
<x>120</x>
<y>80</y>
<width>231</width>
<height>291</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_8">
<property name="geometry">
<rect>
<x>40</x>
<y>330</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_9">
<property name="geometry">
<rect>
<x>30</x>
<y>80</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Sensor7</string>
</property>
</widget>
<widget class="QLabel" name="label_10">
<property name="geometry">
<rect>
<x>30</x>
<y>100</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>140cm</string>
</property>
</widget>
<widget class="QLabel" name="label_11">
<property name="geometry">
<rect>
<x>30</x>
<y>330</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Sensor6</string>
</property>
</widget>
<widget class="QLabel" name="label_12">
<property name="geometry">
<rect>
<x>30</x>
<y>350</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>140cm</string>
</property>
</widget>
<widget class="QLabel" name="label_13">
<property name="geometry">
<rect>
<x>130</x>
<y>400</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Sensor5</string>
</property>
</widget>
<widget class="QLabel" name="label_14">
<property name="geometry">
<rect>
<x>130</x>
<y>420</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>140cm</string>
</property>
</widget>
<widget class="QLabel" name="label_15">
<property name="geometry">
<rect>
<x>280</x>
<y>420</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>140cm</string>
</property>
</widget>
<widget class="QLabel" name="label_16">
<property name="geometry">
<rect>
<x>280</x>
<y>400</y>
<width>67</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Sensor4</string>
</property>
</widget>
<widget class="QLabel" name="label_17">
<property name="geometry">
<rect>
<x>380</x>
<y>350</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>140cm</string>
</property>
</widget>
<widget class="QLabel" name="label_18">
<property name="geometry">
<rect>
<x>380</x>
<y>330</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Sensor3</string>
</property>
</widget>
<widget class="QLabel" name="label_19">
<property name="geometry">
<rect>
<x>380</x>
<y>100</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>140cm</string>
</property>
</widget>
<widget class="QLabel" name="label_20">
<property name="geometry">
<rect>
<x>380</x>
<y>80</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Sensor2</string>
</property>
</widget>
<widget class="QLabel" name="label_21">
<property name="geometry">
<rect>
<x>130</x>
<y>40</y>
<width>61</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>140cm</string>
</property>
</widget>
<widget class="QLabel" name="label_22">
<property name="geometry">
<rect>
<x>130</x>
<y>20</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Sensor0</string>
</property>
</widget>
<widget class="QLabel" name="label_23">
<property name="geometry">
<rect>
<x>270</x>
<y>40</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>140cm</string>
</property>
</widget>
<widget class="QLabel" name="label_24">
<property name="geometry">
<rect>
<x>270</x>
<y>20</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Sensor1</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>510</x>
<y>210</y>
<width>191</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>21</pointsize>
</font>
</property>
<property name="text">
<string>Status:</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>700</x>
<y>210</y>
<width>170</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>26</pointsize>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>913</width>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuSafety">
<property name="title">
<string>Control</string>
</property>
</widget>
<widget class="QMenu" name="menuControl">
<property name="title">
<string>Safety</string>
</property>
</widget>
<addaction name="menuSafety"/>
<addaction name="menuControl"/>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
`
Asked by rosuseruser on 2018-11-07 12:40:55 UTC
Comments
Hi, i am facing similar problem, I have a custom plugin displaying GPS data, and it works well, but freezes after some time, randomly... did you find any solution?
Asked by npellejero on 2019-03-27 08:46:54 UTC
Hi. I didn't use rqt at the end of the day. Basically I just switched over to qt_ros and qt_tutorials: http://wiki.ros.org/qt_tutorials?distro=kinetic
Works correctly. You have to create your own node and inherit from QNode class. For example, when you want to subscribe to some topic, you should send a signal from the callback. The slot should be implemented in the MainWindow class as well as connection between the signal and the slot.
EDIT: You might want to take a look at qlistener/qtalker demo features and investigate how to integrate your ROS design with Qt.
Asked by rosuseruser on 2019-03-27 12:43:02 UTC