[Study Notes] Use python to launch the launch file

Project scenario:

Since when face recognition is used, cv.VideoCapture will occupy the camera device, causing the subsequent startup of the camera program to fail. Therefore, after the face recognition is completed and the occupation is released, the launch file is launched in the python file to avoid the problem of crowded occupancy.


solution:

Thanks: Using Python code to launch the launch file_wongHome's blog-CSDN blog_launch python

import roslaunch
import time

uuid = roslaunch.rlutil.get_or_generate_uuid(None, False)
roslaunch.configure_logging(uuid)
tracking_launch = roslaunch.parent.ROSLaunchParent(
    uuid, ["/home/spark/spark_noetic/src/3rd_app/move2grasp/launch/ar_grasp_ready.launch"])
tracking_launch.start()
while not rospy.is_shutdown():
    time.sleep(1)

The above is the startup code. Just replace the launch file path that needs to be started with your own.


Code interpretation

If there is any misinterpretation, please give me some advice.

Link in roswiki ( roslaunch/API Usage - ROS Wiki )

roslaunch的源代码(GitHub - ros/ros_comm: ROS communications-related packages, including core client libraries (roscpp, rospy, roslisp) and graph introspection tools (rostopic, rosnode, rosservice, rosparam).

1.uuid = roslaunch.rlutil.get_or_generate_uuid(None, False)

def get_or_generate_uuid(options_runid, options_wait_for_master)
options_runid: run_id value from command-line or None, str
options_wait_for_master: the wait_for_master command option. If this is True, it means that we must retrieve the value from the parameter server and need to avoid any race conditions with the roscore being initialized. bool
Full name: roslaunch.rlutil.get_or_generate_uuid

As you can know from the function name, this is a function that obtains or generates a run_id number. It provides two parameter choices, namely run_id and whether to wait for the master. Select none to create an id number from the parent process and not wait for the parameter server to respond.

The full statement is posted here:

def get_or_generate_uuid(options_runid, options_wait_for_master):
    """
    :param options_runid: run_id value from command-line or ``None``, ``str``
    :param options_wait_for_master: the wait_for_master command
      option. If this is True, it means that we must retrieve the
      value from the parameter server and need to avoid any race
      conditions with the roscore being initialized. ``bool``
    """

    # Three possible sources of the run_id:
    #
    #  - if we're a child process, we get it from options_runid
    #  - if there's already a roscore running, read from the param server
    #  - generate one if we're running the roscore
    if options_runid:
        return options_runid

    # #773: Generate a run_id to use if we launch a master
    # process.  If a master is already running, we'll get the
    # run_id from it instead
    param_server = rosgraph.Master('/roslaunch')
    val = None
    while val is None:
        try:
            val = param_server.getParam('/run_id')
        except:
            if not options_wait_for_master:
                val = roslaunch.core.generate_run_id()
    return val

2.roslaunch.configure_logging(uuid)

The script using roslaunch must call configure_logging and pass in the uuid just generated.

The full statement is posted here:

def configure_logging(uuid):
    """
    scripts using roslaunch MUST call configure_logging
    """
    try:
        import socket
        import rosgraph.roslogging
        logfile_basename = os.path.join(uuid, '%s-%s-%s.log'%(NAME, socket.gethostname(), os.getpid()))
        # additional: names of python packages we depend on that may also be logging
        logfile_name = rosgraph.roslogging.configure_logging(NAME, filename=logfile_basename)
        if logfile_name:
            print("... logging to %s"%logfile_name)

        # add logger to internal roslaunch logging infrastructure
        logger = logging.getLogger('roslaunch')
        roslaunch_core.add_printlog_handler(logger.info)
        roslaunch_core.add_printerrlog_handler(logger.error)
    except:
        print("WARNING: unable to configure logging. No log files will be generated", file=sys.stderr)

3.tracking_launch = roslaunch.parent.ROSLaunchParent()

class ROSLaunchParent(object):
    """
    ROSLaunchParent represents the main 'parent' roslaunch process. It
    is responsible for loading the launch files, assigning machines,
    and then starting up any remote processes. The __main__ method
    delegates most of runtime to ROSLaunchParent.

    This must be called from the Python Main thread due to signal registration.    
    """

Simply understood, it is the parent process of roslaunch, which is used to load startup files, allocate machines, and then start any remote processes.

 def __init__(self, run_id, roslaunch_files, is_core=False, port=None, local_only=False, process_listeners=None,
            verbose=False, force_screen=False, force_log=False, is_rostest=False, roslaunch_strs=None, num_workers=NUM_WORKERS, timeout=None, master_logger_level=False, show_summary=True, force_required=False,
            sigint_timeout=DEFAULT_TIMEOUT_SIGINT, sigterm_timeout=DEFAULT_TIMEOUT_SIGTERM):
        """
        @param run_id: UUID of roslaunch session
        @type  run_id: str
        @param roslaunch_files: list of launch configuration
            files to load
        @type  roslaunch_files: [str]

The main parameters are, run_id, roslaunch file

4.tracking_launch.start()

Start launch file

def start(auto_terminate=True)
Run the parent roslaunch.

@param auto_terminate: stop process monitor once there are no
more processes to monitor (default True). This defaults to
True, which is the command-line behavior of roslaunch. Scripts
may wish to set this to False if they wish to keep the
roslauch infrastructure up regardless of processes being
monitored.
Full name: roslaunch.parent.ROSLaunchParent.start

Guess you like

Origin blog.csdn.net/weixin_44362628/article/details/124097524