Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

I am using the following frequently, for instance in ros tests.

import roslaunch
package = 'package_name'
executable = 'node.py'
node_name = 'nodename'
node = roslaunch.core.Node(package=package, node_type=executable, name=node_name, output='screen')
launch = roslaunch.scriptapi.ROSLaunch()
launch.start()
process = launch.launch(node)

The only problem I still couldn't solve is, how to launch nodes outside of the main thread.

I am using the following frequently, for instance in ros tests.

import roslaunch
package = 'package_name'
executable = 'node.py'
node_name = 'nodename'
node = roslaunch.core.Node(package=package, node_type=executable, name=node_name, output='screen')
launch = roslaunch.scriptapi.ROSLaunch()
launch.start()
process = launch.launch(node)

The only problem I still couldn't solve is, how to launch nodes outside of the main thread.

[EDIT]

I have now also solved the problem about launching nodes outside the main thread within callbacks. The following code snippet illustrates the solution. It also shows, how you can start nodes with launch file programmatically.

import rospy
import os
import rospy
import rospkg
import subprocess
import roslaunch
from std_srvs.srv import Trigger, TriggerResponse

def start_node_direct():
    """
    Does work as well from service/topic callbacks directly using rosrun
    """    
    package = 'YOUR_PACKAGE'
    node_name = 'YOUR_NODE.py'

    command = "rosrun {0} {1}".format(package, node_name)

    p = subprocess.Popen(command, shell=True)

    state = p.poll()
    if state is None:
        rospy.loginfo("process is running fine")
    elif state < 0:
        rospy.loginfo("Process terminated with error")
    elif state > 0:
        rospy.loginfo("Process terminated without error")


def start_node2():
    """
    Does work as well from service/topic callbacks using launch files
    """    
    package = 'YOUR_PACKAGE'
    launch_file = 'YOUR_LAUNCHFILE.launch'

    command = "roslaunch  {0} {1}".format(package, launch_file)

    p = subprocess.Popen(command, shell=True)

    state = p.poll()
    if state is None:
        rospy.loginfo("process is running fine")
    elif state < 0:
        rospy.loginfo("Process terminated with error")
    elif state > 0:
        rospy.loginfo("Process terminated without error")

def start_node():
    """
    Does not work if called from service/topic callbacks due to main signaling issue
    """
    package = 'YOUR_PACKAGE'
    launch_file = 'YOUR_LAUNCHFILE.launch'
    uuid = roslaunch.rlutil.get_or_generate_uuid(None, False)
    roslaunch.configure_logging(uuid)
    launch_file = os.path.join(rospkg.RosPack().get_path(package), 'launch', launch_file)
    launch = roslaunch.parent.ROSLaunchParent(uuid, [launch_file])
    launch.start()

def service_callback(req):

    # edit below for other options
    #start_node()
    #start_node2()
    start_node_direct()

    return TriggerResponse(success=True)

if __name__ == '__main__':
    rospy.init_node('test1', anonymous=True)

    service = rospy.Service('launch', Trigger, service_callback)

    rospy.spin()

I am using the following frequently, for instance in ros tests.

import roslaunch
package = 'package_name'
executable = 'node.py'
node_name = 'nodename'
node = roslaunch.core.Node(package=package, node_type=executable, name=node_name, output='screen')
launch = roslaunch.scriptapi.ROSLaunch()
launch.start()
process = launch.launch(node)

The only problem I still couldn't solve is, how to launch nodes outside of the main thread.

[EDIT]

I have now also solved the problem about launching nodes outside the main thread within callbacks. The following code snippet illustrates the solution. It also shows, how you can start nodes with launch file programmatically.programmatically. However, instructing the command line programmatically is not nice but the only way I was able to make it work.

import rospy
import os
import rospy
import rospkg
import subprocess
import roslaunch
from std_srvs.srv import Trigger, TriggerResponse

def start_node_direct():
    """
    Does work as well from service/topic callbacks directly using rosrun
    """    
    package = 'YOUR_PACKAGE'
    node_name = 'YOUR_NODE.py'

    command = "rosrun {0} {1}".format(package, node_name)

    p = subprocess.Popen(command, shell=True)

    state = p.poll()
    if state is None:
        rospy.loginfo("process is running fine")
    elif state < 0:
        rospy.loginfo("Process terminated with error")
    elif state > 0:
        rospy.loginfo("Process terminated without error")


def start_node2():
    """
    Does work as well from service/topic callbacks using launch files
    """    
    package = 'YOUR_PACKAGE'
    launch_file = 'YOUR_LAUNCHFILE.launch'

    command = "roslaunch  {0} {1}".format(package, launch_file)

    p = subprocess.Popen(command, shell=True)

    state = p.poll()
    if state is None:
        rospy.loginfo("process is running fine")
    elif state < 0:
        rospy.loginfo("Process terminated with error")
    elif state > 0:
        rospy.loginfo("Process terminated without error")

def start_node():
    """
    Does not work if called from service/topic callbacks due to main signaling issue
    """
    package = 'YOUR_PACKAGE'
    launch_file = 'YOUR_LAUNCHFILE.launch'
    uuid = roslaunch.rlutil.get_or_generate_uuid(None, False)
    roslaunch.configure_logging(uuid)
    launch_file = os.path.join(rospkg.RosPack().get_path(package), 'launch', launch_file)
    launch = roslaunch.parent.ROSLaunchParent(uuid, [launch_file])
    launch.start()

def service_callback(req):

    # edit below for other options
    #start_node()
    #start_node2()
    start_node_direct()

    return TriggerResponse(success=True)

if __name__ == '__main__':
    rospy.init_node('test1', anonymous=True)

    service = rospy.Service('launch', Trigger, service_callback)

    rospy.spin()