Ask Your Question
4

Start launchfile from service

asked 2017-04-25 05:39:06 -0500

follesoe gravatar image

I'm looking into using the roslaunch python API to start/stop a given launch file based on service calls. The roslaunch API is fairly straight forward to work with, but I've run into a threading issue. When calling roslaunch.parent.ROSLaunchParentfrom my Service Handler function, I get the following error: Error processing request: signal only works in main thread.

This makes sense, as the documentation clearly states that ROSLaunchParent must be called from the main thread, while the service handler function is clearly running in its own thread.

So my question is: is there an easy way to switch context/execute the ROSLaunchParent call in the main thread of the node hosting the service?

The node looks like this:

from rosbag_logging.srv import *
import rospy
import roslaunch

class LoggingNode:
    def __init__(self):
        self.launch = None
        self.start_service = rospy.Service('rosbag_logging/start', StartLogging, self._srv_start_logging)
        self.stop_service = rospy.Service('rosbag_logging/stop', StopLogging, self._srv_stop_logging)
        self.status_service = rospy.Service('rosbag_logging/status', GetLoggingStatus, self._srv_status_logging)

    def _srv_start_logging(self, req):
        if self.launch == None:
            uuid = roslaunch.rlutil.get_or_generate_uuid(None, False)
            roslaunch.configure_logging(uuid)
            self.launch = roslaunch.parent.ROSLaunchParent(uuid, ['rosbag_logging.launch'])
            self.launch.start()
        return EmptyResponse()

    def _srv_stop_logging(self, req):
        if self.launch != None:
            self.launch.shutdown()
            self.launch = None
        return EmptyResponse()

    def _srv_status_logging(self, req):
        is_running = self.launch != None
        return GetLoggingStatusResponse(is_running)

if __name__ == "__main__":
    rospy.init_node('rosbag_logging')
    logging_node = LoggingNode()
    rospy.spin()
edit retag flag offensive close merge delete

Comments

The ROS capabilities provides a set of services for discovering, starting and stopping launch files using ROS services. Maybe you can use that instead of writing your own version?

ahendrix gravatar imageahendrix ( 2017-04-25 12:59:17 -0500 )edit

@follesoe Did you figure out a bespoke solution or a solution using capabilities?

surfertas gravatar imagesurfertas ( 2019-03-23 10:34:40 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2019-08-01 05:57:52 -0500

felix_v gravatar image

Not perfect but one way round this problem is to trigger launch.start() in the main thread by passing the variable self.launch generated in _srv_start_logging and any other required information to the main thread using global variables. Then in the main thread have a loop that performs the start/stop actions.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2017-04-25 05:39:06 -0500

Seen: 625 times

Last updated: Apr 25 '17