Skip to content

Launch Files

Tom Howard edited this page Mar 29, 2022 · 9 revisions

Advanced Features

Quick Links

Overview

As you'll know by now, we execute Nodes on a ROS network using the rosrun command:

rosrun {package name} {script name}

Alternatively though, we also have the option of using roslaunch:

roslaunch {package name} {launch file}

... where (as we learnt in Week 1) a {launch file} is an xml file with a .launch file extension. Inside this we can ask ROS to do lots of things at the same time, from one single roslaunch command-line call.

roslaunch therefore offers a number of advantages over rosrun:

  • Multiple nodes can be executed simultaneously.
  • roslaunch will launch the ROS Master for us, if isn't already running (so we don't have to manually call roscore).
  • From within one .launch file, we can launch other .launch files.
  • We can pass in additional arguments to launch certain things conditionally, or pass specific arguments to certain ROS nodes.
  • As if that wasn't enough, there is also a roslaunch Python API, allowing us to launch nodes from within other (Python) nodes!

On this page we will talk about some features that may be useful for you.

Launching Other Launch Files

Let's think back to the move_circle.py node that we created in Week 2. We need a simulation of our robot active in order to run this, which we can enable with the following command (which you should be very familiar with by now):

$ roslaunch turtlebot3_gazebo turtlebot3_empty_world.launch

Suppose you wanted to save yourself some work and launch both the simulation and the move_circle.py node at the same time...

  1. Firstly, return to your week2_navigation package and create a launch directory (if you haven't done so previously):

    $ roscd week2_navigation
    $ mkdir launch
    $ cd launch/
  2. Then create a launch file. You could call this whatever you want, but for the purposes of this example we'll create one called circle.launch:

    $ touch circle.launch
  3. Inside this file add the following:

    <launch>
      <include file="$(find turtlebot3_gazebo)/launch/turtlebot3_empty_world.launch" />
      <node pkg="week2_navigation" type="move_circle.py" name="circle_node" output="screen" />
    </launch>

    The <node> tag should already be familiar to you, but the <include> tag before it is new...

    This is what we use to launch other launch files. Here, we are locating the turtlebot3_gazebo package (using find), and asking for the turtlebot3_empty_world.launch file to be executed.

  4. From the command-line, execute your newly created launch file as follows:

     $ roslaunch week2_navigation circle.launch
    

    The TurtleBot3 Waffle will be launched in the "empty world" simulation, and the robot will start moving in a circle straight away!

roslaunch Command-line Arguments

A lot of the launch files that we have used throughout the lab course actually have command-line arguments that can be (optionally) supplied when making the roslaunch call. Consider the turtlebot3_empty_world.launch file for instance...

Enter the full command and then press the SPACE and TAB keys on your keyboard like so:

roslaunch turtlebot3_gazebo turtlebot3_empty_world.launch[SPACE][TAB][TAB]

This will reveal the available command-line arguments for this launch file:

model  x_pos  y_pos  z_pos

We can therefore optionally specify custom values for these parameters in order to change what happens when this launch file is executed. Try this, for example:

$ roslaunch turtlebot3_gazebo turtlebot3_empty_world.launch x_pos:=1 y_pos:=1

When the Gazebo simulation is launched, the robot will be located at coordinates (1, 1) in the X-Y plane, rather than (0, 0), as would usually be the case.

This is made possible by using <arg> tags at the start of the launch file (just after the opening <launch> tag):

<launch>
  <arg name="x_pos" default="0.0"/>
  <arg name="y_pos" default="0.0"/>
  ...

Here, the command-line arguments are specified by name (name="x_pos", name="y_pos" etc...) and a default value of 0.0 is defined (default="0.0"). Assigning a default is important, as it makes the command-line arguments optional (i.e. by default, the robot will be located at coordinates (0, 0), unless we specify otherwise).

Building Command-line Interfaces (CLIs) for Python Nodes

Suppose we have a very simple node, such as the publisher.py node that we created in Week 1. This node publishes a std_msgs/String type message to a topic called "chatter". Let's have a look at an alternative version of that node that takes in command-line arguments and publishes those to the "chatter" topic instead.

Take a look at the publisher_cli.py node from the com2009_examples package. Make sure you also have this node installed locally by pulling down the most recent updates to the COM2009 repo:

$ cd ~/catkin_ws/src/COM2009 && git pull

Here, we use the Python argparse module to allow us to work with arguments that are passed to the node from the command-line:

import argparse

We use this in the __init__() method of the Publisher() class to build a command-line interface (CLI) for the node:

cli = argparse.ArgumentParser(...)
cli.add_argument(...)

(See the code for more details)

Arguments that we define with a - at the front will be optional, i.e. we don't have to provide these every time we run the node. We do, however, need to assign a default value for each optional argument in cases where no value is supplied, e.g.:

cli.add_argument("-a_colour", metavar="COL", type=String,
    default="Blue", 
    help="The name of a colour")

The final step is to grab any arguments that are passed to this node when it is called. We use the rospy.myargv() method here, so that this works regardless of whether we call the node using rosrun or roslaunch:

self.args = cli.parse_args(rospy.myargv()[1:])

Having defined the CLI above, argparse then automatically generates help text for us! Try running the following command to see this in action:

$ rosrun com2009_examples publisher_cli.py -h

Run the node as it is (using rosrun) and see what happens:

$ rosrun com2009_examples publisher_cli.py

Then provide a value for the a_number variable, via the CLI:

$ rosrun com2009_examples publisher_cli.py -a_number 1.5

Passing Command-line Arguments to Python Nodes with roslaunch

Having built an CLI for our Python Node in the section above, we'll now look at how this all works when we call a node using roslaunch instead.

  1. First, create a launch file called publisher_cli.launch. It probably makes sense to create this one inside your week1_pubsub package:

    $ roscd week1_pubsub/launch
    $ touch publisher_cli.launch
  2. Inside this add the following:

    <launch>
      <arg name="colour" default="Black" />
      <arg name="number" default="0.9" />
    
      <node pkg="com2009_examples" type="publisher_cli.py"
        name="publisher_cli_node" output="screen"
        args="-a_colour $(arg colour) -a_number $(arg number)" />
    </launch>

    Here, we are specifying command-line arguments for the launch file using <arg> tags, as discussed earlier:

    <arg name="colour" default="Black" />
    <arg name="number" default="0.9" />    

    Next, we use a <node> tag to launch the publisher_cli.py node from the com2009_examples package. All of that should be familiar to you from Week 1. What's new here however is the additional args attribute:

    args="-a_colour $(arg colour) -a_number $(arg number)"

    This is how we pass the roslaunch command-line arguments to the CLI of our ROS Node:

    • -a_colour and -a_number are the command-line arguments of the Python Node
    • colour and number are the command-line arguments of the launch file
  3. Run the launch file without passing any arguments first, and see what happens:

    $ roslaunch week1_pubsub publisher_cli.launch
  4. Then try again, this time setting alternative values for the available command-line arguments:

    $ roslaunch week1_pubsub publisher_cli.launch number:=4 colour:=purple

Using the roslaunch Python API

This section will be available soon...