Zum Inhalt

Migration

Diese Seite wurde aus der AirSimTech MediaWiki migriert.

Flight Plan Lifecycle

Overview

The FlightPlanActor owns and mutates a single immutable FlightPlan data structure via Akka.NET message passing. Because all mutations are sequentially processed through the actor mailbox, no locking is required. Two independent instances are created by FmgcSupervisor: PrimaryFlightPlanActor (path /user/FmgcSupervisor/PrimaryPlan) holds the active flight plan, and SecondaryFlightPlanActor (path /user/FmgcSupervisor/SecondaryPlan) holds the revision plan. Neither actor can corrupt the other's state. Consumers obtain an immutable FlightPlanSnapshot via the Ask pattern and can read it freely without risk of mid-mutation state.

Flight Plan Structure

The FlightPlan class aggregates five typed segments, each containing an ordered list of FlightPlanLeg objects. Mutation produces a new FlightPlan instance — the previous instance is discarded.

Each FlightPlanLeg is also immutable. Key fields:

  • WaypointIdent — ICAO identifier string
  • Latitude / Longitude — geographic position
  • ArinCCommand — 2-char ARINC 424 path terminator (e.g. "TF", "CF", "DF", "CA")
  • LegTypeFlightPlanLegType enum (Normal, Sid, Star, Approach, Hold, etc.)
  • AltConstraint1 / AltConstraint2 / AltConstraintType — altitude constraint window
  • SpeedConstraint — speed constraint in knots (0 = unconstrained)
  • ViaToNext — airway name used to reach this waypoint (blank for direct)

Initialization Flow

Flight plan initialization begins on the INIT A MCDU page. Each pilot entry triggers a Tell to FlightPlanActor; SID/STAR selections additionally require a NavDb query via the Ask+PipeTo pattern.

Mutation Operations

All flight plan changes are sent as immutable message objects to FlightPlanActor via Tell (fire-and-forget). No reply is expected — the actor applies the mutation synchronously before processing the next message.

Message Class Key Parameters Sender Effect
SetOriginDestination Adep As String, Ades As String McduActor (INIT A page) Clears all segments and holdings; sets departure and destination ICAO codes
SetDepartureInfo AdepRunway, SidName, SidTransitionName McduActor (SidPage, SidTransPage, AdepRwyPage) Records selected runway, SID, and SID transition names
SetArrivalInfo AdesRunway, StarName, StarTransitionName, ViaName, ApproachName McduActor (StarPage, StarTransPage, ViaPage, AdesRwyPage) Records selected runway, STAR, VIA, and approach names
SetDepartureSegment Segment As DepartureSegment McduActor (after NavDb SID query) Replaces entire DepartureSegment with loaded SID legs
SetEnRouteSegment Segment As EnRouteSegment McduActor (airways page) Replaces entire en-route portion
SetArrivalSegment Segment As ArrivalSegment McduActor (after NavDb STAR query) Replaces entire ArrivalSegment with loaded STAR legs
SetApproachSegment Segment As ApproachSegment McduActor (after NavDb approach query) Replaces approach leg sequence
SetMissedApproachSegment Segment As MissedApproachSegment McduActor Replaces missed approach leg sequence
InsertWaypoint AfterLegIndex As Integer, Leg As FlightPlanLeg McduActor (F-PLN lateral revision) Inserts leg after global index; -1 inserts at position 0
DeleteWaypoint LegIndex As Integer McduActor (F-PLN lateral revision) Removes leg at global index
SetVerticalConstraint LegIndex, AltConstraintType, AltConstraint1, AltConstraint2, SpeedConstraint McduActor (VERT REV page) Applies altitude/speed constraint to leg; produces new FlightPlanLeg via WithVerticalConstraint
ExecuteDirectTo TargetLegIndex As Integer McduActor (DIR page) Truncates all legs before target; inserts DF leg at front; preserves legs after target
SetHoldingPattern LegIndex As Integer, Holding As HoldingPattern McduActor (HOLD page) Adds or replaces holding in FlightPlan.Holdings dictionary keyed by leg index
RemoveHoldingPattern LegIndex As Integer McduActor (HOLD page) Removes holding at leg index; no-op if none exists
SetFlightInfo FlightNumber As String, CompanyRouteName As String McduActor (INIT A page) Updates flight number and company route name
SetAlternate Alternate As String McduActor (INIT B page) Sets alternate airport ICAO code
CopyFromSecondary SourcePlan As FlightPlan McduActor (TMPY INSERT), KernelActor (plan promotion) Replaces primary plan data with provided plan snapshot. Used both for TMPY acceptance and secondary plan promotion.
ResetPlan KernelActor (plan promotion) Resets secondary plan to FlightPlan.Empty() after promotion

