Nasal Flightplan: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
No edit summary
(→‎Waypoint hashes: "Hold" does not seem to work.)
(42 intermediate revisions by 4 users not shown)
Line 1: Line 1:
{{Systems Modeling Disclaimer}}
{{Autoflight Navigation}}
{{Autoflight Navigation}}
{{Template:Nasal Navigation}}
{{Nasal Navigation}}


Discussion of interacting with the [[Route manager]] and flight-planning via Nasal.
Because FlightGear's [[route manager]] flight plan system is exposed to [[Nasal]], '''Nasal can be used to interact with flight plans'''. Obviously, this is very useful, especially for aircraft like airliners, which have complex route managers systems. This article shows how this can be done.


== Background ==
== Background ==
The Nasal functions relating to the route manager system include:
* {{func link|flightplan()}} - return the active plan.
* {{func link|airwaysRoute()}}
* {{func link|createFlightplan()}} - creates new empty plan. A path can be supplied to load a plan from xml.


Several advanced aircraft have created FMS and CDU implementations using custom Nasal code, with some (or no) interaction with the C++ route-manager, and often with code that overlaps. There's a goal to improve this, while keeping the complex, especially aircraft-dependant functionality in Nasal so it can be tailored and extended easily.
Flight plans are based on waypoints, which, in C++, inherit from the {{API Link|flightgear|class|FGPositioned}} class.


Scott has defined a FMS procedure, flight-plan and waypoint interface in Nasal, which James intends to replicate and extend from the C++ side, and then hopefully aircraft can be ported to use this instead of their own route and flight plan structures. Thus the C++ code and Nasal model will be in sync, and the user experience will be better!
== Waypoint hashes ==
The following are members of a waypoint ghost, as generated by, for example, {{func link|airwaysRoute()}}:


== Data Sources ==
; wp_name : Name of the waypoint, returned as string.
; wp_type : Waypoint type, returned as string. One of "basic," "navaid," "offset-navaid," "runway," "hdgToAlt," "dmeIntercept," "radialIntercept," or "vectors."
; wp_role: Role of waypoint.
; wp_lat ''or'' lat : Latitude of waypoint.
; wp_lon ''or'' lon : Longitude of waypoint.
; wp_parent_name : Name of waypoint's parent.
; wp_parent : Waypoint's parent.
; fly_type : How to waypoint should be flown over or reacted to. One of "flyOver" or "flyBy".
; heading_course : Heading of runway.


The current C++ code reads airways data from airways.dat, and can read the Level-D 767 procedure files if they are added to the Airports scenery data. However, it's intended that any other format can be supported.
== Flightplan methods and variables ==
Notice that instead of passing a leg as parameter, a waypoint can be passed.
; getWP(index) : Returns the leg for specified index.
; currentWP() : Return current active leg.
; nextWP() : Make next waypoint active.
; getPlanSize() : Returns number of waypoints
; appendWP(leg) : Add a leg to the end of the flightplan.
; insertWP(leg, index) : Pass a leg object and its position.
; deleteWP(index) : Deletes the waypoint at specified index.
; insertWPAfter() :
; insertWaypoints(vector, index) : Pass a vector of waypoint objects, and the position to insert.
; cleanPlan() : Clears all waypoints except destination and departure.
; clearWPType(type) : Supply a type string, it will clear all waypoints of the type.
; clone() : Return a copy of the flightplan.
; pathGeod() : This is used for graphical display: it’s an array of coordinates which show the path of the plan. This includes holds, procedure turns, turn anticipation and more.
; finish() : Finish the plan. (a call to delegate will be made)
; indexOfWP(wp) : Returns the index of the passed waypoint/leg.
; destination : airport object as destination.
; destination_runway : rwy object as destination and its airport implicit.
; departure : airport object as departure.
; departure_runway : rwy object as departure and its airport implicit.
; id : optional name of plan.
; sid : procedure object for SID.
; star : procedure object for STAR.
; sid_trans :
; star_trans :
; approach : procedure object for approach.
; current : Index of current waypoint.
; aircraftCategory : ICAO aircraft category.
; followLegTrackToFix : Specific used by some procedures. It controls whether the system will fly on an intersection course (and hence, different track) to the end of the leg, or make a corrective S-turn to get back on the leg track immediately it becomes possible.
; activate() : This will make the flight plan the default (the one used in route-manager).
; save(path) : Save a plan to xml. Will return true or false for success.


== Current Nasal Model ==
== Leg methods and variables ==
A leg is a wrapper for a waypoint, so it will have all waypoints variables and methods plus what is listed below.
Notice, that a leg you have gotten from a plan, but deleted in the plan, will be invalid and should not be used or modified.
A leg you have gotten from a plan, when modified, will modify the leg inside the plan you got it from.
; setSpeed(speed, type) : Sets the speed restriction. Setting nil type, will crash FG, setting empty type is same as setting "at". See below for type list.
; setAltitude(altitude, type) : Sets the altitude restriction. Setting nil type, will crash FG, setting empty type is same as setting "at". See below for type list.
; path() : Returns a vector of hashes containing lat and lon variables. These compromise a curved path for long non straight legs.
; courseAndDistanceFrom(coord) : Return vector with true course and distance. Coord is a geo.Coord.
; parents : Nasal parents.
; wp_owner : Will return you the owning route-structure of the WP - this could be an airway, procedure, or the flightplan if the waypoint doesn’t belong to a route structure.
; index : Returns the index of the leg in the owning route-structure.
; alt_cstr : Read-only. Altitude restriction.
; alt_cstr_type : Read-only. Altitude restriction type. See below for list.
; speed_cstr : Read-only. Speed restriction.
; speed_cstr_type : Read-only. Speed restriction. See below for list.
; leg_distance : Returns distance along the leg, from the preceding waypoint.
; leg_bearing : Returns the bearing along the leg.
; distance_along_route : Return the total distance laterally along the route to the beginning of the leg.


As defined by Scott several years ago, basically stable and working but independent of the route-manager at the moment. (Where does it load procedure data from? Or airways data?)
For speed restrictions these types can be used:
* "at" = kt should be spot on
* "above" = kt should be higher
* "below" = kt should be under
* "computed" = predicted kt
* "computed-mach" = predicted mach
* "mach" = its in mach instead of kt
* "delete" = Cleared by ATC


=== Flightplan ===
For altitude restrictions these types can be used:
<pre>
* "at" = alt should be spot on
appendWP        : func(wp)      : int    // returns the index it was inserted at
* "above" = alt should be higher
insertWP        : func(wp, idx)
* "below" = alt should be below
insertWPAfter  : func(wp, idx)
* "computed" = predicted alt
replaceWPAt    : func(wp, idx)
* "computed-mach" = not used for altitude
findWPName      : func(name)    : fmsWP
* "mach" = not used for altitude
findWPType      : func(type)    : fmsWP
* "delete" = Cleared by ATC
getWP          : func(idx)    : fmsWP
clearPlan      : func()
getPlanSize    : func()        : int
clearWPType    : func(type)
</pre>


=== FMS DB functions ===
== Procedure methods and variables ==
<pre>
; route(runway) : Returns a vector of waypoints.
fmsDB
; transition() : Only works on STAR and SID.
new            : func(icao)
getSIDList      : func(runway)  
getSTARList    : func(runway) 
getApproachList : func(runway, radio)  
getSid          : func(name)
getStar        : func(name)
getIAP          : func(name)
</pre>


=== Procedure and Waypoint hashes ===
== Examples ==
<pre>
These return a fmsTP class or an array of fmsTP that then contain an array of fmsWP amongst other things;
        me.wp_name        = "";
        me.tp_type        = "";        # SID, STAR, IAP
        me.radio          = "";        # ILS, VOR, NDB, RNAV approach
        me.runways        = [];        # array of runway names of this procedure
        me.wpts          = [];        # array of fmsWP
        me.rwy_tw        = [];        # array of runway transition waypoints if SID or approach transition for STAR
        me.transitions    = [];        # array of transition paths
 
 
The fmsWP model class contains;
        me.wp_name        = "";        # fix, navaid or pseudo waypoint name
        me.wp_parent_name = "";        # if a SID/STAR WP then the SID/STAR name, or AIRWAY name
        me.wp_type        = "FIX";      # FIX, NAVAID, Termination Point, transition wp, Final Fix, Appr Fix, RWY transition, SID/STAR WP,
        me.fly_type      = "FlyOver";  # flyOver, flyBy, Hold,
        me.action        = "DIRECT";  # direct, trk, intercept, vectors (not used)
        me.wp_lat        = 0.0;        # latitude
        me.wp_lon        = 0.0;        # longitude
        me.alt_cstr      = 0;          # alt constraint from db or calculated altitude in ft
        me.alt_cstr_ind  = 0;          # if the alt is a programmed constraint or just calculated (as part of STAR)
        me.spd_cstr      = 0;          # spd constraint in kts, mach or zero
        me.spd_cstr_ind  = 0;          # 0 - calculated speed, 1 - constraint
        me.hdg_radial    = 0.0;        # either heading/track or radial
        me.leg_distance  = 0;          # NM for this leg
        me.leg_bearing    = 0.0;        # deg bearing for this leg
</pre>
 
== Proposed Nasal API ==
 
* The fmsDB is mostly subsumed by the methods James is adding to the airport hash - only a couple more are required to get a 'procedure' hash corresponding to a flightgear::Procedure
* the fmsWP hash will stay almost the same, but gain some methods to set explicit or calculated speeds, and attach custom data.
* the flightplan class will gain methods and state to tracy departure and arrival airport / runway / procedures explicit, as the C++ code already does
* flightplan will support setting callback functions for Nasal to (re-) compute pseudo waypoints and VNAV profile when waypoints are added/removed/edited
* Although flight plans will support loading and saving to a standard XML format, it should be possible with the API to use Nasal to parse (or write) any other file format, and then build the flight plan using the setter methods. Moving the standard XML loading and saving to Nasal (from C++) would be a nice bonus.
 
== To Be Decided ==
 
* In the current C++ API, the route-manager sets the runway / procedure, and the transition is automatically selected, and the waypoints inserted into the flight-plan. In the code below I'm (James) exposing this logic to Nasal, on the assumption that any other behaviour is more complicated and unnecessary. If it's better, to follow Scott's API above, then instead 'procedure' would simple expose its waypoints as an array, and flight plan would gain a 'insertWaypoints(type, waypoint_vec), where type is 'sid', 'star', 'approach' or similar. (And the code knows the correct insert location). This needs another callback when the departure or arrival data changes from 'outside', i.e the route-manager properties or similar.
 
== Example Nasal ==
 
Setting flight-plan global (non-waypoint) data. Potentially this can include lots of FMS data - cruise profile, EPR setting, company route ID and so on. But most of that is probably better handled in Nasal, so long as the flight plan object provides a way to persist it.
<syntaxhighlight lang="nasal">
<syntaxhighlight lang="nasal">
# methods on airport (as returned from airportinfo())
var apt = airportinfo('eddm');
var rwy = apt.runway('28L');
# at some point in the future (not for the next release) there will hopefully be:
var rwy = apt.getActiveRunwayFor('departure', <enroute point>);
# which will return the active runway(s) for an airport based on type (arrival / departure)
# and enroute direction (e.g., departing north or arriving from the west)
# get the active flight plan (the one being used by the route manager)
# get the active flight plan (the one being used by the route manager)
fms.flightplan()
var fp = flightplan();


# or create one from Nasal
# or create one an XML file
fms.load('/path/to/xml')
fp = flightplan('/path/to/xml');


# save the active flight plan
# save the active flight plan
var fp = fms.flightplan()
fgcommand("save-flightplan", props.Node.new({"path": 'path/to/xml'}));
fp.save("/path/to/xml")


# duplicate a flight-plan
# duplicate a flight-plan
var secondary = fmd.flightplan().copy();
var secondary = fp.clone();


var dest = airportinfo('EDDM')
var dest = airportinfo('KSFO');
var rwy = dest.runway('08R');
var rwy = dest.runway('19L');
# the the arrival runway (and airport, automatically)
# the the arrival runway (and airport, automatically)
fp.setArrival(rwy)
fp.destination_runway = rwy;
 
# or if no runway is known / specified
fp.setArrival(dest)


# optional, not used by anything in C++, but worth adding?
# or if no runway is known/specified
fg.setAlternate(<airport>);
fp.destination = dest;
</syntaxhighlight>
</syntaxhighlight>


Building procedures and transitions. As mentioned above there's a couple of different ways to handle this, the examples below assume the C++ code automatically deletes and re-inserts waypoints for procedures, but that's only one possible design.
Building procedures and transitions. As mentioned above there's a couple of different ways to handle this, the examples below assume the C++ code automatically deletes and re-inserts waypoints for procedures, but that's only one possible design.
<syntaxhighlight lang="nasal">
<syntaxhighlight lang="nasal">
# example for sids, stars are the same, approaches too
var apt = airportinfo('KSFO');
# example for SIDs, STARs are the same, approaches too
var allSids = apt.sids();
var allSids = apt.sids();


# SIDs for a specific runway - note these return SID IDs as string, for compatibility with existing code
# SIDs for a specific runway - note these return SID IDs as string, for compatibility with existing code
var rwySids = apt.sids('28L')
var rwySids = apt.sids('28L');
# or (potentially)
var rwySids = rwy.sids();
# rwySids = ['TALLA', 'GRICE', 'BEKNO']
 
# here's the actual call to get a procedure object by ID, from an airport
var sid = apt.procedure('BEKNO')
# sid is very similar to fmsTP above, has runways[], ident, type,
 
var star = dest.procedure('FOOBZ')
# methods: find transition for runway, find transition for location
 
# given a waypoint or geod, find the closest STAR transition point
var transition = star.findTransitionFor(fp.lastEnrouteLeg());
 
# or some other way to compute thr transition ....
 
# clear all existing arrival waypoints and rebuild from the star and approach
 
# similarly, find the best approach for our runway
var app = star.findRunwayTransition(rwy)
 
# finally, delete all existing arrival waypoints from the plan, and insert new
# waypoints from the transition, STAR and approach.
# the replaced 'buildArrival' in FGRouteManager and FGAirport (which is good!)
fp.setArrivalWaypoints(star, transition, app);
</syntaxhighlight>
 
Setting waypoint restrictions / clearing them / setting computed speeds and altitudes from the FMS
<syntaxhighlight lang="nasal">
 
var wpt = fp.firstEnrouteLeg();
# specify a manual user constraint on  this WP
# presumably do this from a CDU page
wpt.setSpeed(210);
# or in Mach
wpt.setMach(0.77)
 
wpt.setAltitude(18000);
 
# or (again from a CDU page?)
wpt.deleteRestrictions();
 
# save some data persistently to a flight plan leg
# (maybe not saved to XML? depends on the type)
wpt.setData('customfield', ..... any nasal var .... );
 
</syntaxhighlight>
</syntaxhighlight>


Inserting and deleting waypoints (possibly in batches)
Inserting and deleting waypoints (possibly in batches)
<syntaxhighlight lang="nasal">
<syntaxhighlight lang="nasal">
var fp = flightplan();
# waypoint created from lat, lon, or a navaid, or anything else?
var pos = geo.aircraft_position().apply_course_distance(getprop("/orientation/heading-deg"), 100000);
var wp = createWP(pos.lat(), pos.lon(), "EPICA");


# waypoint created from lat,lon, or a navaid, or anything else?
# manually insert a waypoint at the end of the plan
var wpt = fp.createWaypoint(<waypoint args>)
fp.insertWP(wp, fp.getPlanSize());


# manually insert a waypoint into the plan
# manually insert a waypoint at a defined position (n) into the plan
fp.insertWayptAt(index, wpt);
fp.insertWP(wp, n);


# route along airways, and insert a whole bunch of waypoints
# route along airways, and insert a whole bunch of waypoints
# this is needed for the route-manager dialog, maybe not for a
# this is needed for the route-manager dialog, maybe not for a
# real FMS interface....
# real FMS interface....
var segment = airways.route(<some geo pos or similar>, <some other geo pos>);
var segment = [<waypoint object>, <waypoint object>, <waypoint object>];
# segment is a vector of waypoints now
# segment is a vector of waypoints now
fp.insertWaypoints(index, segment);
fp.insertWaypoints(segment, fp.getPlanSize());
</syntaxhighlight>
 
== aircraft.history() (3.2+) ==


# in the future, VOR-VOR routing could be added (for GA flights, although this is rathe irrelevant thanks to GPS)
Function to expose flight history as aircraft.history()
var route = routeVORtoVOR(<some pos>, <some other pos>)
fp.insertWaypoints(index, route);


# any other way of building up an array of waypoints is also find - suggestions?
<syntaxhighlight lang="nasal">
var hist = aircraft.history();


# get history of aircraft position/orientation collapsing
# nodes with a distance smaller than the given minimum
# edge length
debug.dump( hist.pathForHistory(<minimum-edge-length-meter>) );
</syntaxhighlight>
</syntaxhighlight>


Callback from C++ when the flight plan is modified, to allow the FMS to rebuild pseduo-waypoints and compute the VNAV profile. This function can be fairly intensive, but it's only going to be called occasionally, in response to user interaction.
== Related content ==
<syntaxhighlight lang="nasal">
=== Wiki articles ===
* [[Nasal library#Extension functions|Nasal library § Extension functions]]
* [[Navdata cache#Accessing via Nasal|Navdata cache § Accessing via Nasal]]
* [[Route Manager]]
* [[Route Manager internals]]
* [[Howto:Control the route manager in Nasal]]
 
=== Documentation ===
* [http://api-docs.freeflightsim.org/flightgear/NasalPositioned_8cxx_source.html#l00585 flightplanGhostSetMember] — ''Members of a flight plan object that can be set.''
* [http://api-docs.freeflightsim.org/flightgear/NasalPositioned_8cxx_source.html#l00557 flightplanGhostGetMember] — ''Members of flight plan object that can be read.''
* [http://api-docs.freeflightsim.org/flightgear/NasalPositioned_8cxx_source.html#l02485 initNasalPositioned] — ''Contains a list of functions that can be called on airport, flight plan, waypoint, procedure, or flight plan leg objects.''
* [http://api-docs.freeflightsim.org/flightgear/route__mgr_8cxx_source.html#l00220 FGRouteMgr::FGRouteMgr] — ''List of [[fgcommands]] relating to the route manager.''
 
=== Misc ===
* https://sourceforge.net/p/flightgear/mailman/message/34688624/
* https://sourceforge.net/p/flightgear/mailman/message/35164289/
* https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/BB67C9F3-028B-40E5-94E4-246CD1E0B2CC%40mac.com/#msg23708827
* https://sourceforge.net/p/flightgear/mailman/message/33699574/
* https://sourceforge.net/p/flightgear/mailman/message/21010010/
* https://sourceforge.net/p/flightgear/mailman/message/23678747/


# set the callback on the flight plan
=== Search Queries ===
fp.setUpdateCallback(cb);


var cb = func(fp)
=== Commits ===
{
    # delete the existing pseudso waypoints
    fp.clearWPType('pseudo')
   
    # compute T/D and T/C location
   
    var wp = fp.createPseudoWP('T/D', ... other info .....);
    fp.insertWayptAt(wp , index);
   
    var tc = fp.createPseudoWP('T/C', ....)
    fp.insertWayptAt(tc, someindex);
   
# update the calculated speed / altitude values
# this needs the difficult VNAV bit to work forwards / backwards
# along the route.
    foreach (var leg, fp.legs()) {
        if (leg.alt_cstr == 'none') {
            var altitude = .... ;
            leg.setCalculatedAlt(altitude);
        }
       
        if (leg.speed_cstr == 'none') {
            var speed = .... ;
            leg.setCalculatedSpeed(speed);
        }
       
    }
}


</syntaxhighlight>
=== Threads ===
{{Appendix}}


[[Category:Nasal]]
[[Category:Nasal]]
[[Category: Core development projects]]
[[Category: Core developer documentation]]

Revision as of 15:33, 8 February 2019

Note  Whenever possible, please refrain from modeling complex systems, like an FDM, autopilot or Route Manager with Nasal. This is primarily to help reduce Nasal overhead (especially GC overhead). It will also help to unify duplicated code. The FlightGear/SimGear code base already contains fairly generic and efficient systems and helpers, implemented in C++, that merely need to be better generalized and exposed to Nasal so that they can be used elsewhere. For example, this would enable Scripted AI Objects to use full FDM implementations and/or built-in route manager systems.

Technically, this is also the correct approach, as it allows us to easily reuse existing code that is known to be stable and working correctly, .

For details on exposing these C++ systems to Nasal, please refer to Nasal/CppBind. If in doubt, please get in touch via the mailing list or the forum first.


Because FlightGear's route manager flight plan system is exposed to Nasal, Nasal can be used to interact with flight plans. Obviously, this is very useful, especially for aircraft like airliners, which have complex route managers systems. This article shows how this can be done.

Background

The Nasal functions relating to the route manager system include:

Flight plans are based on waypoints, which, in C++, inherit from the FGPositioned (doxygen) class.

Waypoint hashes

The following are members of a waypoint ghost, as generated by, for example, airwaysRoute() :

wp_name
Name of the waypoint, returned as string.
wp_type
Waypoint type, returned as string. One of "basic," "navaid," "offset-navaid," "runway," "hdgToAlt," "dmeIntercept," "radialIntercept," or "vectors."
wp_role
Role of waypoint.
wp_lat or lat
Latitude of waypoint.
wp_lon or lon
Longitude of waypoint.
wp_parent_name
Name of waypoint's parent.
wp_parent
Waypoint's parent.
fly_type
How to waypoint should be flown over or reacted to. One of "flyOver" or "flyBy".
heading_course
Heading of runway.

Flightplan methods and variables

Notice that instead of passing a leg as parameter, a waypoint can be passed.

getWP(index)
Returns the leg for specified index.
currentWP()
Return current active leg.
nextWP()
Make next waypoint active.
getPlanSize()
Returns number of waypoints
appendWP(leg)
Add a leg to the end of the flightplan.
insertWP(leg, index)
Pass a leg object and its position.
deleteWP(index)
Deletes the waypoint at specified index.
insertWPAfter()
insertWaypoints(vector, index)
Pass a vector of waypoint objects, and the position to insert.
cleanPlan()
Clears all waypoints except destination and departure.
clearWPType(type)
Supply a type string, it will clear all waypoints of the type.
clone()
Return a copy of the flightplan.
pathGeod()
This is used for graphical display: it’s an array of coordinates which show the path of the plan. This includes holds, procedure turns, turn anticipation and more.
finish()
Finish the plan. (a call to delegate will be made)
indexOfWP(wp)
Returns the index of the passed waypoint/leg.
destination
airport object as destination.
destination_runway
rwy object as destination and its airport implicit.
departure
airport object as departure.
departure_runway
rwy object as departure and its airport implicit.
id
optional name of plan.
sid
procedure object for SID.
star
procedure object for STAR.
sid_trans
star_trans
approach
procedure object for approach.
current
Index of current waypoint.
aircraftCategory
ICAO aircraft category.
followLegTrackToFix
Specific used by some procedures. It controls whether the system will fly on an intersection course (and hence, different track) to the end of the leg, or make a corrective S-turn to get back on the leg track immediately it becomes possible.
activate()
This will make the flight plan the default (the one used in route-manager).
save(path)
Save a plan to xml. Will return true or false for success.

Leg methods and variables

A leg is a wrapper for a waypoint, so it will have all waypoints variables and methods plus what is listed below. Notice, that a leg you have gotten from a plan, but deleted in the plan, will be invalid and should not be used or modified. A leg you have gotten from a plan, when modified, will modify the leg inside the plan you got it from.

setSpeed(speed, type)
Sets the speed restriction. Setting nil type, will crash FG, setting empty type is same as setting "at". See below for type list.
setAltitude(altitude, type)
Sets the altitude restriction. Setting nil type, will crash FG, setting empty type is same as setting "at". See below for type list.
path()
Returns a vector of hashes containing lat and lon variables. These compromise a curved path for long non straight legs.
courseAndDistanceFrom(coord)
Return vector with true course and distance. Coord is a geo.Coord.
parents
Nasal parents.
wp_owner
Will return you the owning route-structure of the WP - this could be an airway, procedure, or the flightplan if the waypoint doesn’t belong to a route structure.
index
Returns the index of the leg in the owning route-structure.
alt_cstr
Read-only. Altitude restriction.
alt_cstr_type
Read-only. Altitude restriction type. See below for list.
speed_cstr
Read-only. Speed restriction.
speed_cstr_type
Read-only. Speed restriction. See below for list.
leg_distance
Returns distance along the leg, from the preceding waypoint.
leg_bearing
Returns the bearing along the leg.
distance_along_route
Return the total distance laterally along the route to the beginning of the leg.

For speed restrictions these types can be used:

  • "at" = kt should be spot on
  • "above" = kt should be higher
  • "below" = kt should be under
  • "computed" = predicted kt
  • "computed-mach" = predicted mach
  • "mach" = its in mach instead of kt
  • "delete" = Cleared by ATC

For altitude restrictions these types can be used:

  • "at" = alt should be spot on
  • "above" = alt should be higher
  • "below" = alt should be below
  • "computed" = predicted alt
  • "computed-mach" = not used for altitude
  • "mach" = not used for altitude
  • "delete" = Cleared by ATC

Procedure methods and variables

route(runway)
Returns a vector of waypoints.
transition()
Only works on STAR and SID.

Examples

# get the active flight plan (the one being used by the route manager)
var fp = flightplan();

# or create one an XML file
fp = flightplan('/path/to/xml');

# save the active flight plan
fgcommand("save-flightplan", props.Node.new({"path": 'path/to/xml'}));

# duplicate a flight-plan
var secondary = fp.clone();

var dest = airportinfo('KSFO');
var rwy = dest.runway('19L');
# the the arrival runway (and airport, automatically)
fp.destination_runway = rwy;

# or if no runway is known/specified
fp.destination = dest;

Building procedures and transitions. As mentioned above there's a couple of different ways to handle this, the examples below assume the C++ code automatically deletes and re-inserts waypoints for procedures, but that's only one possible design.

var apt = airportinfo('KSFO');
# example for SIDs, STARs are the same, approaches too
var allSids = apt.sids();

# SIDs for a specific runway - note these return SID IDs as string, for compatibility with existing code
var rwySids = apt.sids('28L');

Inserting and deleting waypoints (possibly in batches)

var fp = flightplan();
# waypoint created from lat, lon, or a navaid, or anything else?
var pos = geo.aircraft_position().apply_course_distance(getprop("/orientation/heading-deg"), 100000);
var wp = createWP(pos.lat(), pos.lon(), "EPICA");

# manually insert a waypoint at the end of the plan
fp.insertWP(wp, fp.getPlanSize());

# manually insert a waypoint at a defined position (n) into the plan
fp.insertWP(wp, n);

# route along airways, and insert a whole bunch of waypoints
# this is needed for the route-manager dialog, maybe not for a
# real FMS interface....
var segment = [<waypoint object>, <waypoint object>, <waypoint object>];
# segment is a vector of waypoints now
fp.insertWaypoints(segment, fp.getPlanSize());

aircraft.history() (3.2+)

Function to expose flight history as aircraft.history()

var hist = aircraft.history();

# get history of aircraft position/orientation collapsing
# nodes with a distance smaller than the given minimum
# edge length
debug.dump( hist.pathForHistory(<minimum-edge-length-meter>) );

Related content

Wiki articles

Documentation

Misc

Search Queries

Commits

Threads

References