Using the ROS Launch Python API¶
COM2009 Assignment #1 Checkpoint
It helps if you've already completed Assignment #1 up to and including all of Part 3 before working on this.
The ROS Launch Python API allows us to launch nodes (and other launch files) from inside our own nodes! The official documentation for the ROS Launch API is the best place to go to find out how to use this, but here's a quick example, if you're short on time.
Within the tuos_examples
package there is a node called pointless_file_generator
.
Tip
You may need to update your local copy of the course repo to ensure that you have this!
This node takes a file path as a command-line argument, and writes a text file of the same name to the file system. From the command line, you can call the node like this:
A text file called FILENAME.txt
will be saved to your current working directory.
- Use the
pwd
to determine your current working directory, - Use the
ls
command to show the files/directories present at this file system location, -
Then, use the
cat
command to display the content of theFILENAME.txt
file, e.g.:
Suppose you wanted to call this node programmatically instead (i.e. from within another Python Node). Below is an example of a very simple ROS node that does just that. Once the code below is executed it will launch the pointless_file_generator
node from the tuos_examples
package, but this time using the ROS Launch API. The key difference here is that instead of FILENAME
, we need to define a full path to the text file that we want to generate.
#!/usr/bin/env python3
import roslaunch
import rospy
file_path = "/full/path/to/text/file"
rospy.init_node("pointless_file_generator_caller", anonymous=True)
rate = rospy.Rate(0.5)
launch = roslaunch.scriptapi.ROSLaunch()
launch.start()
print(f"Saving file at time: {rospy.get_time()}...")
node = roslaunch.core.Node(
package="tuos_examples",
node_type="pointless_file_generator",
args=f"-f {file_path}",
output="screen",
)
process = launch.launch(node)
rate.sleep()
Create a node in one of your own ROS packages and then copy and paste the above code into it. You'll need to update the file_path = "/full/path/to/text/file"
line to represent the path to a real location on your file system. The file will be then created automatically by the node in the specified location. You must specify a full file system path in order for this to work correctly using the ROS Launch Python API though, and you will only be able to write to a location that's within your Home directory (e.g.: /home/student/path/to/file
), otherwise you'll get an error!
Assignment #2 Hint: Saving a SLAM Map Programmatically¶
In the SLAM Exercise in Assignment #1 Part 3 we run SLAM in the background while driving our Waffle around a simulated environment manually, using the turtlebot3_teleop
node. Once SLAM has generated a full map we use a rosrun
command (in the terminal) to call a map_saver
node to save a copy of this map for us:
You can therefore use exactly the same approach as in the example above to achieve this programmatically!
Wrap this into one of your own Task 4 ROS nodes, or build a standalone node inside your team's ROS package to call the map_saver
node when required. Perhaps you could even wrap the relevant lines of code from the above example inside a while loop and get the node to update a map file at regular intervals (say every 5 seconds?) while your robot explores its environment...
Warning
- When calling the
map_saver
node you may actually find that it must be wrapped within a loop in order for the process to work reliably. - Don't call the
map_saver
node too regularly though (i.e. no more than once every few seconds at most), otherwise you'll swamp the ROS network which can result in the system becoming unstable and the robot becoming unresponsive.