Temporary Flight Plan (TMPY)

The FMGC supports a temporary flight plan (TMPY) for previewing modifications before committing them to the active plan. When a pilot inserts, deletes, or toggles overfly on a waypoint via the FPLN page, the modification is applied to a TMPY copy rather than the active plan. The FPLN page renders TMPY legs in yellow with INSERT*/ERASE labels on L6/R6. The pilot can undo the last change, accept the TMPY (promoting it to the active plan), or erase it entirely.

TmpyActor

TmpyActor (/user/FmgcSupervisor/TmpyActor) is a ReceiveActor that owns the TMPY lifecycle. It is the 13th child of FmgcSupervisor and is shared by both Captain and FO McduActors via EventStream. State fields:

  • _basePlan — the original active plan snapshot at TMPY creation (for erase/revert)
  • _activePlan — the current TMPY state being edited
  • _undoSlot — one-step undo backup (VB6 lvTMPY(0) equivalent)
Message Direction Effect
CreateTmpy McduActor → TmpyActor Snapshots active plan as base; sets TMPY active
ApplyTmpyInsert McduActor → TmpyActor Inserts leg at position; backs up for undo; normalizes consecutive DISCs; publishes TmpyPlanUpdated. McduActor sends the new waypoint BEFORE the target leg (afterLegIndex - 1), then if the target is not a DISC, sends a second insert to place a DISC between the new waypoint and the target (maintaining route separation)
ApplyTmpyDelete McduActor → TmpyActor Deletes leg at index; backs up for undo; if the deleted leg was not a DISC, inserts a DISC at the deletion point (VB6 parity — maintains route separation); normalizes consecutive DISCs; publishes TmpyPlanUpdated
ApplyTmpyOverfly McduActor → TmpyActor Toggles overfly flag on leg via FlightPlan.ToggleOverfly; publishes TmpyPlanUpdated
GetTmpyPlan McduActor → TmpyActor (Ask) Returns TmpyPlanResult with current plan and undo availability
UndoTmpy McduActor → TmpyActor Reverts to _undoSlot (single step); publishes TmpyPlanUpdated
InsertTmpy McduActor → TmpyActor Accepts TMPY — publishes TmpyCleared; resets all state. McduActor separately sends CopyFromSecondary to FlightPlanActor.
EraseTmpy McduActor → TmpyActor Discards TMPY — publishes TmpyErased with base plan; resets all state

EventStream Messages

TmpyActor publishes three event types on the Akka EventStream. Both McduActors subscribe to these:

  • TmpyPlanUpdated(Plan) — after each mutation; McduActor sets _tmpyFplnActive = True, stores plan for rendering, and tells KernelActor RequestTrajectoryRecompute(plan)
  • TmpyCleared — after INSERT accepted; McduActor clears TMPY state and promotes _tmpyComputedFp to _latestComputedFp so the first post-INSERT render has complete VNAV data
  • TmpyErased(BasePlan) — after erase; McduActor clears TMPY state and triggers trajectory recompute with no override (reverts to active plan)

