Quantcast
Channel: ROS Answers: Open Source Q&A Forum - RSS feed
Viewing all articles
Browse latest Browse all 4

[ROS 2] How to start and stop a node from a Python script?

Previous: Answer by rmapsps for Context: I am running a camera using ROS. To facilitate data collection I integrated a PySimpleGui graphical user interface inside a Node, so I can start streaming, recording or playing back data through a user-friendly interface. Expected behaviour: Therefore, my goal is to execute a Node, when the user clicks on a button. For instance, if the following minimal example, I want to start a publisher Node when the user clicks on the button 'Talk'. And I want to start a subscriber Node when the user clicks on 'Listen'.Platform : I run ROS2 humble on WSL2 - Ubuntu 22.04.1 LTSCode: Here is GUI publisher, which will publish a string corresponding to the button name to the topic \gui_command when the user clicks on a button. import PySimpleGUI as sg import rclpy from rclpy.node import Node from std_msgs.msg import String def generate_layout(): layout = [[sg.Button('Talk'), sg.Button('Listen'), sg.Button('Exit')]] return layout class MinimalGuiPublisher(Node): def __init__(self): super().__init__('gui') # Initialization of the GUI self.layout = generate_layout() self.window = sg.Window('Camera recording', self.layout, location=(800, 400), finalize=True) self.values, self.event = None, '' # Initialization of the publisher self.publisher_ = self.create_publisher(String, 'gui_command', 10) timer_period = 0.2 self.timer = self.create_timer(timer_period, self.gui_callback) def gui_callback(self): msg = String() # Check for any event self.event, self.values = self.window.read() print(self.event) msg.data = str(self.event) self.publisher_.publish(msg) self.get_logger().info('Publishing: "%s"' % msg.data) if self.event in ('Exit', None): print('User clicked on Exit') exit() def main(args=None): rclpy.init(args=args) minimal_publisher = MinimalGuiServer() rclpy.spin(minimal_publisher) minimal_publisher.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() Here is the GUI subscriber that listens to the command through subscription to the topic \gui_command.import rclpy from rclpy.node import Node from std_msgs.msg import String class MinimalGuiClient(Node): def __init__(self): super().__init__('gui_client') self.subscription = self.create_subscription( String, 'gui_command', self.listener_callback, 10) self.subscription # prevent unused variable warning def listener_callback(self, msg): recorder = None self.get_logger().info('User clicked on: "%s"' % msg.data) if msg.data in ('Exit', 'None'): exit() elif msg.data == 'Talk': ###### Here start the talker like it would with ###### ros2 run py_pubsub talker pass elif msg.data == 'Listen': ###### Here start the talker like it would with ###### ros2 run py_pubsub listener pass def main(args=None): rclpy.init(args=args) minimal_subscriber = MinimalGuiClient() rclpy.spin(minimal_subscriber) minimal_subscriber.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() Question : Is it possible to program the execution of a Node from another Node? If yes, could you please indicate which is the correct way to do so? I tried to read the doc, and thought about using ros2launch (edited). But it is not clear to me if and how a node or a launch can be triggered by user interaction. Your help would be very much appreciated !!
$
0
0
**Context**: I am running a camera using ROS. To facilitate data collection I integrated a PySimpleGui graphical user interface inside a Node, so I can start streaming, recording or playing back data through a user-friendly interface. **Expected behaviour**: Therefore, my goal is to execute a Node, when the user clicks on a button. For instance, if the following minimal example, I want to start a publisher Node when the user clicks on the button 'Talk'. And I want to start a subscriber Node when the user clicks on 'Listen'. **Platform** : I run ROS2 humble on WSL2 - Ubuntu 22.04.1 LTS **Code**: Here is `GUI publisher`, which will publish a string corresponding to the button name to the topic \gui_command when the user clicks on a button. import PySimpleGUI as sg import rclpy from rclpy.node import Node from std_msgs.msg import String def generate_layout(): layout = [[sg.Button('Talk'), sg.Button('Listen'), sg.Button('Exit')]] return layout class MinimalGuiPublisher(Node): def __init__(self): super().__init__('gui') # Initialization of the GUI self.layout = generate_layout() self.window = sg.Window('Camera recording', self.layout, location=(800, 400), finalize=True) self.values, self.event = None, '' # Initialization of the publisher self.publisher_ = self.create_publisher(String, 'gui_command', 10) timer_period = 0.2 self.timer = self.create_timer(timer_period, self.gui_callback) def gui_callback(self): msg = String() # Check for any event self.event, self.values = self.window.read() print(self.event) msg.data = str(self.event) self.publisher_.publish(msg) self.get_logger().info('Publishing: "%s"' % msg.data) if self.event in ('Exit', None): print('User clicked on Exit') exit() def main(args=None): rclpy.init(args=args) minimal_publisher = MinimalGuiServer() rclpy.spin(minimal_publisher) minimal_publisher.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() Here is the `GUI subscriber` that listens to the command through subscription to the topic \gui_command. import rclpy from rclpy.node import Node from std_msgs.msg import String class MinimalGuiClient(Node): def __init__(self): super().__init__('gui_client') self.subscription = self.create_subscription( String, 'gui_command', self.listener_callback, 10) self.subscription # prevent unused variable warning def listener_callback(self, msg): recorder = None self.get_logger().info('User clicked on: "%s"' % msg.data) if msg.data in ('Exit', 'None'): exit() elif msg.data == 'Talk': ###### Here start the talker like it would with ###### ros2 run py_pubsub talker pass elif msg.data == 'Listen': ###### Here start the talker like it would with ###### ros2 run py_pubsub listener pass def main(args=None): rclpy.init(args=args) minimal_subscriber = MinimalGuiClient() rclpy.spin(minimal_subscriber) minimal_subscriber.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() **Question** : Is it possible to program the execution of a Node from another Node? If yes, could you please indicate which is the correct way to do so? I tried to read the doc, and thought about using `ros2launch` (edited). But it is not clear to me if and how a node or a launch can be triggered by user interaction. Your help would be very much appreciated !!

Viewing all articles
Browse latest Browse all 4

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>