Flight Plans
The formal description of the flight plan file is given in the DTD (located in conf/flight_plans/flight_plan.dtd). This
DTD must be referenced in the header of your flight plan XML document using the following line:
<!DOCTYPE flight_plan SYSTEM "flight_plan.dtd">
The flight plans are stored in the conf/flight_plans directory. The flight plan editor can be used to create basic flight plans in the GUI.
Structure of the flight plan file
Extract from the DTD:
<!ELEMENT flight_plan (header?,waypoints,sectors?,include*,exceptions?,blocks)>
A flight plan is composed of two compulsory elements: waypoints and blocks and typically contains optional include's and global exceptions.
The root flight_plan element is specified with several attributes:
<flight_plan name lat0 lon0 ground alt security height qfu alt max_dist_from_home>
- name: the name of the mission (a text string)
- lat0, lon0: describe the latitude and longitude of the point {0,0} in WGS84 degree coordinates
- ground_alt: the ground altitude (in meters). It defines the GROUND_ALT constant value which can be used to define waypoint altitudes
- security_height: the altitude used by the circle-home failsafe procedure
- qfu (optional): defines the global constant QFU. It usually is the magnetic heading in degrees (north=0, east=90) of the runway, the opposite of wind direction. This constant may be used in the mission description. It is also used by the simulator as the original course of the aircraft.
- alt: the default altitude of waypoints
- max_dist_from_home: the maximum allowed distance (in meters) from the HOME waypoint.
Here is an example of the first line of a flight plan:
<flight_plan name="Example Muret" lat0="43.46223" lon0="1.27289" max_dist_from_home="300" qfu="270" ground_alt="185" security_height="25" alt="250">
Waypoints
The waypoints are the geographic locations used to specify the trajectories. A waypoint is specified with its name and its relative coordinates:
<waypoint name x y [alt] />
where x and y are the coordinates in meters from point {0,0}. alt is optional and can be used to assign an altitude to a particular waypoint that is different from the globally defined alt above. Note that a waypoint named HOME is required as it is used by the failsafe HOME mode procedure.
One example:
<waypoints> <waypoint name="HOME" x="0.0" y="30.0"/> <waypoint name="1" x="-100.0" y="60.0" alt="270."/> <waypoint name="2" x="-130.0" y="217.5" alt="3000."/> </waypoints>
Waypoints are easily edited with the flight plan editor.
Waypoints which name starts with an underscore are not displayed in the GCS, except in editor mode.
Sectors
Flat Sectors can be described as a list of waypoint corners. Such an area will be displayed in the GCS. A function is generated to check if a point (usually the aircraft itself) is inside the polygon. Currently, this feature requires that the polygon is convex and described in a clockwise order. For a sector named sector, the generated function is bool_t InsideSector(float x, float y); where x and y are east and north coordinated, in meters, relative to the geographic reference of the flight plan. Note: If the flight plan is dynamically relocated, such a sector will be relocated but the display is currently not updated on the GCS.
For example, with the following element in a flight plan (waypoints which name starts with an underscore are not displayed in the GCS, except in editor mode)
<sectors> <sector name="Muret"> <corner name="_1"/> <corner name="_2"/> <corner name="_3"/> <corner name="_4"/> </sector> </sectors>
it is then possible to write a exception to stay inside it:
<exception cond="! InsideMuret(estimator_x, estimator_y)" deroute="standby"/>
Include
include is used to add blocks defined in an external procedure. It’s useful to include pre-written procedures with only few arguments and then clarify the flight plan. Here is the structure:
<include name procedure [x] [y] [rotate] > [<arg name value />]*[<with from to />]*</include>
where name attribute of the include element will be used in this flight plan to jump to the blocks of the procedure, the XML referenced file. The procedure can be shifted (x meters east, y meters north) and rotated (clockwise degrees, north=0). Named arguments may be given with their value in the arg elements. The with tag allows to link labels from the procedure to blocks of the main flight plan. Then, each block of the procedure is like any block of the flight plan and is designated with a dotted identifier: block b of a procedure named p is named b.p .
Here is an example:
<include name="hippo1" procedure="hippo.xml" x="-100" y="150" rotate="0"> <arg name="alt" value="GROUND ALT+100"/> <with from="event1" to="penta"/> </include>
where a jump to event1 inside the hippo.xml procedure will actually jump to the penta block of the current flight plan.
Blocks
Block elements are the main part of a flight plan: they describe each unit of the mission. They are made of various primitives, called stages and exceptions, you can put one after the other. When a stage (or a block) is finished, the autopilot go to the next one. The behaviour after the last stage of the last block is undefined.
As described in the DTD, the blocks element is composed of block elements which are sequence of stages:
<!ELEMENT blocks (block+)> <!ELEMENT block (exception|while|heading|attitude|go|xyz|set|circle|deroute|stay|follow |survey_rectangle)*>
Example:
<block name="circlehome"> <circle radius="75" wp="HOME"/> </block>
You can add a button in the strip of the aircraft with the attribute strip_button:
<block name="descent" strip_button="Descent"> <circle wp="HOME" throttle="0.0" pitch="-15" vmode="throttle"/> </block>
This button will activate the block.
An icon can be specified to display the button. The strip_button label then is a tooltip for the icon. The icon must be an image file available in the directory data/pictures/gcs_icons:
<block name="Takeoff" strip_icon="takeoff.png" strip_button="Takeoff">
You can call functions before or after each execution of the block:
<block name="ciclehome" pre_call="function_to_call_before_circle()" post_call="function_to_call_after_circle()"> <circle wp="HOME"/> </block>
Expressions
Most of the numeric attributes in stages are analyzed as C expressions. The syntax of this C expression is restricted to
- numeric constants
- some internal autopilot variables (not fully documented, see examples)
- Some binary operators: <, >, <=, >=, <>, ==, +, -, /, *
- Some utility functions
Some examples of usable expressions are given in the next sections.
Exceptions
The flight manager can handle exceptions. They consist in conditions checked periodically (at the same pace as the navigation control), allowing the control to jump to a given block. Here is the syntax of exceptions:
<exception cond="..." deroute="...">
where cond is an expression and deroute is the name of the block we want to switch to as soon as the condition is true.
Here are some example of exceptions:
<exception cond="10 > PowerVoltage()" deroute="go_down"/> <exception cond="(ground_alt+10 > estimator_z)" deroute="go_up"/> <exception cond="(estimator_flight_time > 840)" deroute="quick_land"/>
Exceptions can be local to a block or global to the flight plan, in the <exceptions> element. In the following example, time since last reception of a message from the ground station is monitored and the navigation is switched to the Standby block if no message have been received for 22s. This exception is valid for all the blocks.
<flight_plan ...> <waypoints> ... </waypoints> <exceptions> <exception cond="datalink_time > 22" deroute="Standby"/> </exceptions> <blocks> ...
Deroute
The deroute is the goto directive of the flight plan; it switches the navigation to the given block: <deroute block="landing"/>
Note that this primitive should not be used to execute loops which are provided by the following elements.
Loops
Unbounded loops are written with while elements whose cond attribute is a boolean expression. Children of while are stages:
<while cond="TRUE"> <go wp="A"/> <go wp="B"/> <go wp="C"/> <while cond="5 > stage_time"/> </while>
In this example, we run an infinite loop, going to waypoints A, B and C and waiting for 5 seconds before repeating.
Bounded loops are written with the for tag:
<for var="i" from="0" to="3"> ... </for>
where the body of the loop will be run four times.
The variable of a for loop can be used inside expressions appearing as attributes of the stages:
<for var="i" from="1" to="5"> <circle wp="HOME" radius="75" alt="ground_alt+50*$i" until="stage_time>10" /> </for>
In this example, we circle around HOME 10 seconds at height 50m, 10s at height 100m, ... until height 250m. Note: Two bounded loops using the same control variable are not allowed in the same block.
Navigation modes give the description of the desired trajectory in 3D. While the horizontal mode is specified through stages, the vertical control is specified with various attributes of these stages. The current available navigation stages are
- attitude : just keep a fixed attitude;
- heading : keep a given course;
- go : go to a given waypoint;
- circle : circle around a waypoint;
- stay : hold the position (hard to realize for a fixed-win aircraft);
- follow : follow another aircraft;
- xyz : circle around a point moveable with the RC transmitter stick (obsolete with the datalink).
The vertical control is achieved using the vmode attribute of these stages. The possible values are
- alt (the default) : the autopilot keeps the desired altitude which is the altitude of the waypoint (if any) or the altitude specified with the alt attribute;
- climb : the autopilot keeps the desired vertical speed specified with the climb attribute (in m/s);
- throttle : the autopilots sets the desired throttle specified with the throttle attribute (between 0 and 1);
- glide : the autopilot keeps the desired slope between two waypoints
The default control is done with the throttle. However, setting the pitch attribute to auto and the throttle attribute to a constant allows a vertical control only by controlling the attitude of the A/C. The pitch attribute also can be set to any value (in degrees) while the throttle control is in use: it usually affects the airspeed of the aircraft.
The different navigation modes are detailed in the next sections.
Attitude
Element attitude is the navigation mode which corresponds to the current lowest control loop for horizontal mode. The autopilot then keeps a constant attitude. The roll attribute is required (in degrees, positive to put right wing low).
To fly away, at constant airspeed:
<attitude roll="0" vmode="throttle", throttle="0.5"/>
To fly around, holding a given altitude:
<attitude roll="30" alt="ground_alt+50"/>
Note that it is not a safe navigation mode since the geographic position of the plane is not controlled. However, this mode is useful to tune the roll attitude control loop.
Heading
heading primitive is relative to the second level loop for horizontal mode in the autopilot which will keep the given course, a required attribute (in degrees, clockwise, north=0, east=90).
One example to takeoff, following the QFU, 80% throttle, nose up (15 degrees) until height of 30m is reached:
<heading course="QFU" vmode="throttle" throttle="0.8" pitch="15" until="(estimator_z > ground_alt+30)"/>
Go
The go primitive is probably the most useful one. Basically, the autopilot will try to join a given waypoint (wp, the only required attribute). So the simplest thing you can ask for is
<go wp="HOME"/>
which will set the HOME waypoint as the desired target position. Note than since vmode="alt" is the default, the altitude of the target waypoint is also taken into account. The navigation will switch to the next stage as soon as the target is reached.
It is usually not a good idea to try to join a waypoint without asking for a precise trajectory, i.e. a given line. Setting the hmode attribute to route, the navigation will go over a segment joining two waypoints:
<go from="wp1" wp="wp2" hmode="route"/>
The target altitude is the altitude of the target waypoint; it can also be set with the alt attribute. The following example keeps an altitude with fixed throttle:
<go from="wp2" wp="wp3" hmode="route" pitch="auto" throttle="0.75" alt="ground_alt+100"/>
The attributes related to the vertical control can also be set to replace the default altitude mode:
<go from="wp1" wp="wp2" hmode="route" vmode="climb" climb="1.5"/>
Finally, the approaching_time (in seconds) attribute helps to decide when the target is reached. It can be set to 0 to go over the target waypoint (default value is the CARROT time, set in the airframe configuration file).
<go from="wp1" wp="wp2" hmode="route" approaching_time="1"/>
Circle
The circle primitive is the second main navigation mode: the trajectory is defined as a circle around a given waypoint with a given radius:
<circle wp="HOME" radius="75"/>
A positive radius makes the UAS move clockwise, a negative counter-clockwise.
The until attribute may be used to control the end of the stage. The following example defines an ascending trajectory at constant throttle, nose up (15 degrees), over growing circles, until the battery level is low:
<circle wp="wp1" radius="50+(estimator_z-ground_alt)/2" vmode="throttle" throttle="0.75" pitch="15" until="10>PowerVoltage()"/>
Follow
The follow is a special primitive which makes the UAS follow another UAS (real or simulated, named with its ac_id) at a given distance (in meters) behind and at a given height (in meters) above.
In this example, the autopilot will try to follow A/C number 4, staying 50m behind and 20m above.
<follow ac_id="4" distance="50" height="20"/>
Stay
The stay is a mode for UAS's able to hover:
<stay wp="HOME" alt="10"/>
Xyz
xyz is a special mode where the UAS circles around a user moveable waypoint. This waypoint is moved with the RC sticks:
- YAW channel controls the point over the west-east axis;
- PITCH channel controls the point over the south-north axis;
- ROLL channel controls the altitude.
Example (default radius is 100):
<xyz radius="40"/>
Set
The set element is a dangerous one which should be used only by expert users: it is used to directly set an internal variable of the autopilot. For example, you can change the value of the default ground altitude, a variable used by the home mode failsafe procedure (and maybe by your own flight plan):
<set var="ground_alt" value="ground_alt+50"/>
This directive is extremely powerful and has great potential for error - use with caution.
Call
The call allows the user to define its own navigation procedures in C. The value must be a call to a boolean function which must return TRUE as long as the stage is not completed (a function which should be called only once would then return immediately FALSE). This feature is illustrated with the line pattern:
<call fun="nav_line_init()"/> <call fun="nav_line(WP_1, WP_2, nav_radius)"/>
where nav_line_init() returns FALSE and nav_line() always returns TRUE (this stage never ends). Such functions usually are defined in a supplementary C file which must be specified in the airframe file (in the makefile section)
ap.srcs += nav_line.c sim.srcs += nav_line.c
These functions also must be declared in a header file which must be mentioned in the header element of the flight plan:
<header> #include "nav_line.h" </header>
These C source file and H header file must be located in the sw/airborne directory.
Advanced Examples
Parameters used in a flight plan can be computed expressions. In this example, the plane is asked to perform 5 circles at progressively increasing altitudes for exactly one minute at each altitude:
<for var = "i" from = "1" to = "5"> <circle wp = "HOME" radius="75" alt = "ground_alt+50*$i" until = "stage_time>60" /> </for>
Immobilize Actuators
h_ctl setpoints variable are set by the h_ctl_attitude_loop() (from fw_h_ctl.c) loop) which can be disabled with the h_ctl_disabled flag:
<set var="h_ctl_disabled" value="true"/> <set var="h_ctl_aileron_setpoint" value="0"/> <set var="h_ctl_elevator_setpoint" value="MAX_PPRZ/2"/> .... waiting for a condition ... <set var="h_ctl_disabled" value="false"/>
Procedures
Procedures are libraries which can be included in flight plans. They are composed of waypoints and blocks. The header of a procedure may contain some parameters which are replaced by arguments when the procedure is included.
Extract of the DTD: a procedure is a sequence of parameters, waypoints, optional global exceptions and blocks:
<!ELEMENT procedure (param*,waypoints,exceptions?,blocks)>
A parameter is just a name. A parameter is optional if it is declared with a default value. An example with a required and an optional parameter:
<param name="alt"/> <param name="radius" default_value="75"/>
Procedures are called with the include element in a flight plan (a procedure cannot be included by another procedure). A procedure call requires:
- the name of the procedure file, the name given to this inclusion;
- the relative position and the orientation of the procedure in the flight plan;
- values for the parameters;
- backlinks for block name exits of the procedure.
For example:
<include name="hippo1" procedure="hippo.xml" x="-100" y="150" rotate="0"> <arg name="alt" value="ground_alt+100"/> <with from="end" to="landing"/> </include>
Here is the corresponding procedure hippo.xml:
<procedure> <param name="alt"/> <param name="radius" default value="75"/> <waypoints> <waypoint name="c1" x="0" y="0"/> <waypoint name="c2" x="250" y="0"/> </waypoints> <blocks> <block name="oneturn"> <go hmode="route" alt="alt" from="c1" from_qdr="0" from_dist="radius" wp="c2" wp_qdr="0" wp_dist="radius"/> <circle wp="c2" radius="radius" until="Qdr(180)" alt="alt"/> <go hmode="route" alt="alt" from="c2" from_qdr="180" from_dist="radius" wp="c1" wp_qdr="180" wp_dist="radius"/> <circle wp="c1" radius="radius" until="Qdr(0)" alt="alt"/> <deroute block="end"/> </block> </blocks> </procedure>
Note that the name of procedure block is then hippo1.oneturn:
<deroute block="hippo1.oneturn"/>
will jump to this procedure block.
Flight Simulation
Complex flight plans should always be carefully tested prior to flight. See the simulation page for details.