KernelActor also participates in the TMPY trajectory pipeline:

  • KernelActor subscribes to TmpyPlanUpdated and caches the TMPY plan. When a TrajectoryResult arrives while a TMPY plan is cached, KernelActor builds a ComputedFlightPlan from the TMPY plan + trajectory and publishes TmpyComputedFlightPlanResult on the EventStream.
  • KernelActor subscribes to TmpyCleared and TmpyErased — both clear the cached TMPY plan and publish TmpyComputedFlightPlanCleared.
  • McduActor subscribes to TmpyComputedFlightPlanResult and caches it as _tmpyComputedFp. The FPLN page's McduFplnLegBuilder prefers the TMPY ComputedFlightPlan (which has VNAV markers like T/C, T/D, SPDLIM) over the raw TmpyFlightPlan when available.
  • Diagnostic forms (MapView, SideView, RAW FPLN, Computed FPLN) also subscribe to these messages for TMPY visualization (see Trajectory Visualization and Diagnostics).

TMPY and Trajectory Recomputation

Each TMPY mutation triggers an immediate trajectory recomputation via RequestTrajectoryRecompute sent to KernelActor. When the message carries a PlanOverride (the TMPY plan), KernelActor uses it directly instead of asking FlightPlanActor for a snapshot. This allows the trajectory profile to update in real-time as the pilot edits the TMPY plan.

Primary vs Secondary Flight Plan

FmgcSupervisor creates two independent FlightPlanActor instances with different planName constructor parameters:

  • PrimaryFlightPlanActor — path /user/FmgcSupervisor/PrimaryPlan — the active flight plan used for trajectory computation and guidance
  • SecondaryFlightPlanActor — path /user/FmgcSupervisor/SecondaryPlan — used for revisions and secondary F-PLN before activation

Because each actor owns its own private _plan field and all mutations are message-driven, the secondary plan can be modified freely without any risk of corrupting the primary plan. Plan promotion is a two-step message sequence: CopyFromSecondary copies the secondary plan snapshot into the primary actor, then ResetPlan clears the secondary. Actor identities (paths, mailboxes) remain stable — only the data is swapped.

FlightPlan Snapshot

When any actor needs the current flight plan, it uses the Ask + PipeTo pattern to avoid blocking its own mailbox:

_flightPlanActor.Ask(Of FlightPlanSnapshot)(New GetFlightPlan(), TimeSpan.FromMilliseconds(500)) _
    .PipeTo(Self)

The FlightPlanSnapshot wraps the current FlightPlan instance. Because FlightPlan and all its segments and legs are immutable reference types, the snapshot is safe to read from any actor thread without locking. KernelActor requests a snapshot on every KernelTick (1-second timer) and forwards it to TrajectoryActor with a ComputeTrajectory message.

GenerateDisplayRows

The MCDU F-PLN page calls FlightPlanActor with GetFlightPlanDisplayRows to obtain display rows for rendering. The actor calls _plan.GenerateDisplayRows() on demand — this method assembles display data from the immutable in-memory FlightPlan with no caching and no database queries. It iterates all segments in order (Departure → EnRoute → Arrival → Approach → MissedApproach), building one FlightPlanDisplayRow per leg. The result is returned as a FlightPlanDisplayRowsResult reply.

SID / STAR / Approach Loading

Loading a procedure from the navigation database is a two-step process: (1) McduActor queries NavDbActor using the Ask+PipeTo pattern to load the SID (InsertSid flow), STAR (InsertStar flow), or approach (InsertApproach flow); (2) when NavDbActor replies with the procedure legs, McduActor sends the appropriate segment mutation message to FlightPlanActor.

The informal names InsertSid, InsertStar, and InsertApproach refer to this two-step flow. The actual message classes sent to FlightPlanActor are SetDepartureSegment, SetArrivalSegment, and SetApproachSegment respectively. The procedure name and transition are separately recorded via SetDepartureInfo / SetArrivalInfo for display purposes.

ComputedFlightPlan

The ComputedFlightPlan structure merges raw navigation legs from FlightPlan.GetAllLegs() with trajectory-computed predictions from TrajectoryResult into a single unified immutable list. This replaces the earlier two-source pattern where display code had to separately look up predictions from a WaypointPredictions dictionary by waypoint ident (which was never actually populated).

