ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

I have found a solution that works for me be using rosbridge to remotely publish service messages to start or stop processes.

  1. First I made rosbridge and a ros2 node start on boot of the device by:

sudo vim /etc/systemd/system/ros2node.service

[Unit]
Description=Start ROS2 Node
After=network.target

[Service]
ExecStart=/bin/bash -c 'source /opt/ros/humble/setup.bash; source 
/home/ketill/Documents/ros2_script/ros2_ws/install/setup.bash; ros2 launch rosbridge_server 
rosbridge_websocket_launch.xml; ros2 run node_starter talker'
User=ketill
Environment="DISPLAY=:0"
Environment="XAUTHORITY=/run/user/1000/gdm/Xauthority"
Restart=always

[Install]
WantedBy=multi-user.target

sudo systemctl enable ros2node.service sudo systemctl start ros2node.service

and similar for the node. 2. The a node for handling the processes depending on the service message for the gui

class NavigationService(Node):

def __init__(self):
    super().__init__('navigation_service')
    self.srv = self.create_service(SetBool, 'start_navigation', self.handle_service)
    self.process = None
    self.hasStartedOnce = False

def handle_service(self, request, response):
    response.success = self.run_navigation_launch_file(request.data)
    response.message = 'Navigation launch started.' if response.success else 'Failed to start navigation launch.'
    return response

def run_navigation_launch_file(self, start):
    if start and not self.hasStartedOnce:
        command = "source /opt/ros/humble/setup.bash; source /home/ggeo/auto_gpr/install/setup.bash; ros2 launch auto_gpr bringup.launch.py"
        self.process = subprocess.Popen(command, shell=True, executable="/bin/bash", preexec_fn=os.setsid)
        self.hasStartedOnce = True
        return self.process.poll() is None  # return True if process is running
    else:
        # Implement logic to stop the process here
        if self.process is not None:
            os.killpg(os.getpgid(self.process.pid), signal.SIGINT)  # Send the signal to all the process in the group
            self.process = None
            self.hasStartedOnce = False
        return False


def main(args=None):
    rclpy.init(args=args)

navigation_service = NavigationService()

rclpy.spin(navigation_service)

navigation_service.destroy_node()
rclpy.shutdown()


if __name__ == '__main__':
main()

This solution make it possible to start remotely as long as the devices are on the same network.