How to rclpy.spin() a subscriber in Qt/Kivy GUI in ROS2?
Hi! I am building a small GUI which will be a node in my ROS2 foxy system. Let's call it gui_node
and it is based on the Kivy framework. I would like to start another node - subscriber
- from the code of my GUI programmatically. The subscriber subscribes to a topic and calculates its frequency which is supposed to be displayed in the Kivy label in my GUI node.
The only problem is that gui_node
must start its loop to work properly (gui_node.run()
) and the subscriber
needs rclpy.spin(subscriber)
to start subscribing to the topic. How to make these two work in ROS2? When I try to do this it does not work:
import rclpy
from rclpy.node import Node
from kivymd.app import MDApp
from kivy.lang import Builder
class Subscriber(Node):
def __init__(self, topic_name):
super().__init__('My_Subscriber')
self.subscription = self.create_subscription(
Image,
topic_name,
self.listener_callback,
10)
self.subscription # prevent unused variable warning
def listener_callback(self, msg):
# some code
class MyApp(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.subscriber = Subscriber('topic')
rclpy.spin(self.subscriber) # <---
self.screen=Builder.load_file('file.kv')
def build(self):
return self.screen
### the rest of the code here ###
def main(args=None):
rclpy.init(args=args)
gui_node = MyApp()
gui_node.run() # <---
rclpy.shutdown()
if __name__ == '__main__':
main()
Can you share your node_subscriber file. I am not sure but maybe you can try create a node. We are subscribing topics, not nodes actually but you did not create a node and you tried subscribe topic without node.
Your priority should be check the subscription, without kivy. Firstly try to subscribe topic and fix subscription and than you can continue with kivy.
https://index.ros.org/doc/ros2/Tutorials/Writing-A-Simple-Py-Publisher-And-Subscriber/#write-the-subscriber-node
@bekirbostanci I've added the definition of my
Subscriber
class in my original post as you requested. My subscriber alone works perfectly indeed. It does not, however, work with Kivy as shown in the code above - the Kivy app appears black as if the executed code did not reach thegui_node.run()
line.