Nasal Flightplan
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. |
Autoflight |
---|
Autopilot |
Route manager |
Specific autopilots |
Miscellaneous |
The FlightGear forum has a subforum related to: Nasal Scripting |
Nasal scripting |
---|
Nasal internals |
---|
Memory Management (GC) |
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:
flightplan()
- return the active plan.airwaysRoute()
createFlightplan()
- creates new empty plan. A path can be supplied to load a plan from xml.
Flight plans are based on waypoints, which, in C++, inherit from the FGPositioned
(doxygen) class.
Waypoint ghost
The following are members of a waypoint ghost, as generated by, for example, airwaysRoute()
:
- wp_name or id
- Name of the waypoint, returned as string.
- wp_type
- Waypoint type, returned as string. One of "basic," "navaid," "offset-navaid," "runway," "hold", "hdgToAlt," "dmeIntercept," "radialIntercept," "discontinuity", "via", or "vectors."
- wp_role
- Role of waypoint. One of "pseudo", "sid", "star", "missed", "approach"
- 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 as a ghost.
- fly_type
- How to waypoint should be flown over or reacted to. One of "flyOver" or "flyBy" or "Hold".
- heading_course
- Heading of runway, hdgToAlt, hold, radialIntercept, or dmeIntercept waypoints
- hidden
- Boolean flag as to whether it should be shown on map / navigation display when included in a flightplan
Hold members
Holds are waypoints with additional parameters. Holds can be created in three ways:
- By loading a procedure that defines holds (SID/STAR/transition/approach)
- By setting the hold_count of a flightplan leg to a nonzero value (see below, under "Leg methods and variables").
- By setting the hold_heading_radial_deg of a flightplan leg to any value
The following hold-specific members are available:
- hold_is_left_handed
- boolean, defines direction of turns in the hold
- hold_heading_radial_deg
- number, the inbound radial of the hold, measured in degrees
- hold_inbound_radial
- number, readonly alias for hold_heading_radial_deg
- hold_time_or_distance
- number, readonly, the leg length, defined either in seconds or nautical miles
- hold_is_distance
- boolean, readonly, defines if hold is measured by distance
- hold_is_time
- boolean, readonly, defines if hold is measured by time
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. Example: insertWP(leg, 1) --> leg becomes waypoint at index 1.
- deleteWP(index)
- Deletes the waypoint at specified index. Example: deleteWP(0) --> deletes first waypoint.
- 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() or pointAlongRoute()
- (function has two associated names). 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
- procedure object for SID transition (as of 2020.2, may be written to)
- star_trans
- procedure object for STAR transition (as of 2020.2, may be written to)
- 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.
- airport()
- Return airport ghost associated with this leg, if any. Leg waypoint must be an airport or runway.
- navaid()
- Return navaid ghost associated with this leg, if any. Leg waypoint must be a navaid (VOR/NDB/DME/ILS).
- runway()
- Return runway ghost associated with this leg, if any. Leg waypoint must be a runway.
- parents
- Nasal parents.
- wp_parent
- 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 output. Set using setAltitude.
- alt_cstr_type
- Read-only. Altitude restriction type. See below for list.
- speed_cstr
- Read-only. Speed restriction output. Set using setSpeed.
- 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.
- hold_count
- If the leg is a hold, return the remaining number of laps to be flown. For non-hold legs, and for hold legs that have been completed, it will be 0. Setting this to a positive value will turn the leg into a hold. Note that as of version 2020.3.13, there is no way of converting a hold back into a regular, non-hold 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
- id
- a string containing the name of the procedure
- airport
- airport object associated with the procedure
- radio
- for instrument approaches, returns the type of procedure (VOR, ILS, RNAV, or NDB)
- tp_type
- returns the type of procedure (sid, star, or iap)
- runways
- a vector containing the runways associated with the procedure
- transitions
- a vector containing the transitions of the procedure (for SIDS and STARS only)
- route(runway)
- Returns a vector of waypoints.
- transition()
- Only works on STAR and SID.
Airport methods and variables
- runway
- a ghost for the runway passed as a string or nil
- runwaysWithoutReciprocals
- helipad
- a ghost for the helipad passed as a string or nil
- tower
- returns hash containing airport tower location
- comms
- contains vector containing communication frequencies
- sids
- a vector containing the ids of sids of the airport, if a runway is passed, just for that runway. Pass an id into getSid to get the ghost.
- stars
- a vector containing the ids of stars of the airport, if a runway is passed, just for that runway. Pass an id into getStar to get the ghost.
- getApproachList
- a vector containing the ids of IAPs of the airport, if a runway is passed, just for that runway. Pass an id into getIAP to get the ghost.
- parking
- a vector containing parking positions of the airport
- getSid
- a ghost for a SID
- getStar
- a ghost for a STAR
- getIAP
- a ghost for a IAP
- findBestRunwayForPos
- passed a position, returns a ghost for the runway it decides is best
- toString
- returns "an airport " + the airport id
Airway methods and variables
- id
- returns identifier of airway
- level
- "high", "low", or "both"
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
- Nasal library § Extension functions
- Navdata cache § Accessing via Nasal
- Route Manager
- Route Manager internals
- Howto:Control the route manager in Nasal
Documentation
- flightplanGhostSetMember — Members of a flight plan object that can be set.
- flightplanGhostGetMember — Members of flight plan object that can be read.
- initNasalPositioned — Contains a list of functions that can be called on airport, flight plan, waypoint, procedure, or flight plan leg objects.
- 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/
Search Queries
Commits
Threads
References
|