From 15990d30a88cc701410f4b2eba3ffb1ac88696a9 Mon Sep 17 00:00:00 2001 From: Saschl Date: Thu, 22 Dec 2022 09:25:15 +0100 Subject: [PATCH] ix: Improve import flight plan from MSFS World Map #7646 @e97c240 --- .github/CHANGELOG.md | 1 + .../src/flightplanning/FlightPlanAsoboSync.ts | 239 ++++++++++-------- .../src/flightplanning/FlightPlanManager.ts | 69 +++-- src/fmgc/src/flightplanning/LegsProcedure.ts | 169 +++++++------ .../src/flightplanning/ManagedFlightPlan.ts | 160 ++++++------ src/fmgc/src/flightplanning/RawDataMapper.ts | 20 +- 6 files changed, 359 insertions(+), 299 deletions(-) diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index 179dd360354..494ec5915d3 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -17,6 +17,7 @@ 1. [FLIGHTMODEL] Reduced flap induced drag - @donstim (donbikes#4084) 1. [RMP] RMPs navigation backup - Julian Sebline (Julian Sebline#8476 on Discord) 1. [EFB] Fix and improve pushback system and add API documentation - @frankkopp (Frank Kopp) +1. [FMGC] Improved importing flight plans from MSFS World Map - @frankkopp (Frank Kopp) ## 0.9.0 diff --git a/src/fmgc/src/flightplanning/FlightPlanAsoboSync.ts b/src/fmgc/src/flightplanning/FlightPlanAsoboSync.ts index 5c7367c6268..483e68bf223 100644 --- a/src/fmgc/src/flightplanning/FlightPlanAsoboSync.ts +++ b/src/fmgc/src/flightplanning/FlightPlanAsoboSync.ts @@ -45,142 +45,159 @@ export class FlightPlanAsoboSync { Coherent.call('LOAD_CURRENT_ATC_FLIGHTPLAN').catch(console.error); setTimeout(() => { Coherent.call('GET_FLIGHTPLAN').then(async (data: Record) => { - console.log('COHERENT GET_FLIGHTPLAN received'); - const { isDirectTo } = data; + console.log('COHERENT GET_FLIGHTPLAN received:'); + console.log('Data from MSFS flight plan:', data); + // Purpose unclear // TODO: talk to matt about dirto - if (!isDirectTo) { - // TODO FIXME: better handling of mid-air spawning and syncing fpln - if (data.waypoints.length === 0 || data.waypoints[0].icao[0] !== 'A') { - fpln.resumeSync(); - resolve(); - return; - } + const { isDirectTo } = data; + if (isDirectTo) { + return; + } - await fpln._parentInstrument.facilityLoader.getFacilityRaw(data.waypoints[0].icao, 10000).catch((e) => { - console.error('[FP LOAD] Error getting first wp data'); - console.error(e); - }); + // Mid air flight plan loading not yet supported - return if first waypoint is not an airport + // TODO FIXME: better handling of mid-air spawning and syncing fpln + if (data.waypoints.length === 0 || data.waypoints[0].icao[0] !== 'A') { + fpln.resumeSync(); + resolve(); + return; + } - // set origin - await fpln.setOrigin(data.waypoints[0].icao).catch((e) => { - console.error('[FP LOAD] Error setting origin'); - console.error(e); - }); + // result dismissed - why?? + // assumption: counter timeout issues when reading facility from MSFS? + await fpln._parentInstrument.facilityLoader.getFacilityRaw(data.waypoints[0].icao, 10000).catch((e) => { + console.error('[FP LOAD] Error getting first wp data'); + console.error(e); + }); - // set dest - await fpln.setDestination(data.waypoints[data.waypoints.length - 1].icao).catch((e) => { - console.error('[FP LOAD] Error setting Destination'); - console.error(e); - }); + // set origin + await fpln.setOrigin(data.waypoints[0].icao).catch((e) => { + console.error('[FP LOAD] Error setting origin'); + console.error(e); + }); + + // set dest + await fpln.setDestination(data.waypoints[data.waypoints.length - 1].icao).catch((e) => { + console.error('[FP LOAD] Error setting Destination'); + console.error(e); + }); - // set route + // set route + const enrouteStart = (data.departureWaypointsSize === -1) ? 1 : data.departureWaypointsSize; + // Find out first approach waypoint, - 1 to skip destination + const enrouteEnd = data.waypoints.length - ((data.arrivalWaypointsSize === -1) ? 0 : data.arrivalWaypointsSize) - 1; + const enroute = data.waypoints.slice(enrouteStart, enrouteEnd); - const enrouteStart = (data.departureWaypointsSize === -1) ? 1 : data.departureWaypointsSize; - // Find out first approach waypoint, - 1 to skip destination - const enrouteEnd = data.waypoints.length - ((data.arrivalWaypointsSize === -1) ? 1 : data.arrivalWaypointsSize) - 1; - const enroute = data.waypoints.slice(enrouteStart, enrouteEnd - 1); - for (let i = 0; i < enroute.length - 1; i++) { - const wpt = enroute[i]; - if (wpt.icao.trim() !== '') { - fpln.addWaypoint(wpt.icao, Infinity, () => console.log(`[FP LOAD] Adding [${wpt.icao}]... SUCCESS`)).catch(console.error); - } + for (let i = 0; i < enroute.length; i++) { + const wpt = enroute[i]; + if (wpt.icao.trim() !== '') { + // Without the 'await' the order of import is undefined and the flight plan waypoints + // are not in the correct order + // eslint-disable-next-line no-await-in-loop + await fpln.addWaypoint(wpt.icao, Infinity, + () => { + // console.log(`[FP LOAD] Adding [${wpt.icao}]... SUCCESS`); + }) + .catch(console.error); } + } - // set departure - // rwy index - await fpln.setDepartureRunwayIndex(data.departureRunwayIndex) - // .then(() => console.log(`[FP LOAD] Setting Departure Runway ${data.departureRunwayIndex} ... SUCCESS`)) - .catch((e) => { - console.error(`[FP LOAD] Setting Departure Runway ${data.departureRunwayIndex} ... FAILED`); - console.error(e); - }); - // proc index - await fpln.setDepartureProcIndex(data.departureProcIndex) - // .then(() => console.log(`[FP LOAD] Setting Departure Procedure ${data.departureProcIndex} ... SUCCESS`)) + // set departure + // rwy index + await fpln.setDepartureRunwayIndex(data.departureRunwayIndex) + // .then(() => console.log(`[FP LOAD] Setting Departure Runway ${data.departureRunwayIndex} ... SUCCESS`)) + .catch((e) => { + console.error(`[FP LOAD] Setting Departure Runway ${data.departureRunwayIndex} ... FAILED`); + console.error(e); + }); + // proc index + await fpln.setDepartureProcIndex(data.departureProcIndex) + // .then(() => console.log(`[FP LOAD] Setting Departure Procedure ${data.departureProcIndex} ... SUCCESS`)) + .catch((e) => { + console.error(`[FP LOAD] Setting Departure Procedure ${data.departureProcIndex} ... FAILED`); + console.error(e); + }); + // origin runway + if (data.originRunwayIndex !== -1) { + await fpln.setOriginRunwayIndex(data.originRunwayIndex) + // .then(() => console.log(`[FP LOAD] Setting Origin ${data.originRunwayIndex} ... SUCCESS`)) .catch((e) => { - console.error(`[FP LOAD] Setting Departure Procedure ${data.departureProcIndex} ... FAILED`); + console.error(`[FP LOAD] Setting Origin ${data.originRunwayIndex} ... FAILED`); console.error(e); }); - // origin runway - if (data.originRunwayIndex !== -1) { - await fpln.setOriginRunwayIndex(data.originRunwayIndex) - // .then(() => console.log(`[FP LOAD] Setting Origin ${data.originRunwayIndex} ... SUCCESS`)) - .catch((e) => { - console.error(`[FP LOAD] Setting Origin ${data.originRunwayIndex} ... FAILED`); - console.error(e); - }); - } else if (data.departureRunwayIndex !== -1 && data.departureProcIndex !== -1) { - await fpln.setOriginRunwayIndexFromDeparture() - // .then(() => console.log(`[FP LOAD] Setting Origin using ${data.departureProcIndex}/${data.departureRunwayIndex}... SUCCESS`)) + } else if (data.departureRunwayIndex !== -1 && data.departureProcIndex !== -1) { + await fpln.setOriginRunwayIndexFromDeparture() + // .then(() => console.log(`[FP LOAD] Setting Origin using ${data.departureProcIndex}/${data.departureRunwayIndex}... SUCCESS`)) .catch((e) => { - console.error(`[FP LOAD] Setting Origin using ${data.departureProcIndex}/${data.departureRunwayIndex} ... FAILED`); - console.error(e); - }); - } - // enroutetrans index - await fpln.setDepartureEnRouteTransitionIndex(data.departureEnRouteTransitionIndex) - // .then(() => console.log(`[FP LOAD] Setting Departure En Route Transition ${data.departureEnRouteTransitionIndex} ... SUCCESS`)) - .catch((e) => { - console.error(`[FP LOAD] Setting Departure En Route Transition ${data.departureEnRouteTransitionIndex} ... FAILED`); + console.error(`[FP LOAD] Setting Origin using ${data.departureProcIndex}/${data.departureRunwayIndex} ... FAILED`); console.error(e); }); - // set approach - // rwy index - await fpln.setArrivalRunwayIndex(data.arrivalRunwayIndex) - // .then(() => console.log(`[FP LOAD] Setting Arrival Runway ${data.arrivalRunwayIndex} ... SUCCESS`)) + } + // enroutetrans index + await fpln.setDepartureEnRouteTransitionIndex(data.departureEnRouteTransitionIndex) + // .then(() => console.log(`[FP LOAD] Setting Departure En Route Transition ${data.departureEnRouteTransitionIndex} ... SUCCESS`)) + .catch((e) => { + console.error(`[FP LOAD] Setting Departure En Route Transition ${data.departureEnRouteTransitionIndex} ... FAILED`); + console.error(e); + }); + // set approach + // rwy index + await fpln.setArrivalRunwayIndex(data.arrivalRunwayIndex) + // .then(() => console.log(`[FP LOAD] Setting Arrival Runway ${data.arrivalRunwayIndex} ... SUCCESS`)) .catch((e) => { console.error(`[FP LOAD] Setting Arrival Runway ${data.arrivalRunwayIndex} ... FAILED`); console.error(e); }); - // approach index - await fpln.setApproachIndex(data.approachIndex) - // .then(() => console.log(`[FP LOAD] Setting Approach ${data.approachIndex} ... SUCCESS`)) - .catch((e) => { - console.error(`[FP LOAD] Setting Approach ${data.approachIndex} ... FAILED`); - console.error(e); - }); - // approachtrans index - await fpln.setApproachTransitionIndex(data.approachTransitionIndex) - // .then(() => console.log(`[FP LOAD] Setting Approach Transition ${data.approachTransitionIndex} ... SUCCESS`)) - .catch((e) => { - console.error(`[FP LOAD] Setting Approach Transition ${data.approachTransitionIndex} ... FAILED`); - console.error(e); - }); + // approach index + await fpln.setApproachIndex(data.approachIndex) + // .then(() => console.log(`[FP LOAD] Setting Approach ${data.approachIndex} ... SUCCESS`)) + .catch((e) => { + console.error(`[FP LOAD] Setting Approach ${data.approachIndex} ... FAILED`); + console.error(e); + }); + // approachtrans index + await fpln.setApproachTransitionIndex(data.approachTransitionIndex) + // .then(() => console.log(`[FP LOAD] Setting Approach Transition ${data.approachTransitionIndex} ... SUCCESS`)) + .catch((e) => { + console.error(`[FP LOAD] Setting Approach Transition ${data.approachTransitionIndex} ... FAILED`); + console.error(e); + }); - // set arrival - // arrivalproc index - await fpln.setArrivalProcIndex(data.arrivalProcIndex) - // .then(() => console.log(`[FP LOAD] Setting Arrival Procedure ${data.arrivalProcIndex} ... SUCCESS`)) - .catch((e) => { - console.error(`[FP LOAD] Setting Arrival Procedure ${data.arrivalProcIndex} ... FAILED`); - console.error(e); - }); - // arrivaltrans index - await fpln.setArrivalEnRouteTransitionIndex(data.arrivalEnRouteTransitionIndex) - // .then(() => console.log(`[FP LOAD] Setting En Route Transition ${data.arrivalEnRouteTransitionIndex} ... SUCCESS`)) - .catch((e) => { - console.error(`[FP LOAD] Setting En Route Transition ${data.arrivalEnRouteTransitionIndex} ... FAILED`); - console.error(e); - }); + // set arrival + // arrivalproc index + await fpln.setArrivalProcIndex(data.arrivalProcIndex) + // .then(() => console.log(`[FP LOAD] Setting Arrival Procedure ${data.arrivalProcIndex} ... SUCCESS`)) + .catch((e) => { + console.error(`[FP LOAD] Setting Arrival Procedure ${data.arrivalProcIndex} ... FAILED`); + console.error(e); + }); + // arrivaltrans index + await fpln.setArrivalEnRouteTransitionIndex(data.arrivalEnRouteTransitionIndex) + // .then(() => console.log(`[FP LOAD] Setting En Route Transition ${data.arrivalEnRouteTransitionIndex} ... SUCCESS`)) + .catch((e) => { + console.error(`[FP LOAD] Setting En Route Transition ${data.arrivalEnRouteTransitionIndex} ... FAILED`); + console.error(e); + }); - await fpln.setDestinationRunwayIndexFromApproach() - // .then(() => console.log(`[FP LOAD] Setting Destination Runway using ${data.approachIndex} ... SUCCESS`)) + await fpln.setDestinationRunwayIndexFromApproach() + // .then(() => console.log(`[FP LOAD] Setting Destination Runway using ${data.approachIndex} ... SUCCESS`)) .catch((e) => { console.error(`[FP LOAD] Setting Destination Runway using ${data.approachIndex} ... FAILED`); console.error(e); }); - fpln.resumeSync(); + fpln.resumeSync(); - this.fpChecksum = fpln.getCurrentFlightPlan().checksum; - // Potential CTD source? - Coherent.call('SET_ACTIVE_WAYPOINT_INDEX', 0) - .catch((e) => console.error('[FP LOAD] Error when setting Active WP')); - Coherent.call('RECOMPUTE_ACTIVE_WAYPOINT_INDEX') - .catch((e) => console.error('[FP LOAD] Error when recomputing Active WP')); - resolve(); - } + this.fpChecksum = fpln.getCurrentFlightPlan().checksum; + + // Potential CTD source? + Coherent.call('SET_ACTIVE_WAYPOINT_INDEX', 0) + .catch((e) => console.error('[FP LOAD] Error when setting Active WP', e)); + Coherent.call('RECOMPUTE_ACTIVE_WAYPOINT_INDEX') + .catch((e) => console.error('[FP LOAD] Error when recomputing Active WP', e)); + resolve(); + + console.log('Resulting aircraft flight plan: ', fpln); }).catch(console.error); }, 500); }, 200); @@ -270,8 +287,8 @@ export class FlightPlanAsoboSync { this.fpChecksum = plan.checksum; } Coherent.call('RECOMPUTE_ACTIVE_WAYPOINT_INDEX') - .catch((e) => console.log('[FP SAVE] Setting Active Waypoint... FAILED')) - .then(() => console.log('[FP SAVE] Setting Active Waypoint... SUCCESS')); + // .then(() => console.log('[FP SAVE] Setting Active Waypoint... SUCCESS')) + .catch((e) => console.log('[FP SAVE] Setting Active Waypoint... FAILED: ', e)); })); }); } diff --git a/src/fmgc/src/flightplanning/FlightPlanManager.ts b/src/fmgc/src/flightplanning/FlightPlanManager.ts index 1a936471045..cf111cd84cf 100644 --- a/src/fmgc/src/flightplanning/FlightPlanManager.ts +++ b/src/fmgc/src/flightplanning/FlightPlanManager.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-underscore-dangle */ /* * MIT License * @@ -23,16 +24,16 @@ */ import { NXDataStore } from '@shared/persistence'; -import { LegType, TurnDirection } from '@fmgc/types/fstypes/FSEnums'; +import { LegType } from '@fmgc/types/fstypes/FSEnums'; import { FlightLevel } from '@fmgc/guidance/vnav/verticalFlightPlan/VerticalFlightPlan'; +import { LnavConfig } from '@fmgc/guidance/LnavConfig'; +import { ApproachStats, HoldData } from '@fmgc/flightplanning/data/flightplan'; +import { SegmentType } from '@fmgc/wtsdk'; import { ManagedFlightPlan } from './ManagedFlightPlan'; import { GPS } from './GPS'; import { FlightPlanSegment } from './FlightPlanSegment'; import { FlightPlanAsoboSync } from './FlightPlanAsoboSync'; import { FixInfo } from './FixInfo'; -import { LnavConfig } from '@fmgc/guidance/LnavConfig'; -import { ApproachStats, HoldData } from '@fmgc/flightplanning/data/flightplan'; -import { SegmentType } from '@fmgc/wtsdk'; export enum WaypointConstraintType { CLB = 1, @@ -149,9 +150,12 @@ export class FlightPlanManager { } public registerListener() { + // empty } + // eslint-disable-next-line @typescript-eslint/no-unused-vars public addHardCodedConstraints(wp) { + // empty } /** @@ -160,7 +164,9 @@ export class FlightPlanManager { * @param currentWaypoints The waypoints array to modify with the data loaded. * @param callback A callback to call when the data has completed loading. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars private _loadWaypoints(data: any, currentWaypoints: any, callback: () => void) { + // empty } /** @@ -177,6 +183,7 @@ export class FlightPlanManager { * @param {() => void} callback A callback to call when the update has completed. * @param {Boolean} log Whether or not to log the loaded flight plan value. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public updateFlightPlan(callback: () => void = () => { }, log = false, force = false): void { const flightPlanVersion = SimVar.GetSimVarValue(FlightPlanManager.FlightPlanVersionKey, 'number'); if (flightPlanVersion !== this._currentFlightPlanVersion || force) { @@ -202,6 +209,7 @@ export class FlightPlanManager { } } + // eslint-disable-next-line @typescript-eslint/no-unused-vars public updateCurrentApproach(callback = () => { }, log = false): void { callback(); } @@ -356,16 +364,18 @@ export class FlightPlanManager { * @param forceSimVarCall Unused * @param useCorrection Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public getActiveWaypointIndex(forceSimVarCall = false, useCorrection = false, flightPlanIndex = NaN): number { - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { return this._flightPlans[this._currentFlightPlanIndex].activeWaypointIndex; } return this._flightPlans[flightPlanIndex]?.activeWaypointIndex ?? -1; } + // eslint-disable-next-line @typescript-eslint/no-unused-vars public isActiveWaypointAtEnd(forceSimVarCall = false, useCorrection = false, flightPlanIndex = NaN): boolean { - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { return this._flightPlans[this._currentFlightPlanIndex].activeWaypointIndex + 1 === this.getWaypointsCount(this._currentFlightPlanIndex) - 1; } return this._flightPlans[flightPlanIndex].activeWaypointIndex === this.getWaypointsCount(flightPlanIndex) - 1; @@ -403,6 +413,7 @@ export class FlightPlanManager { * Gets the index of the waypoint prior to the currently active waypoint. * @param forceSimVarCall Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public getPreviousActiveWaypoint(forceSimVarCall = false): WayPoint { const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; const previousWaypointIndex = currentFlightPlan.activeWaypointIndex - 1; @@ -414,6 +425,7 @@ export class FlightPlanManager { * Gets the ident of the active waypoint. * @param forceSimVarCall Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public getActiveWaypointIdent(forceSimVarCall = false): string { const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; if (currentFlightPlan.activeWaypoint) { @@ -427,6 +439,7 @@ export class FlightPlanManager { * Gets the active waypoint index from fs9gps. Currently unimplemented. * @param forceSimVarCall Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public getGPSActiveWaypointIndex(forceSimVarCall = false): number { return this.getActiveWaypointIndex(); } @@ -436,8 +449,9 @@ export class FlightPlanManager { * @param forceSimVarCall Unused * @param useCorrection Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public getActiveWaypoint(forceSimVarCall = false, useCorrection = false, flightPlanIndex = NaN): WayPoint { - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { flightPlanIndex = this._currentFlightPlanIndex; } @@ -448,6 +462,7 @@ export class FlightPlanManager { * Gets the next waypoint following the active waypoint. * @param forceSimVarCall Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public getNextActiveWaypoint(forceSimVarCall = false): WayPoint { const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; const nextWaypointIndex = currentFlightPlan.activeWaypointIndex + 1; @@ -510,7 +525,7 @@ export class FlightPlanManager { return { name, distanceFromPpos, - } + }; } /** @@ -578,7 +593,7 @@ export class FlightPlanManager { */ public getDeparture(flightPlanIndex = NaN): WayPoint | undefined { const origin = this.getOrigin(); - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { flightPlanIndex = this._currentFlightPlanIndex; } const currentFlightPlan = this._flightPlans[flightPlanIndex]; @@ -678,7 +693,7 @@ export class FlightPlanManager { /** * Gets the index of the last waypoint in the enroute segment of the current flight plan. */ - public getEnRouteWaypointsFirstIndex(flightPlanIndex = this._currentFlightPlanIndex): number | null { + public getEnRouteWaypointsFirstIndex(flightPlanIndex = this._currentFlightPlanIndex): number | null { const currentFlightPlan = this._flightPlans[flightPlanIndex]; const enrouteSegment = currentFlightPlan?.enroute; @@ -721,7 +736,7 @@ export class FlightPlanManager { * @param waypoint The waypoint we want to find the segment for. */ public getSegmentFromWaypoint(waypoint: WayPoint | undefined, flightPlanIndex = NaN): FlightPlanSegment { - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { flightPlanIndex = this._currentFlightPlanIndex; } @@ -947,6 +962,7 @@ export class FlightPlanManager { * @param {*} _callback Unused */ public addFlightPlanUpdateCallback(_callback) { + // empty } /** @@ -972,6 +988,7 @@ export class FlightPlanManager { callback(); } + // eslint-disable-next-line @typescript-eslint/no-unused-vars addWaypointOverfly(index: number, thenSetActive = false, callback = () => { }): void { this._flightPlans[this._currentFlightPlanIndex].setWaypointOverfly(index, true); @@ -979,6 +996,7 @@ export class FlightPlanManager { callback(); } + // eslint-disable-next-line @typescript-eslint/no-unused-vars removeWaypointOverfly(index: number, thenSetActive = false, callback = () => { }): void { this._flightPlans[this._currentFlightPlanIndex].setWaypointOverfly(index, false); @@ -1008,6 +1026,7 @@ export class FlightPlanManager { * @param index The index of the first waypoint to remove. * @param callback A callback to call when the operation finishes. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public truncateWaypoints(index: number, thenSetActive = false, callback = () => { }): void { const fp = this._flightPlans[this._currentFlightPlanIndex]; for (let i = fp.length; i >= index; i--) { @@ -1031,7 +1050,7 @@ export class FlightPlanManager { * @param flightPlanIndex The index of the flight plan. If omitted, will get the current flight plan. */ public getWaypointsCount(flightPlanIndex = NaN): number { - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { return this._flightPlans[this._currentFlightPlanIndex]?.length ?? 0; } @@ -1058,8 +1077,9 @@ export class FlightPlanManager { * @param flightPlanIndex The index of the flight plan to get the waypoint from. If omitted, will get from the current flight plan. * @param considerApproachWaypoints Whether or not to consider approach waypoints. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public getWaypoint(index: number, flightPlanIndex = NaN, considerApproachWaypoints = false): WayPoint | undefined { - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { flightPlanIndex = this._currentFlightPlanIndex; } @@ -1072,7 +1092,7 @@ export class FlightPlanManager { * @param flightPlanIndex The index of the flight plan to get the waypoints from. If omitted, will get from the current flight plan. */ public getWaypoints(flightPlanIndex = NaN): WayPoint[] { - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { flightPlanIndex = this._currentFlightPlanIndex; } @@ -1223,12 +1243,11 @@ export class FlightPlanManager { && currentFlightPlan.procedureDetails.departureIndex >= 0 && currentFlightPlan.originAirfield ) { - const transition = (currentFlightPlan.originAirfield.infos as AirportInfo) .departures[currentFlightPlan.procedureDetails.departureIndex] .runwayTransitions[currentFlightPlan.procedureDetails.departureRunwayIndex]; const runways = (currentFlightPlan.originAirfield.infos as AirportInfo).oneWayRunways; - await this.setOriginRunwayIndex(runways.findIndex(r => r.number === transition.runwayNumber && r.designator === transition.runwayDesignation)); + await this.setOriginRunwayIndex(runways.findIndex((r) => r.number === transition.runwayNumber && r.designator === transition.runwayDesignation)); } } @@ -1262,6 +1281,7 @@ export class FlightPlanManager { * Unused */ public getDepartureDiscontinuity() { + // empty } /** @@ -1335,6 +1355,7 @@ export class FlightPlanManager { * Unused */ public getArrivalDiscontinuity() { + // empty } /** @@ -1451,11 +1472,9 @@ export class FlightPlanManager { const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; if (currentFlightPlan.hasDestination && currentFlightPlan.procedureDetails.approachIndex >= 0) { - console.error('Destination runway index is -1 with valid STAR'); const approach = (currentFlightPlan.destinationAirfield.infos as AirportInfo).approaches[currentFlightPlan.procedureDetails.approachIndex]; const destRunways = (currentFlightPlan.destinationAirfield.infos as AirportInfo).oneWayRunways; - - await this.setDestinationRunwayIndex(destRunways.findIndex(r => r.number === approach.runwayNumber && r.designator === approach.runwayDesignator)); + await this.setDestinationRunwayIndex(destRunways.findIndex((r) => r.number === approach.runwayNumber && r.designator === approach.runwayDesignator)); } } @@ -1472,6 +1491,7 @@ export class FlightPlanManager { * @param callback A callback to call when the operation has completed. * @param transition The approach transition index to set in the approach information. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public async setApproachIndex(index: number, callback = () => { }, transition = -1): Promise { const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; // console.log(currentFlightPlan); @@ -1494,6 +1514,7 @@ export class FlightPlanManager { * Whether or not an approach is loaded in the current flight plan. * @param forceSimVarCall Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public isLoadedApproach(forceSimVarCall = false): boolean { const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; return currentFlightPlan.procedureDetails.approachIndex >= 0; @@ -1503,6 +1524,7 @@ export class FlightPlanManager { * Whether or not the approach is active in the current flight plan. * @param forceSimVarCall Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public isActiveApproach(forceSimVarCall = false): boolean { const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; return currentFlightPlan.approach.waypoints.length > 0 @@ -1526,12 +1548,14 @@ export class FlightPlanManager { * Deactivates the approach segments in the current flight plan. */ public deactivateApproach() { + // empty } /** * Attemptes to auto-activate the approach in the current flight plan. */ public tryAutoActivateApproach() { + // empty } /** @@ -1602,7 +1626,7 @@ export class FlightPlanManager { const approach = (flightPlan.destinationAirfield.infos as AirportInfo).approaches[flightPlan.procedureDetails.approachIndex]; const runways = (flightPlan.destinationAirfield.infos as AirportInfo).oneWayRunways; - return runways.findIndex(r => r.number === approach.runwayNumber && r.designator === approach.runwayDesignator); + return runways.findIndex((r) => r.number === approach.runwayNumber && r.designator === approach.runwayDesignator); } return -1; } @@ -1670,7 +1694,7 @@ export class FlightPlanManager { * @param callback A callback to call when the operation completes. */ public cancelDirectTo(callback = EmptyCallback.Void): void { - const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; + // const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; // currentFlightPlan.directTo.cancel(); callback(); @@ -1703,6 +1727,7 @@ export class FlightPlanManager { } public getCoordinatesHeadingAtDistanceAlongFlightPlan(_distance) { + // empty } /** @@ -1715,11 +1740,9 @@ export class FlightPlanManager { if (destination) { const fromStartDistance = destination.cumulativeDistanceInFP - distance; - let prevIndex; let prev; let next; for (let i = 0; i < allWaypoints.length - 1; i++) { - prevIndex = i; prev = allWaypoints[i]; next = allWaypoints[i + 1]; if (prev.cumulativeDistanceInFP < fromStartDistance && next.cumulativeDistanceInFP > fromStartDistance) { diff --git a/src/fmgc/src/flightplanning/LegsProcedure.ts b/src/fmgc/src/flightplanning/LegsProcedure.ts index 00f06fcabf5..3dfeed7ee75 100644 --- a/src/fmgc/src/flightplanning/LegsProcedure.ts +++ b/src/fmgc/src/flightplanning/LegsProcedure.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-underscore-dangle */ /* * MIT License * @@ -76,7 +77,7 @@ export class LegsProcedure { private airportMagVar: number, private approachType?: ApproachType, private legAnnotations?: string[], - ) { + ) { for (const leg of this._legs) { if (this.isIcaoValid(leg.fixIcao)) { this._facilitiesToLoad.set(leg.fixIcao, this._instrument.facilityLoader.getFacilityRaw(leg.fixIcao, 2000, true)); @@ -262,72 +263,72 @@ export class LegsProcedure { } private getMagCorrection(currentLeg: RawProcedureLeg): number { - // we try to interpret PANS OPs as accurately as possible within the limits of available data - - // magnetic tracks to/from a VOR always use VOR station declination - if (currentLeg.fixIcao.charAt(0) === 'V') { - const vor: RawVor = this.getLoadedFacility(currentLeg.fixIcao) as RawVor; - if (!vor || vor.magneticVariation === undefined) { - console.warn('Leg coded incorrectly (missing vor fix or station declination)', currentLeg, vor); - return this.airportMagVar; + // we try to interpret PANS OPs as accurately as possible within the limits of available data + + // magnetic tracks to/from a VOR always use VOR station declination + if (currentLeg.fixIcao.charAt(0) === 'V') { + const vor: RawVor = this.getLoadedFacility(currentLeg.fixIcao) as RawVor; + if (!vor || vor.magneticVariation === undefined) { + console.warn('Leg coded incorrectly (missing vor fix or station declination)', currentLeg, vor); + return this.airportMagVar; + } + return 360 - vor.magneticVariation; } - return 360 - vor.magneticVariation; - } - // we use station declination for VOR/DME approaches - if (this.approachType === ApproachType.APPROACH_TYPE_VORDME) { + // we use station declination for VOR/DME approaches + if (this.approachType === ApproachType.APPROACH_TYPE_VORDME) { // find a leg with the reference navaid for the procedure - for (let i = this._legs.length - 1; i >= 0; i--) { - if (this._legs[i].originIcao.trim().length > 0) { - const recNavaid: RawVor = this.getLoadedFacility(currentLeg.originIcao) as RawVor; - if (recNavaid && recNavaid.magneticVariation !== undefined) { - return 360 - recNavaid.magneticVariation; + for (let i = this._legs.length - 1; i >= 0; i--) { + if (this._legs[i].originIcao.trim().length > 0) { + const recNavaid: RawVor = this.getLoadedFacility(currentLeg.originIcao) as RawVor; + if (recNavaid && recNavaid.magneticVariation !== undefined) { + return 360 - recNavaid.magneticVariation; + } + } } - } + console.warn('VOR/DME approach coded incorrectly (missing recommended navaid or station declination)', currentLeg); + return this.airportMagVar; } - console.warn('VOR/DME approach coded incorrectly (missing recommended navaid or station declination)', currentLeg); - return this.airportMagVar; - } - // for RNAV procedures use recommended navaid station declination for these leg types - let useStationDeclination = (currentLeg.type === LegType.CF || currentLeg.type === LegType.FA || currentLeg.type === LegType.FM); + // for RNAV procedures use recommended navaid station declination for these leg types + let useStationDeclination = (currentLeg.type === LegType.CF || currentLeg.type === LegType.FA || currentLeg.type === LegType.FM); - // for localiser bearings (i.e. at or beyond FACF), always use airport value - if (this.approachType === ApproachType.APPROACH_TYPE_ILS || this.approachType === ApproachType.APPROACH_TYPE_LOCALIZER) { - useStationDeclination = useStationDeclination && this._legs.indexOf(currentLeg) < this.getFacfIndex(); - } + // for localiser bearings (i.e. at or beyond FACF), always use airport value + if (this.approachType === ApproachType.APPROACH_TYPE_ILS || this.approachType === ApproachType.APPROACH_TYPE_LOCALIZER) { + useStationDeclination = useStationDeclination && this._legs.indexOf(currentLeg) < this.getFacfIndex(); + } - if (useStationDeclination) { - const recNavaid: RawVor = this.getLoadedFacility(currentLeg.originIcao) as RawVor; - if (!recNavaid || recNavaid.magneticVariation === undefined) { - console.warn('Leg coded incorrectly (missing recommended navaid or station declination)', currentLeg, recNavaid); - return this.airportMagVar; + if (useStationDeclination) { + const recNavaid: RawVor = this.getLoadedFacility(currentLeg.originIcao) as RawVor; + if (!recNavaid || recNavaid.magneticVariation === undefined) { + console.warn('Leg coded incorrectly (missing recommended navaid or station declination)', currentLeg, recNavaid); + return this.airportMagVar; + } + return 360 - recNavaid.magneticVariation; } - return 360 - recNavaid.magneticVariation; - } - // for all other terminal procedure legs we use airport magnetic variation - return this.airportMagVar; + // for all other terminal procedure legs we use airport magnetic variation + return this.airportMagVar; } private getLoadedFacility(icao: string): RawFacility { - const facility = this._facilities.get(icao); - if (!facility) { - throw new Error(`Failed to load facility: ${icao}`); - } - return facility; + const facility = this._facilities.get(icao); + if (!facility) { + throw new Error(`Failed to load facility: ${icao}`); + } + return facility; } private getFacfIndex(): number { - if (this.approachType !== undefined) { - for (let i = this._legs.length - 1; i >= 0; i--) { - if (this._legs[i].fixTypeFlags & FixTypeFlags.IF) { - return i; - } + if (this.approachType !== undefined) { + for (let i = this._legs.length - 1; i >= 0; i--) { + if (this._legs[i].fixTypeFlags & FixTypeFlags.IF) { + return i; + } + } } - } - return undefined; + return undefined; } /** @@ -376,37 +377,37 @@ export class LegsProcedure { * @returns The mapped leg. */ public mapBearingAndDistanceFromOrigin(leg: RawProcedureLeg): WayPoint { - const origin = this.getLoadedFacility(leg.fixIcao); - const originIdent = origin.icao.substring(7, 12).trim(); - const course = leg.trueDegrees ? leg.course : A32NX_Util.magneticToTrue(leg.course, Facilities.getMagVar(origin.lat, origin.lon)); - // this is the leg length for FC, and the DME distance for FD - const refDistance = leg.distance / 1852; - - let termPoint; - let legLength; - if (leg.type === LegType.FD) { - const recNavaid = this.getLoadedFacility(leg.originIcao); - termPoint = firstSmallCircleIntersection( - { lat: recNavaid.lat, long: recNavaid.lon }, - refDistance, - { lat: origin.lat, long: origin.lon }, - course, - ); - legLength = Avionics.Utils.computeGreatCircleDistance( - { lat: origin.lat, long: origin.lon }, - termPoint, - ); - } else { // FC - termPoint = Avionics.Utils.bearingDistanceToCoordinates( - course, - refDistance, - origin.lat, - origin.lon, - ); - legLength = refDistance; - } - - return this.buildWaypoint(`${originIdent.substring(0, 3)}/${Math.round(legLength).toString().padStart(2, '0')}`, termPoint); + const origin = this.getLoadedFacility(leg.fixIcao); + const originIdent = origin.icao.substring(7, 12).trim(); + const course = leg.trueDegrees ? leg.course : A32NX_Util.magneticToTrue(leg.course, Facilities.getMagVar(origin.lat, origin.lon)); + // this is the leg length for FC, and the DME distance for FD + const refDistance = leg.distance / 1852; + + let termPoint; + let legLength; + if (leg.type === LegType.FD) { + const recNavaid = this.getLoadedFacility(leg.originIcao); + termPoint = firstSmallCircleIntersection( + { lat: recNavaid.lat, long: recNavaid.lon }, + refDistance, + { lat: origin.lat, long: origin.lon }, + course, + ); + legLength = Avionics.Utils.computeGreatCircleDistance( + { lat: origin.lat, long: origin.lon }, + termPoint, + ); + } else { // FC + termPoint = Avionics.Utils.bearingDistanceToCoordinates( + course, + refDistance, + origin.lat, + origin.lon, + ); + legLength = refDistance; + } + + return this.buildWaypoint(`${originIdent.substring(0, 3)}/${Math.round(legLength).toString().padStart(2, '0')}`, termPoint); } /** @@ -437,6 +438,7 @@ export class LegsProcedure { * @param nextLeg The next leg in the procedure to intercept. * @returns The mapped leg. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public mapHeadingToInterceptNextLeg(leg: RawProcedureLeg, prevLeg: WayPoint, nextLeg: RawProcedureLeg): WayPoint | null { const magVar = Facilities.getMagVar(prevLeg.infos.coordinates.lat, prevLeg.infos.coordinates.long); const course = leg.trueDegrees ? leg.course : A32NX_Util.magneticToTrue(leg.course, magVar); @@ -489,7 +491,7 @@ export class LegsProcedure { public mapHeadingUntilAltitude(leg: RawProcedureLeg, prevLeg: WayPoint) { const magVar = Facilities.getMagVar(prevLeg.infos.coordinates.lat, prevLeg.infos.coordinates.long); const course = leg.trueDegrees ? leg.course : A32NX_Util.magneticToTrue(leg.course, magVar); - const heading = leg.trueDegrees ? A32NX_Util.trueToMagnetic(leg.course, magVar) : leg.course; + // const heading = leg.trueDegrees ? A32NX_Util.trueToMagnetic(leg.course, magVar) : leg.course; const altitudeFeet = (leg.altitude1 * 3.2808399); const distanceInNM = altitudeFeet / 500.0; @@ -510,7 +512,7 @@ export class LegsProcedure { public mapVectors(leg: RawProcedureLeg, prevLeg: WayPoint) { const magVar = Facilities.getMagVar(prevLeg.infos.coordinates.lat, prevLeg.infos.coordinates.long); const course = leg.trueDegrees ? leg.course : A32NX_Util.magneticToTrue(leg.course, magVar); - const heading = leg.trueDegrees ? A32NX_Util.trueToMagnetic(leg.course, magVar) : leg.course; + // const heading = leg.trueDegrees ? A32NX_Util.trueToMagnetic(leg.course, magVar) : leg.course; const coordinates = GeoMath.relativeBearingDistanceToCoords(course, 1, prevLeg.infos.coordinates); const waypoint = this.buildWaypoint(FixNamingScheme.vector(), coordinates); @@ -531,11 +533,10 @@ export class LegsProcedure { return RawDataMapper.toWaypoint(facility, this._instrument); } + // eslint-disable-next-line @typescript-eslint/no-unused-vars public mapArcToFix(leg: RawProcedureLeg, prevLeg: WayPoint): WayPoint { const toFix = this.getLoadedFacility(leg.fixIcao); - const waypoint = RawDataMapper.toWaypoint(toFix, this._instrument); - return waypoint; } diff --git a/src/fmgc/src/flightplanning/ManagedFlightPlan.ts b/src/fmgc/src/flightplanning/ManagedFlightPlan.ts index 30df74e4dc2..39b3712d01b 100644 --- a/src/fmgc/src/flightplanning/ManagedFlightPlan.ts +++ b/src/fmgc/src/flightplanning/ManagedFlightPlan.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-underscore-dangle */ /* * MIT License * @@ -23,6 +24,7 @@ */ import { HoldData, StepData, WaypointStats } from '@fmgc/flightplanning/data/flightplan'; +import { WaypointConstraintType } from '@fmgc/flightplanning/FlightPlanManager'; import { AltitudeDescriptor, FixTypeFlags, LegType } from '../types/fstypes/FSEnums'; import { FlightPlanSegment, SegmentType } from './FlightPlanSegment'; import { LegsProcedure } from './LegsProcedure'; @@ -32,7 +34,6 @@ import { ProcedureDetails } from './ProcedureDetails'; import { DirectTo } from './DirectTo'; import { GeoMath } from './GeoMath'; import { WaypointBuilder } from './WaypointBuilder'; -import { WaypointConstraintType } from '@fmgc/flightplanning/FlightPlanManager'; /** * A flight plan managed by the FlightPlanManager. @@ -200,11 +201,7 @@ export class ManagedFlightPlan { private computeWaypointEta(distance: number, preComputedTime? :number) { const eta = preComputedTime ?? this.computeWaypointTime(distance); - const utcTime = SimVar.GetGlobalVarValue('ZULU TIME', 'seconds'); - - // // console.log(`BRUHEGG: ${utcTime}, BRUHHH #2: ${eta}`); - return eta + utcTime; } @@ -361,7 +358,8 @@ export class ManagedFlightPlan { index?: number | undefined, segmentType?: SegmentType, ): number { - console.log('addWaypoint', waypoint, index, SegmentType[segmentType]); + console.log(`addWaypoint ${waypoint.icao}, ${index}, ${SegmentType[segmentType]}`, waypoint); + const mappedWaypoint: WayPoint = (waypoint instanceof WayPoint) ? waypoint : RawDataMapper.toWaypoint(waypoint, this._parentInstrument); if (mappedWaypoint.type === 'A' && index === 0) { @@ -482,28 +480,21 @@ export class ManagedFlightPlan { * @param index The index of the waypoint to remove. */ public removeWaypoint(index: number, noDiscontinuity: boolean = false): void { - let removed = null; if (this.originAirfield && index === 0) { - removed = this.originAirfield; this.originAirfield = undefined; - this.reflowSegments(); this.reflowDistances(); } else if (this.destinationAirfield && index === this.length - 1) { - removed = this.destinationAirfield; this.destinationAirfield = undefined; } else { const segment = this.findSegmentByWaypointIndex(index); if (segment) { - // console.log("--> REMOVING WAYPOINT ", this.getWaypoint(index), ", FROM SEGMENT ", segment); const spliced = segment.waypoints.splice(index - segment.offset, 1); - removed = spliced[0]; - + console.log(`removing waypoint ${spliced[0].icao} from segment ${segment.type}`); if (segment.waypoints.length === 0 && segment.type !== SegmentType.Enroute) { - // console.log("SEGMENT LENGTH is 0, REMOVING..."); + console.log(`removing segment ${segment.type} as length is 0`); this.removeSegment(segment.type); } - this.reflowSegments(); this.reflowDistances(); } @@ -570,7 +561,7 @@ export class ManagedFlightPlan { const atWaypoint = this.getWaypoint(index); if (!atWaypoint) { - return; + return 0; } const magVar = Facilities.getMagVar(atWaypoint.infos.coordinates.lat, atWaypoint.infos.coordinates.long); @@ -588,14 +579,13 @@ export class ManagedFlightPlan { atWaypoint.additionalData.defaultHold = defaultHold; } return index; - } else { - const manualHoldWaypoint = WaypointBuilder.fromWaypointManualHold(atWaypoint, desiredHold.turnDirection, trueCourse, desiredHold.distance, desiredHold.time, this._parentInstrument); - manualHoldWaypoint.additionalData.modifiedHold = modifiedHold; - manualHoldWaypoint.additionalData.defaultHold = defaultHold; - - this.addWaypoint(manualHoldWaypoint, index + 1); - return index + 1; } + const manualHoldWaypoint = WaypointBuilder.fromWaypointManualHold(atWaypoint, desiredHold.turnDirection, trueCourse, desiredHold.distance, desiredHold.time, this._parentInstrument); + manualHoldWaypoint.additionalData.modifiedHold = modifiedHold; + manualHoldWaypoint.additionalData.defaultHold = defaultHold; + + this.addWaypoint(manualHoldWaypoint, index + 1); + return index + 1; } /** @@ -799,7 +789,7 @@ export class ManagedFlightPlan { newFlightPlan._segments[i].waypoints = [...seg.waypoints.map((wp) => { const clone = new (wp as any).constructor(); Object.assign(clone, wp); - clone.additionalData = Object.assign({}, wp.additionalData); + clone.additionalData = { ...wp.additionalData }; return clone; })]; } @@ -832,10 +822,15 @@ export class ManagedFlightPlan { const oldToWp = this.waypoints[this.activeWaypointIndex]; - const turningPoint = WaypointBuilder.fromCoordinates('T-P', new LatLongAlt(lat, long), this._parentInstrument, { legType: LegType.CF, course: trueTrack, dynamicPpos: true }, this.getTurningPointIcao()); + const turningPoint = WaypointBuilder.fromCoordinates( + 'T-P', + new LatLongAlt(lat, long), + this._parentInstrument, { legType: LegType.CF, course: trueTrack, dynamicPpos: true }, + this.getTurningPointIcao(), + ); turningPoint.isTurningPoint = true; - let waypointIndex = this.waypoints.findIndex((w, idx) => idx >= this.activeWaypointIndex && w.icao === waypoint.icao); + const waypointIndex = this.waypoints.findIndex((w, idx) => idx >= this.activeWaypointIndex && w.icao === waypoint.icao); if (waypointIndex === -1) { // in this case the waypoint is not already in the flight plan // we string it to the start of the flight plan, add a discontinuity after, and then the existing flight plan @@ -880,7 +875,7 @@ export class ManagedFlightPlan { private getTurningPointIcao(): string { this.turningPointIndex = (this.turningPointIndex + 1) % 1000; - return `WXX TP${this.turningPointIndex.toFixed(0).padStart(3, '0')}` + return `WXX TP${this.turningPointIndex.toFixed(0).padStart(3, '0')}`; } /** @@ -925,7 +920,7 @@ export class ManagedFlightPlan { const departure: RawDeparture = airportInfo.departures[departureIndex]; if (runwayTransition) { legs.push(...runwayTransition.legs); - legAnnotations.push(...runwayTransition.legs.map(_ => departure.name)); + legAnnotations.push(...runwayTransition.legs.map((_) => departure.name)); origin.endsInDiscontinuity = false; origin.discontinuityCanBeCleared = undefined; } @@ -934,14 +929,14 @@ export class ManagedFlightPlan { if (departureIndex >= 0) { const departure: RawDeparture = airportInfo.departures[departureIndex]; legs.push(...departure.commonLegs); - legAnnotations.push(...departure.commonLegs.map(_ => departure.name)); + legAnnotations.push(...departure.commonLegs.map((_) => departure.name)); } if (transitionIndex >= 0 && departureIndex >= 0) { if (airportInfo.departures[departureIndex].enRouteTransitions.length > 0) { const transition: RawEnRouteTransition = airportInfo.departures[departureIndex].enRouteTransitions[transitionIndex]; legs.push(...transition.legs); - legAnnotations.push(...transition.legs.map(_ => transition.name)); + legAnnotations.push(...transition.legs.map((_) => transition.name)); } } @@ -956,7 +951,7 @@ export class ManagedFlightPlan { if (legs.length > 0 || selectedOriginRunwayIndex >= 0 || (departureIndex >= 0 && runwayIndex >= 0)) { segment = this.addSegment(SegmentType.Departure); - let procedure = new LegsProcedure(legs, origin, this._parentInstrument, airportMagVar, undefined, legAnnotations); + const procedure = new LegsProcedure(legs, origin, this._parentInstrument, airportMagVar, undefined, legAnnotations); const runway: OneWayRunway | null = this.getOriginRunway(); @@ -983,6 +978,7 @@ export class ManagedFlightPlan { let waypointIndex = segment.offset; while (procedure.hasNext()) { + // eslint-disable-next-line no-await-in-loop const waypoint = await procedure.getNext(); if (waypoint !== undefined) { @@ -1018,7 +1014,7 @@ export class ManagedFlightPlan { const destination = this.destinationAirfield; const { arrivalIndex } = this.procedureDetails; - const { approachTransitionIndex } = this.procedureDetails; + // const { approachTransitionIndex } = this.procedureDetails; const { arrivalRunwayIndex } = this.procedureDetails; const { arrivalTransitionIndex } = this.procedureDetails; @@ -1029,7 +1025,7 @@ export class ManagedFlightPlan { const transition: RawEnRouteTransition = destinationInfo.arrivals[arrivalIndex].enRouteTransitions[arrivalTransitionIndex]; if (transition !== undefined) { legs.push(...transition.legs); - legAnnotations.push(...transition.legs.map(_ => transition.name)); + legAnnotations.push(...transition.legs.map((_) => transition.name)); // console.log('MFP: buildArrival - pushing transition legs ->', legs); } } @@ -1038,7 +1034,7 @@ export class ManagedFlightPlan { // string the common legs in the middle of the STAR const arrival: RawArrival = destinationInfo.arrivals[arrivalIndex]; legs.push(...arrival.commonLegs); - legAnnotations.push(...arrival.commonLegs.map(_ => arrival.name)); + legAnnotations.push(...arrival.commonLegs.map((_) => arrival.name)); // console.log('MFP: buildArrival - pushing STAR legs ->', legs); // if no runway is selected at all (non-runway-specific approach) @@ -1051,7 +1047,7 @@ export class ManagedFlightPlan { const runwayTransition = arrival.runwayTransitions[runwayTransIndex]; if (runwayTransition) { legs.push(...runwayTransition.legs); - legAnnotations.push(...runwayTransition.legs.map(_ => arrival.name)); + legAnnotations.push(...runwayTransition.legs.map((_) => arrival.name)); } } @@ -1068,6 +1064,7 @@ export class ManagedFlightPlan { let waypointIndex = segment.offset; // console.log('MFP: buildArrival - ADDING WAYPOINTS ------------------------'); while (procedure.hasNext()) { + // eslint-disable-next-line no-await-in-loop const waypoint = await procedure.getNext(); if (waypoint) { @@ -1106,7 +1103,7 @@ export class ManagedFlightPlan { if (approachIndex >= 0 && approachTransitionIndex >= 0) { const transition: RawApproachTransition = destinationInfo.approaches[approachIndex].transitions[approachTransitionIndex]; legs.push(...transition.legs); - legAnnotations.push(...transition.legs.map(_ => transition.name)); + legAnnotations.push(...transition.legs.map((_) => transition.name)); // console.log('MFP: buildApproach - pushing approachTransition legs ->', legs); } @@ -1125,7 +1122,7 @@ export class ManagedFlightPlan { this.procedureDetails.approachType = approach.approachType; legs.push(...finalLegs); - legAnnotations.push(...finalLegs.map(_ => approachName)); + legAnnotations.push(...finalLegs.map((_) => approachName)); missedLegs.push(...approach.missedLegs); } @@ -1153,6 +1150,7 @@ export class ManagedFlightPlan { let waypointIndex = _startIndex; // console.log('MFP: buildApproach - ADDING WAYPOINTS ------------------------'); while (procedure.hasNext()) { + // eslint-disable-next-line no-await-in-loop const waypoint = await procedure.getNext(); if (waypoint !== undefined) { @@ -1164,19 +1162,19 @@ export class ManagedFlightPlan { } if (runway) { - const selectedRunwayMod = runway.designation.slice(-1); - let selectedRunwayOutput; - if (selectedRunwayMod === 'L' || selectedRunwayMod === 'C' || selectedRunwayMod === 'R') { - if (runway.designation.length === 2) { - selectedRunwayOutput = `0${runway.designation}`; - } else { - selectedRunwayOutput = runway.designation; - } - } else if (runway.designation.length === 2) { - selectedRunwayOutput = runway.designation; - } else { - selectedRunwayOutput = `0${runway.designation}`; - } + // const selectedRunwayMod = runway.designation.slice(-1); + // let selectedRunwayOutput; + // if (selectedRunwayMod === 'L' || selectedRunwayMod === 'C' || selectedRunwayMod === 'R') { + // if (runway.designation.length === 2) { + // selectedRunwayOutput = `0${runway.designation}`; + // } else { + // selectedRunwayOutput = runway.designation; + // } + // } else if (runway.designation.length === 2) { + // selectedRunwayOutput = runway.designation; + // } else { + // selectedRunwayOutput = `0${runway.designation}`; + // } // When adding approach, edit destination waypoint this.destinationAirfield.infos.coordinates = runway.beginningCoordinates; @@ -1186,7 +1184,9 @@ export class ManagedFlightPlan { if (approachIndex >= 0) { const lastLeg = approach.finalLegs[approach.finalLegs.length - 1]; if (lastLeg.type === LegType.CF) { - const magCourse = lastLeg.trueDegrees ? A32NX_Util.trueToMagnetic(lastLeg.course, Facilities.getMagVar(runway.beginningCoordinates.lat, runway.beginningCoordinates.long)) : lastLeg.course; + const magCourse = lastLeg.trueDegrees + ? A32NX_Util.trueToMagnetic(lastLeg.course, Facilities.getMagVar(runway.beginningCoordinates.lat, runway.beginningCoordinates.long)) + : lastLeg.course; this.destinationAirfield.additionalData.annotation = `C${magCourse.toFixed(0).padStart(3, '0')}°`; } else { this.destinationAirfield.additionalData.annotation = approachName; @@ -1233,26 +1233,26 @@ export class ManagedFlightPlan { private static isXfLeg(leg: WayPoint): boolean { switch (leg?.additionalData?.legType) { - case LegType.CF: - case LegType.DF: - case LegType.IF: - case LegType.RF: - case LegType.TF: - return true; - default: - return false; + case LegType.CF: + case LegType.DF: + case LegType.IF: + case LegType.RF: + case LegType.TF: + return true; + default: + return false; } } private static isFxLeg(leg: WayPoint): boolean { switch (leg?.additionalData?.legType) { - case LegType.FA: - case LegType.FC: - case LegType.FD: - case LegType.FM: - return true; - default: - return false; + case LegType.FA: + case LegType.FC: + case LegType.FD: + case LegType.FM: + return true; + default: + return false; } } @@ -1262,21 +1262,25 @@ export class ManagedFlightPlan { private static climbConstraint(leg: WayPoint): number { switch (leg.legAltitudeDescription) { - case AltitudeDescriptor.At: - case AltitudeDescriptor.AtOrBelow: - return leg.legAltitude1; - case AltitudeDescriptor.Between: - return leg.legAltitude2; + case AltitudeDescriptor.At: + case AltitudeDescriptor.AtOrBelow: + return leg.legAltitude1; + case AltitudeDescriptor.Between: + return leg.legAltitude2; + default: + break; } return Infinity; } private static descentConstraint(leg: WayPoint): number { switch (leg.legAltitudeDescription) { - case AltitudeDescriptor.At: - case AltitudeDescriptor.AtOrAbove: - case AltitudeDescriptor.Between: - return leg.legAltitude1; + case AltitudeDescriptor.At: + case AltitudeDescriptor.AtOrAbove: + case AltitudeDescriptor.Between: + return leg.legAltitude1; + default: + break; } return -Infinity; } @@ -1326,7 +1330,7 @@ export class ManagedFlightPlan { legAltitude1, legAltitude2, speedConstraint: Number.isFinite(speed) ? speed : 0, - } + }; } /** @@ -1536,8 +1540,7 @@ export class ManagedFlightPlan { default: } } else if (ManagedFlightPlan.isXfLeg(a) && ManagedFlightPlan.isXfLeg(b) - || ManagedFlightPlan.isFxLeg(a) && ManagedFlightPlan.isFxLeg(b)) - { + || ManagedFlightPlan.isFxLeg(a) && ManagedFlightPlan.isFxLeg(b)) { return a.icao === b.icao; } @@ -1595,6 +1598,7 @@ export class ManagedFlightPlan { return wp.legAltitude1; } } + return undefined; } get destinationIndex(): number { diff --git a/src/fmgc/src/flightplanning/RawDataMapper.ts b/src/fmgc/src/flightplanning/RawDataMapper.ts index 6a260d65777..3627adc4fa2 100644 --- a/src/fmgc/src/flightplanning/RawDataMapper.ts +++ b/src/fmgc/src/flightplanning/RawDataMapper.ts @@ -53,16 +53,28 @@ export class RawDataMapper { info.approaches = facility.approaches; info.approaches.forEach((approach) => approach.name = normaliseApproachName(approach.name)); - info.approaches.forEach((approach) => approach.transitions.forEach((trans) => trans.name.trim().length === 0 && (trans.name = WayPoint.formatIdentFromIcao(trans.legs[0].fixIcao)))); + info.approaches.forEach( + (approach) => approach.transitions.forEach( + (trans) => trans.name.trim().length === 0 && (trans.name = WayPoint.formatIdentFromIcao(trans.legs[0].fixIcao)), + ), + ); info.approaches.forEach((approach) => approach.runway = approach.runway.trim()); info.departures = facility.departures; info.departures.forEach((departure) => departure.runwayTransitions.forEach((trans) => trans.name = RawDataMapper.generateRunwayTransitionName(trans))); - info.departures.forEach((departure) => departure.enRouteTransitions.forEach((trans) => trans.name.trim().length === 0 && (trans.name = RawDataMapper.generateDepartureEnRouteTransitionName(trans)))); + info.departures.forEach( + (departure) => departure.enRouteTransitions.forEach( + (trans) => trans.name.trim().length === 0 && (trans.name = RawDataMapper.generateDepartureEnRouteTransitionName(trans)), + ), + ); info.arrivals = facility.arrivals; info.arrivals.forEach((arrival) => arrival.runwayTransitions.forEach((trans) => trans.name = RawDataMapper.generateRunwayTransitionName(trans))); - info.arrivals.forEach((arrival) => arrival.enRouteTransitions.forEach((trans) => trans.name.trim().length === 0 && (trans.name = RawDataMapper.generateArrivalTransitionName(trans)))); + info.arrivals.forEach( + (arrival) => arrival.enRouteTransitions.forEach( + (trans) => trans.name.trim().length === 0 && (trans.name = RawDataMapper.generateArrivalTransitionName(trans)), + ), + ); info.runways = facility.runways; @@ -143,6 +155,8 @@ export class RawDataMapper { case 3: name += 'C'; break; + default: + break; } return name;