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 stringLatitude/Longitude— geographic positionArinCCommand— 2-char ARINC 424 path terminator (e.g. "TF", "CF", "DF", "CA")LegType—FlightPlanLegTypeenum (Normal, Sid, Star, Approach, Hold, etc.)AltConstraint1/AltConstraint2/AltConstraintType— altitude constraint windowSpeedConstraint— 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 (VB6lvTMPY(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 KernelActorRequestTrajectoryRecompute(plan)TmpyCleared— after INSERT accepted; McduActor clears TMPY state and promotes_tmpyComputedFpto_latestComputedFpso the first post-INSERT render has complete VNAV dataTmpyErased(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:
KernelActorsubscribes toTmpyPlanUpdatedand caches the TMPY plan. When aTrajectoryResultarrives while a TMPY plan is cached, KernelActor builds aComputedFlightPlanfrom the TMPY plan + trajectory and publishesTmpyComputedFlightPlanResulton the EventStream.KernelActorsubscribes toTmpyClearedandTmpyErased— both clear the cached TMPY plan and publishTmpyComputedFlightPlanCleared.McduActorsubscribes toTmpyComputedFlightPlanResultand caches it as_tmpyComputedFp. The FPLN page'sMcduFplnLegBuilderprefers the TMPY ComputedFlightPlan (which has VNAV markers like T/C, T/D, SPDLIM) over the rawTmpyFlightPlanwhen 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 guidanceSecondaryFlightPlanActor— 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 sourceFlightPlanLeg,Nothingfor pseudo-waypoints and intermediates),RawLegIndex(index of this leg in the rawFlightPlan.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:
- Match named waypoints — collects all
ProfilePoints from climb + cruise + descent profiles, sorted byDistanceFromDepartureNm. Each navigational raw leg is matched to its nearestProfilePointby lat/lon geographic proximity (not cumulativeleg.Distance, which is 0 for minimal airport-to-airport routes). Prediction fields are extracted from the matched point. - Insert T/C and T/D —
(T/C)uses the lastClimbProfilepoint (exact values at top of climb: IAS, Mach, GS, fuel remaining, ETA, FF, VS, PerfSource).(T/D)uses the firstDescentProfilepoint. Both carry full prediction data — no zeroed fields. - Insert SPDLIM markers — finds where the trajectory crosses 10,000 ft (FL100) in climb (ascending) and descent (descending). Inserts a
(SPDLIM)VnavMarker withSpeedConstraint=250andPredictedIasKts=250(always 250 kt at the FL100 boundary, not interpolated). Position, fuel, ETA, and other fields are interpolated between the two bracketing ProfilePoints. UsesInsertAltitudeCrossingMarker. - 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. - Sort by distance — all navigational items (named waypoints + pseudo-waypoints + intermediates) sorted by
DistFromDepartureNmto ensure chronological order. - Compute DistToNext/TrackToNext —
GeoCalculations.DistanceNmandGeoCalculations.Bearingbetween each pair of consecutive items in the sorted list. - 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
TrajectoryResultarrives (and aFlightPlanSnapshotis already cached) - When a new
FlightPlanSnapshotarrives (and aTrajectoryResultis 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 promotionA320_FMGC/FlightPlan/FlightPlanModels.vb—FlightPlan,DepartureSegment,EnRouteSegment,ArrivalSegment,ApproachSegment,MissedApproachSegment,FlightPlanLeg,FlightPlanLegType,HoldingPatternA320_FMGC/FlightPlan/FlightPlanMessages.vb— all message class definitions listed in the Mutation Operations tableA320_FMGC/FlightPlan/ComputedFlightPlanModels.vb—ComputedFlightPlanLeg(29 fields),ComputedFlightPlancontainer,FromLeg()andCreatePseudoWaypoint()factory methodsA320_FMGC/FlightPlan/ComputedFlightPlanBuilder.vb— 6-phaseBuild()merge algorithm, lat/lon matching, intermediate**nnninsertion,InterpolatePosition(),FormatEta(),WithDistToNext()A320_FMGC/FlightPlan/ComputedFlightPlanMessages.vb—ComputedFlightPlanResult,TmpyComputedFlightPlanResult,TmpyComputedFlightPlanClearedEventStream messagesA320_FMGC/Kernel/KernelActor.vb—KernelTickhandler,Ask(Of FlightPlanSnapshot).PipeTo(Self),ComputeTrajectorydispatch,ComputedFlightPlanbuild and publish