Structure

ComputedFlightPlanLeg is an immutable class combining:

  • Navigation fields (mirrored from FlightPlanLeg): WaypointIdent, Latitude, Longitude, LegType, ArinCCommand, Course, Distance, AltConstraintType, AltConstraint1, SpeedConstraint, IsOverfly, ViaToNext
  • Prediction fields (from nearest ProfilePoint): PredictedAltFt, PredictedIasKts, PredictedMach, PredictedFuelRemainingKg, PredictedEtaHhmm (formatted "HHMMSS"), PredictedWindDir, PredictedWindSpd, PredictedGroundSpeedKts, DistToNextNm, TrackToNextDeg, DistFromDepartureNm, DistToGoNm
  • Performance fields (Phase 20): FuelFlowKgH (fuel flow in kg/h), VerticalSpeedFpm (V/S in ft/min), PerfSourceMdb (True = FMGCPERF1.MDB, False = fallback model)
  • Constraint match fields (Phase 21): SpdCstrMatch ("Y" if predicted IAS within 5 kt of speed constraint, "N" if not, "" if no constraint), AltCstrMatch ("Y" if predicted altitude within 200 ft of altitude constraint respecting @/+/- type, "N" if not, "" if no constraint)
  • Metadata: IsPseudoWaypoint (True for T/C, T/D, and intermediate points), OriginalLeg (reference to the source FlightPlanLeg, Nothing for pseudo-waypoints and intermediates), RawLegIndex (index of this leg in the raw FlightPlan.GetAllLegs() collection; -1 for pseudo/internal waypoints — used by FPLN page mutation commands to target the correct leg in delete, insert, and overfly operations), FlightPhase

Three types of legs appear in the computed list:

Type Ident Pattern LegType IsPseudoWaypoint Description
Named waypoint ICAO ident (e.g. "EDDF", "KPT") From raw leg False Flight plan waypoints matched to nearest ProfilePoint by lat/lon
Pseudo-waypoint (T/C), (T/D) VnavMarker True Top of Climb / Top of Descent at interpolated position
Speed limit marker (SPDLIM) VnavMarker True FL100 crossing point (250 kt IAS restriction boundary); one in climb (ascending), one in descent (descending); SpeedConstraint=250
Intermediate point **00001, **00002, ... Internal True Trajectory computation steps (every ~5 NM) with full prediction data
Non-navigational ---F-PLN DISCONTINUITY--- Discontinuity, EndOfFlightPlan False Structural markers with no position or predictions

ComputedFlightPlan wraps the leg list with Legs As IReadOnlyList(Of ComputedFlightPlanLeg), a ComputedAt timestamp, a HasTrajectory flag (False when built without trajectory data, in which case all prediction fields are zeroed), and ComputationDurationMs As Double — the wall-clock trajectory kernel duration with sub-millisecond precision (measured via Stopwatch in TrajectoryActor.StartComputation).

Builder Algorithm

