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

How can I run roscore from python ?

asked 2015-08-11 01:49:42 -0500

asmodehn gravatar image

Whenever I launch a node from python using the roslaunch script api :

#Start roslaunch
launch = roslaunch.scriptapi.ROSLaunch()
launch.start()

# start required nodes
empty_srv_node = roslaunch.core.Node('rostful_node', 'emptyService.py', name='empty_service')
empty_srv_process = launch.launch(empty_srv_node)

I get an error on rospy.init_node() because master is not started :

Unable to register with master node [http://localhost:11311]: master may not be running yet. Will keep trying.

Question : How can I run roscore ( not only rosmaster ) from python if needed ? I would expect roslaunch to do it but it seems it doesnt.

Thank you.

edit retag flag offensive close merge delete

4 Answers

Sort by ยป oldest newest most voted
3

answered 2015-12-30 04:57:03 -0500

lgeorge gravatar image

I don't know the ros way to do it, and personally I use python subbprocess to run the roscore first:

import subprocess
roscore = subprocess.Popen('roscore')
time.sleep(1)  # wait a bit to be sure the roscore is really launched

then your code:

unittest.main()  # for instance in my case I need a roscore to run some node tests
edit flag offensive delete link more
3

answered 2018-05-28 02:10:18 -0500

thinwybk gravatar image

If you want to use the subprocess approach you should make sure that all processes are killed cleanly.

import subprocess
import shlex
import sys
import signal
import psutil

def kill_child_processes(parent_pid, sig=signal.SIGTERM):
    try:
        parent = psutil.Process(parent_pid)
        print(parent)
    except psutil.NoSuchProcess:
        print("parent process not existing")
        return
    children = parent.children(recursive=True)
    print(children)
    for process in children:
        print("try to kill child: " + str(process))
        process.send_signal(sig)

class Roscore(object):
    """
    roscore wrapped into a subprocess.
    Singleton implementation prevents from creating more than one instance.
    """
    __initialized = False
    def __init__(self):
        if Roscore.__initialized:
            raise Exception("You can't create more than 1 instance of Roscore.")
        Roscore.__initialized = True
    def run(self):
        try:
            self.roscore_process = subprocess.Popen(['roscore'])
            self.roscore_pid = self.roscore_process.pid  # pid of the roscore process (which has child processes)
        except OSError as e:
            sys.stderr.write('roscore could not be run')
            raise e
    def terminate(self):
        print("try to kill child pids of roscore pid: " + str(self.roscore_pid))
        kill_child_processes(self.roscore_pid)
        self.roscore_process.terminate()
        self.roscore_process.wait()  # important to prevent from zombie process
        Roscore.__initialized = False

Usage is like follows:

roscore = Roscore()
roscore.run()
roscore.terminate()
edit flag offensive delete link more

Comments

Thank you @thinwybk ! I got to learn a lot from this piece of code. This seems like a very good practice. Here is my upvote :)

archiparchi gravatar image archiparchi  ( 2022-03-23 07:46:29 -0500 )edit
2

answered 2020-12-09 03:33:41 -0500

qgallouedec gravatar image

I think this is the ROS way to do it:

import roslaunch
uuid = roslaunch.rlutil.get_or_generate_uuid(options_runid=None, options_wait_for_master=False)
roslaunch.configure_logging(uuid)
launch = roslaunch.parent.ROSLaunchParent(uuid, roslaunch_files=[], is_core=True)
launch.start()
#  --- your code ---
launch.shutdown()

You can specify your launch files as a list of string in the ROSLaunchParent constructor. Check the doc if needed.

edit flag offensive delete link more
0

answered 2015-08-11 07:41:12 -0500

Airuno2L gravatar image

Usually, a ROS application is started by running the roslaunch command in the command line and providing it a launch file. This tutorial covers the basics of roslaunch, but there are more in depth examples else where. When roslaunch is used, it starts the roscore and any nodes that are listed in the roslaunch.

Does this answer your question? If not, could you explain a little more about what you're trying to do?

edit flag offensive delete link more

Comments

1

Yes I know about roslaunch and the xml format, and how to use an xml file, instead of using a python script to start a node. But xml files are much less flexible than usual code. In my specific usecase, I need to test the behavior of a node when another node comes up and down. So I need it in code.

asmodehn gravatar image asmodehn  ( 2015-08-11 09:06:38 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2015-08-11 01:49:42 -0500

Seen: 7,331 times

Last updated: Dec 09 '20