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

how to launch a launch file from python code

asked 2012-09-02 21:37:11 -0500

karan4515 gravatar image

updated 2014-01-28 17:13:32 -0500

ngrennan gravatar image

i am working on voice and i want to launch a file from within my python script what i have tried is

if command == 'that':
        file_path =  "/opt/ros/fuerte/stacks/fuerte_workspace/dynamixel_motor/dynamixel_tutorials/launch/controller_spawner.launch"
        execfile(file_path)

[ERROR] [WallTime: 1346657638.343076] bad callback: <bound method TalkBack.talkback of <__main__.TalkBack instance at 0x9bcca8c>>
Traceback (most recent call last):
  File "/opt/ros/fuerte/lib/python2.7/dist-packages/rospy/topics.py", line 678, in _invoke_callback
    cb(msg)
  File "/opt/ros/fuerte/stacks/fuerte_workspace/pi_speech_tutorial/nodes/talkback.py", line 79, in talkback
    execfile(file_path)
  File "/opt/ros/fuerte/stacks/fuerte_workspace/dynamixel_motor/dynamixel_tutorials/launch/controller_spawner.launch", line 1
    <!-- -*- mode: XML -*- -->
    ^
SyntaxError: invalid syntax

please help

edit retag flag offensive close merge delete

5 Answers

Sort by ยป oldest newest most voted
5

answered 2012-09-02 22:04:30 -0500

Lorenz gravatar image

You cannot use execfile because it runs a python file. Launch files are xml files that describe which parameters to set and which nodes to run.

To execute a launch file, you can use subprocess.call to execute roslaunch and give it either the absolute path to your launch file or two parameters where the first is the package of your launch file and the second is the name of the file.

edit flag offensive delete link more

Comments

Given that roslaunch is implemented in python, this answer seems a little dissatisfying.

CatherineH gravatar image CatherineH  ( 2015-07-13 08:22:45 -0500 )edit
4

answered 2012-09-03 00:02:32 -0500

yigit gravatar image

I use the following line

...
os.system("roslaunch turtlebot_follower follower.launch")
...

to be able to use os.system, you need to import corresponding package

import os
edit flag offensive delete link more

Comments

This blocks the program when the os.system("xxx") ran.

sonictl gravatar image sonictl  ( 2016-12-07 01:44:38 -0500 )edit
7

answered 2015-11-03 15:24:29 -0500

afakih gravatar image

Something like this would work

  import roslaunch

  uuid = roslaunch.rlutil.get_or_generate_uuid(None, False)
  roslaunch.configure_logging(uuid)
  launch = roslaunch.parent.ROSLaunchParent(uuid, [file_path])
  launch.start()
edit flag offensive delete link more

Comments

2

@afakih this works. But I am trying to workout how you can launch along with arguments?

naveedhd gravatar image naveedhd  ( 2016-05-20 01:17:32 -0500 )edit

@naveedhd have you found out any solution to this yet?

bergercookie gravatar image bergercookie  ( 2016-11-23 16:08:27 -0500 )edit

launch.shutdown() #stops the ROSLaunchParen object. That's really cool~

sonictl gravatar image sonictl  ( 2016-12-07 02:22:57 -0500 )edit
1

arguments are supported as of lunar : http://wiki.ros.org/roslaunch/API%20U...

lucasw gravatar image lucasw  ( 2018-06-19 16:11:00 -0500 )edit

I don't intend to denounce this answer, but just want to raise an attention that as of July 2018 roslaunch API is declared as unstable.

130s gravatar image 130s  ( 2018-07-07 10:13:22 -0500 )edit
2

answered 2018-03-28 09:50:20 -0500

chrisLB gravatar image

updated 2018-03-29 06:21:18 -0500

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. 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()
edit flag offensive delete link more

Comments

Do you have a particular reason for not using the rostest infrastructure for this?

gvdhoorn gravatar image gvdhoorn  ( 2018-03-28 10:29:41 -0500 )edit

@gvdhoorn yes I am often starting/debugging my tests directly from pycharm and not requiring any launch-file-based setup simplifies this a lot.

chrisLB gravatar image chrisLB  ( 2018-03-29 02:28:22 -0500 )edit
2

answered 2021-06-04 13:29:46 -0500

m2-farzan gravatar image

In ROS 2 you need to follow these steps:

  1. Create a LaunchDescription object. If you have seen a regular python launch file, this is what generate_launch_description() returns. This object contains information about nodes to be launched, etc.

  2. Create a LaunchService object from launch python module.

  3. Pass the LaunchDescription to LaunchService using include_launch_description method of the LaunchService instance.

  4. Use run method of the LaunchService. (Use more advanced functions if you need async, etc. See more info here.)

Here's an example:

import launch
from launch.substitutions import Command
import launch_ros


def generate_launch_description():
    model_path = '/path/to/my/robot.urdf'

    robot_state_publisher_node = launch_ros.actions.Node(
        package='robot_state_publisher',
        executable='robot_state_publisher',
        parameters=[{'robot_description': Command(['xacro ', model_path])}]
    )

    spawn_entity = launch_ros.actions.Node(
        package='gazebo_ros', 
        executable='spawn_entity.py',
        arguments=['-entity', 'sam_bot', '-topic', 'robot_description'],
        output='screen'
    )

    return launch.LaunchDescription([
        launch.actions.ExecuteProcess(cmd=['gazebo', '--verbose', '-s', 'libgazebo_ros_factory.so'], output='screen'),
        robot_state_publisher_node,
        spawn_entity,
    ])


def main():
    launch_description = generate_launch_description()
    launch_service = launch.LaunchService()
    launch_service.include_launch_description(launch_description)
    launch_service.run()


if __name__ == '__main__':
    main()
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2012-09-02 21:37:11 -0500

Seen: 20,833 times

Last updated: Jun 04 '21