ComputedFlightPlanBuilder.Build(plan, traj) in ComputedFlightPlanBuilder.vb runs in six phases:

  1. Match named waypoints — collects all ProfilePoints from climb + cruise + descent profiles, sorted by DistanceFromDepartureNm. Each navigational raw leg is matched to its nearest ProfilePoint by lat/lon geographic proximity (not cumulative leg.Distance, which is 0 for minimal airport-to-airport routes). Prediction fields are extracted from the matched point.
  2. Insert T/C and T/D(T/C) uses the last ClimbProfile point (exact values at top of climb: IAS, Mach, GS, fuel remaining, ETA, FF, VS, PerfSource). (T/D) uses the first DescentProfile point. Both carry full prediction data — no zeroed fields.
  3. Insert SPDLIM markers — finds where the trajectory crosses 10,000 ft (FL100) in climb (ascending) and descent (descending). Inserts a (SPDLIM) VnavMarker with SpeedConstraint=250 and PredictedIasKts=250 (always 250 kt at the FL100 boundary, not interpolated). Position, fuel, ETA, and other fields are interpolated between the two bracketing ProfilePoints. Uses InsertAltitudeCrossingMarker.
  4. Insert intermediate points — all ProfilePoints not within 2 NM of a named waypoint or pseudo-waypoint are inserted as **00001, **00002, ... (5-digit, FlightPlanLegType.Internal) with full prediction data (altitude, speed, fuel, ETA, wind, ground speed). These are the trajectory computation steps (typically every 5 NM) that appear on the map view and side view.
  5. Sort by distance — all navigational items (named waypoints + pseudo-waypoints + intermediates) sorted by DistFromDepartureNm to ensure chronological order.
  6. Compute DistToNext/TrackToNextGeoCalculations.DistanceNm and GeoCalculations.Bearing between each pair of consecutive items in the sorted list.
  7. Re-insert non-nav legs — Discontinuity, EndOfFlightPlan and other non-navigational legs are spliced back into the sorted list at their original structural positions relative to the named waypoints.

Data Flow

KernelActor builds and publishes ComputedFlightPlanResult to the EventStream on two triggers:

  • When a new TrajectoryResult arrives (and a FlightPlanSnapshot is already cached)
  • When a new FlightPlanSnapshot arrives (and a TrajectoryResult is already cached)

McduActor subscribes to ComputedFlightPlanResult and caches the latest ComputedFlightPlan. It is passed to pages via McduContext.ComputedFlightPlan. The MCDU F-PLN page iterates directly over ComputedFlightPlan.Legs as the primary data source, rendering UTC, SPD/ALT, EFOB, T WIND, and BRG/DIST columns from each ComputedFlightPlanLeg. When TMPY is active, McduFplnLegBuilder prefers McduContext.TmpyComputedFlightPlan (which includes VNAV markers) over raw TmpyFlightPlan; falls back to raw legs via BuildFromRawLegs() if the TMPY computed plan is not yet available. When no trajectory is available (HasTrajectory = False), it falls back to raw FlightPlan.GetAllLegs() wrapped with FromLeg(). Speed and altitude constraint match markers (SpdCstrMatch / AltCstrMatch) drive magenta/yellow asterisk rendering; MagneticVariationDeg from McduContext converts true track to magnetic for TRK labels.

Navigating to the F-PLN page (via the F-PLN hardkey) resets _fplnTopIndex to 0, ensuring the page always starts at the top of the leg list.

Source Files

  • A320_FMGC/FlightPlan/FlightPlanActor.vb — mutation handlers, GetFlightPlan, GetFlightPlanDisplayRows, plan promotion
  • A320_FMGC/FlightPlan/FlightPlanModels.vbFlightPlan, DepartureSegment, EnRouteSegment, ArrivalSegment, ApproachSegment, MissedApproachSegment, FlightPlanLeg, FlightPlanLegType, HoldingPattern
  • A320_FMGC/FlightPlan/FlightPlanMessages.vb — all message class definitions listed in the Mutation Operations table
  • A320_FMGC/FlightPlan/ComputedFlightPlanModels.vbComputedFlightPlanLeg (29 fields), ComputedFlightPlan container, FromLeg() and CreatePseudoWaypoint() factory methods
  • A320_FMGC/FlightPlan/ComputedFlightPlanBuilder.vb — 6-phase Build() merge algorithm, lat/lon matching, intermediate **nnn insertion, InterpolatePosition(), FormatEta(), WithDistToNext()
  • A320_FMGC/FlightPlan/ComputedFlightPlanMessages.vbComputedFlightPlanResult, TmpyComputedFlightPlanResult, TmpyComputedFlightPlanCleared EventStream messages
  • A320_FMGC/Kernel/KernelActor.vbKernelTick handler, Ask(Of FlightPlanSnapshot).PipeTo(Self), ComputeTrajectory dispatch, ComputedFlightPlan build and publish