Creating A Mission#
A guide to writing your own mission. You will learn how to read a mission YAML finite-state
machine, write a new one incorporating the mode you just created uav.FlyToPointMode, and fly it in the sim.
Before You Begin#
This tutorial continues from Creating Your First Mode. Stay on the
user/<github-username>/tutorial branch you created there because it contains your new
uav.FlyToPointMode. If you have not completed that tutorial, follow it first.
This tutorial also assumes that you have installed the monorepo and built the ROS workspace. If you have not, follow the Ubuntu installation guide first.
You should also be familiar with the following concepts:
Those pages explain the mode lifecycle and how transition labels connect modes inside a mission. Here, you will put those ideas into practice.
Reading an Existing Mission#
Before writing your own mission, read an example one to see how it’s structured.
Here is ros_ws/src/common/uav/missions/basic.yaml, a
mission that takes off, flies to a waypoint, and then lands:
modes:
start:
mode: uav.vtol.TakeoffMode
params:
takeoff_type: vertical
transitions:
complete: GPS
GPS:
mode: uav.NavGPSMode
params:
coordinates:
- [[5, 0, -5], 1, LOCAL]
transitions:
complete: land
land:
mode: uav.LandingMode
Note
The coordinates parameter for uav.NavGPSMode is a list of waypoints. Each waypoint has the form
[coordinates, wait_seconds, frame], where coordinates is either [x, y, z] or [lat, lon, alt].
LOCAL uses PX4’s local NED frame in meters: X is north, Y is east, and Z is down.
Coordinates are relative to PX4’s local position origin, so negative Z values are above the origin.
In this case, the UAV will fly to the point (5, 0, -5) with a wait time of 1 second in the LOCAL frame.
The keys nested directly under modes: are state names: start, GPS, and land. These are just labels
chosen for the mission. There is no requirement that the state named GPS has to run a mode with “GPS” in its name.
Each state takes up to three keys:
mode the registered id of the mode this state runs
params values validated against that mode's params model
transitions a map from a check_status() label to the next state's name
When a mission begins, UAVModeManager switches to the state named start first,
so a mission without this state never begins.
While ordering inside the file doesn’t technically matter, it is good to keep them organized in a logically clear manner.
Read the transitions as label: target. For example, GPS has complete: land, which means that when this mode reports complete,
the program should go to the state named land. Note that the target is a state name in this file, not an actual mode id.
The manager treats three check_status() results specially: continue keeps the current mode running,
terminate ends the mission, and error invokes failure handling. Any other result is treated as a custom
transition label and looked up in transitions:, so do not use the three reserved strings as transition labels.
See Modes for more detail.
Note
The land state has no transitions block at all, since it is a terminal state, as LandingMode
returns the reserved terminate string.
Writing Your Mission#
Create a new YAML file in the UAV missions directory and name it accordingly:
monorepo/ros_ws/src/common/uav/missions/<mission-name>.yaml
You should attempt to create a mission that takes off, calls the mode you created in the previous tutorial uav.FlyToPointMode,
passing in a required 3-tuple target argument and optionally a margin argument, then lands.
Use the above basic.yaml as a template, replacing uav.NavGPSMode with the uav.FlyToPointMode call and parameters:
Note
To see what parameters a mode accepts, read its params model next to the mode itself. For example, you had FlyToPointMode declare
FlyToPointParams at the top of ros_ws/src/common/uav/uav/modes/fly_to_point_mode.py in the mode tutorial,
which provides the schema the params: block is checked against.
Here is a completed version of the mission:
Complete Mission fly_to_point.yaml
modes:
start:
mode: uav.vtol.TakeoffMode
params:
takeoff_type: vertical
transitions:
complete: fly_to_point
fly_to_point:
mode: uav.FlyToPointMode
params:
target: [5.0, 0.0, -5.0]
margin: 1.0
transitions:
complete: land
land:
mode: uav.LandingMode
Running Your Mission in Sim#
Missions are installed into the package share directory, so build the workspace before launching:
# From monorepo root
cd ros_ws
colcon build --packages-select uav
source install/setup.bash
Before launching the mission, start QGroundControl. PX4 requires an active ground station connection to pass its preflight checks and arm the UAV.
Then launch SITL with your mission selected by name, making sure to replace <mission-name> with the name of your mission file:
ros2 launch uav uav_sitl.launch.py mission:=<mission-name>
Committing Your Changes#
To save your progress locally, stage and commit your changes to the branch you created at the start of this tutorial.
# from monorepo/ros_ws
git add src/common/uav/uav/missions/<mission-name>.yaml
git commit -m "created first mission"
Congrats, You Did It!#
You successfully created an entire mode, incorporated it into a mission, and flew it in sim!
Your tutorial work is saved on its own branch. When you are finished, return to main:
git checkout main