From bac01929b9412a24269efbf29a34f63235188308 Mon Sep 17 00:00:00 2001 From: Florian Gross <63071941+flogross89@users.noreply.github.com> Date: Fri, 17 Jan 2025 00:50:01 +0200 Subject: [PATCH 1/7] use FL300 as crossover altitude --- .../instruments/src/MFD/FMC/FmcAircraftInterface.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts b/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts index e2d1092e4d3..7231a81052e 100644 --- a/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts +++ b/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts @@ -1613,9 +1613,14 @@ export class FmcAircraftInterface { } getManagedTargets(v: number, m: number) { - const alt = ADIRS.getBaroCorrectedAltitude(); + // Use hardcoded crossover altitude of 30000ft const vM = SimVar.GetGameVarValue('FROM MACH TO KIAS', 'number', m); - return alt && alt.isNormalOperation() && alt.value > 20_000 && v > vM ? [vM, true] : [v, false]; + return FmcAircraftInterface.useManagedMach() ? [vM, true] : [v, false]; + } + + static useManagedMach(): boolean { + const alt = ADIRS.getBaroCorrectedAltitude(); + return alt !== undefined && alt.isNormalOperation() && alt.value > 30_000; } // TODO/VNAV: Speed constraint From 54d5734f56de7037b0082524fa5ba2fc65f15aa5 Mon Sep 17 00:00:00 2001 From: Florian Gross <63071941+flogross89@users.noreply.github.com> Date: Fri, 17 Jan 2025 06:45:53 +0200 Subject: [PATCH 2/7] fixes --- .../src/MFD/FMC/FmcAircraftInterface.ts | 32 ++++++----- .../systems/instruments/src/MFD/FMC/fmgc.ts | 15 ++++-- .../src/MFD/pages/FMS/MfdFmsPerf.tsx | 54 +++++++++++++------ .../instruments/src/MFD/shared/Adirs.ts | 4 ++ .../src/systems/shared/src/MathUtils.ts | 11 ++++ 5 files changed, 82 insertions(+), 34 deletions(-) diff --git a/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts b/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts index 7231a81052e..424c34f6b82 100644 --- a/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts +++ b/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0 import { ConsumerValue, EventBus, GameStateProvider, SimVarValueType, Subject, UnitType } from '@microsoft/msfs-sdk'; -import { Arinc429SignStatusMatrix, Arinc429Word, FmsOansData } from '@flybywiresim/fbw-sdk'; +import { Arinc429SignStatusMatrix, Arinc429Word, FmsOansData, MathUtils } from '@flybywiresim/fbw-sdk'; import { FlapConf } from '@fmgc/guidance/vnav/common'; import { FlightPlanService } from '@fmgc/index'; import { MmrRadioTuningStatus } from '@fmgc/navigation/NavaidTuner'; @@ -1170,17 +1170,16 @@ export class FmcAircraftInterface { this.fmgc.data.approachFlapRetractionSpeed.set(Math.ceil(approachSpeeds.f3)); this.speedVapp.set(Math.round(approachSpeeds.vapp)); - // Retrieve CAS and altitude from ADRs - const cas = this.fmc.navigation.getComputedAirspeed(); + // Retrieve altitude from ADRs const alt = this.fmc.navigation.getPressureAltitude(); - if (cas !== null && alt !== null) { - // Only update speeds if ADR data valid + if (alt !== null) { + // Only update speeds if ADR altitude data valid. const flapLever = SimVar.GetSimVarValue('L:A32NX_FLAPS_HANDLE_INDEX', 'Enum'); const speeds = new A380OperatingSpeeds( grossWeight, - cas, + this.fmc.navigation.getComputedAirspeed() ?? 0, // CAS is NCD for low speeds/standstill, leading to null here flapLever, this.flightPhase.get(), this.fmgc.getV2Speed(), @@ -1612,15 +1611,20 @@ export class FmcAircraftInterface { return SimVar.GetSimVarValue('AUTOPILOT ALTITUDE SLOT INDEX', 'number') === 2; } - getManagedTargets(v: number, m: number) { - // Use hardcoded crossover altitude of 30000ft - const vM = SimVar.GetGameVarValue('FROM MACH TO KIAS', 'number', m); - return FmcAircraftInterface.useManagedMach() ? [vM, true] : [v, false]; - } - - static useManagedMach(): boolean { + getManagedTargets(v: number, m: number): [number, boolean] { + const sat = ADIRS.getStaticAirTemperature(); const alt = ADIRS.getBaroCorrectedAltitude(); - return alt !== undefined && alt.isNormalOperation() && alt.value > 30_000; + + if (sat !== undefined && sat.isNormalOperation() && alt !== undefined && alt.isNormalOperation()) { + const vM = MathUtils.convertMachToKCas( + m, + MathUtils.convertCtoK(sat.value), + SimVar.GetSimVarValue('AMBIENT PRESSURE', 'millibar'), + ); + return alt.value > 20_000 && v > vM ? [vM, true] : [v, false]; + } else { + return [v, false]; + } } // TODO/VNAV: Speed constraint diff --git a/fbw-a380x/src/systems/instruments/src/MFD/FMC/fmgc.ts b/fbw-a380x/src/systems/instruments/src/MFD/FMC/fmgc.ts index 72d56a99eb2..1207cbaa2d7 100644 --- a/fbw-a380x/src/systems/instruments/src/MFD/FMC/fmgc.ts +++ b/fbw-a380x/src/systems/instruments/src/MFD/FMC/fmgc.ts @@ -53,6 +53,10 @@ export enum ClimbDerated { * Temporary place for data which is found nowhere else. Not associated to flight plans right now, which should be the case for some of these values */ export class FmgcData { + static fmcFormatSpeed(sub: Subscribable) { + return sub.map((it) => (it !== null ? it.toFixed(0) : '---')); + } + public readonly cpnyFplnAvailable = Subject.create(false); public readonly cpnyFplnUplinkInProgress = Subject.create(false); @@ -217,11 +221,11 @@ export class FmgcData { public readonly takeoffFlapsSetting = Subject.create(FlapConf.CONF_1); - public readonly flapRetractionSpeed = Subject.create(141); + public readonly flapRetractionSpeed = Subject.create(null); - public readonly slatRetractionSpeed = Subject.create(159); + public readonly slatRetractionSpeed = Subject.create(null); - public readonly greenDotSpeed = Subject.create(190); + public readonly greenDotSpeed = Subject.create(null); public readonly approachSpeed = Subject.create(null); @@ -454,10 +458,11 @@ export class FmgcDataService implements Fmgc { return preSel; } - if (this.flightPlanService.has(FlightPlanIndex.Active)) { + // FIXME need to rework the cost index based speed calculations + /* if (this.flightPlanService.has(FlightPlanIndex.Active)) { const dCI = ((this.flightPlanService.active.performanceData.costIndex ?? 100) / 999) ** 2; return 290 * (1 - dCI) + 330 * dCI; - } + }*/ return 310; } diff --git a/fbw-a380x/src/systems/instruments/src/MFD/pages/FMS/MfdFmsPerf.tsx b/fbw-a380x/src/systems/instruments/src/MFD/pages/FMS/MfdFmsPerf.tsx index 7baa4383e7d..3b5ed636ac7 100644 --- a/fbw-a380x/src/systems/instruments/src/MFD/pages/FMS/MfdFmsPerf.tsx +++ b/fbw-a380x/src/systems/instruments/src/MFD/pages/FMS/MfdFmsPerf.tsx @@ -29,7 +29,7 @@ import { maxCertifiedAlt, Mmo, Vmo } from '@shared/PerformanceConstants'; import { ConfirmationDialog } from 'instruments/src/MFD/pages/common/ConfirmationDialog'; import { FmsPage } from 'instruments/src/MFD/pages/common/FmsPage'; import { FmgcFlightPhase } from '@shared/flightphase'; -import { TakeoffDerated, TakeoffPowerSetting } from 'instruments/src/MFD/FMC/fmgc'; +import { FmgcData, TakeoffDerated, TakeoffPowerSetting } from 'instruments/src/MFD/FMC/fmgc'; import { ConditionalComponent } from 'instruments/src/MFD/pages/common/ConditionalComponent'; import { MfdSimvars } from 'instruments/src/MFD/shared/MFDSimvarPublisher'; import { VerticalCheckpointReason } from '@fmgc/guidance/vnav/profile/NavGeometryProfile'; @@ -1055,7 +1055,9 @@ export class MfdFmsPerf extends FmsPage {
- {this.props.fmcService.master.fmgc.data.v1ToBeConfirmed} + + {FmgcData.fmcFormatSpeed(this.props.fmcService.master.fmgc.data.v1ToBeConfirmed)} + KT
@@ -1093,7 +1095,9 @@ export class MfdFmsPerf extends FmsPage {
F - {this.props.fmcService.master.fmgc.data.flapRetractionSpeed} + + {FmgcData.fmcFormatSpeed(this.props.fmcService.master.fmgc.data.flapRetractionSpeed)} + KT
@@ -1115,13 +1119,17 @@ export class MfdFmsPerf extends FmsPage {
- {this.props.fmcService.master.fmgc.data.vrToBeConfirmed} + + {FmgcData.fmcFormatSpeed(this.props.fmcService.master.fmgc.data.vrToBeConfirmed)} + KT
S - {this.props.fmcService.master.fmgc.data.slatRetractionSpeed} + + {FmgcData.fmcFormatSpeed(this.props.fmcService.master.fmgc.data.slatRetractionSpeed)} + KT
@@ -1143,7 +1151,9 @@ export class MfdFmsPerf extends FmsPage {
- {this.props.fmcService.master.fmgc.data.v2ToBeConfirmed} + + {FmgcData.fmcFormatSpeed(this.props.fmcService.master.fmgc.data.v2ToBeConfirmed)} + KT
@@ -1153,7 +1163,9 @@ export class MfdFmsPerf extends FmsPage { - {this.props.fmcService.master.fmgc.data.greenDotSpeed} + + {FmgcData.fmcFormatSpeed(this.props.fmcService.master.fmgc.data.greenDotSpeed)} + KT @@ -2557,26 +2569,30 @@ export class MfdFmsPerf extends FmsPage { - {this.props.fmcService.master.fmgc.data.approachGreenDotSpeed} + + {FmgcData.fmcFormatSpeed(this.props.fmcService.master.fmgc.data.approachGreenDotSpeed)} + KT
S - {this.props.fmcService.master.fmgc.data.approachSlatRetractionSpeed} + {FmgcData.fmcFormatSpeed(this.props.fmcService.master.fmgc.data.approachSlatRetractionSpeed)} KT
F - {this.props.fmcService.master.fmgc.data.approachFlapRetractionSpeed} + {FmgcData.fmcFormatSpeed(this.props.fmcService.master.fmgc.data.approachFlapRetractionSpeed)} KT
VREF - {this.props.fmcService.master.fmgc.data.approachVref} + + {FmgcData.fmcFormatSpeed(this.props.fmcService.master.fmgc.data.approachVref)} + KT
@@ -2594,7 +2610,9 @@ export class MfdFmsPerf extends FmsPage { />
VLS - {this.props.fmcService.master.fmgc.data.approachVls} + + {FmgcData.fmcFormatSpeed(this.props.fmcService.master.fmgc.data.approachVls)} + KT
@@ -2653,12 +2671,16 @@ export class MfdFmsPerf extends FmsPage {
F - {this.props.fmcService.master.fmgc.data.approachFlapRetractionSpeed} + + {FmgcData.fmcFormatSpeed(this.props.fmcService.master.fmgc.data.approachFlapRetractionSpeed)} + KT
S - {this.props.fmcService.master.fmgc.data.approachSlatRetractionSpeed} + + {FmgcData.fmcFormatSpeed(this.props.fmcService.master.fmgc.data.approachSlatRetractionSpeed)} + KT
@@ -2667,7 +2689,9 @@ export class MfdFmsPerf extends FmsPage { - {this.props.fmcService.master.fmgc.data.approachGreenDotSpeed} + + {FmgcData.fmcFormatSpeed(this.props.fmcService.master.fmgc.data.approachGreenDotSpeed)} + KT
diff --git a/fbw-a380x/src/systems/instruments/src/MFD/shared/Adirs.ts b/fbw-a380x/src/systems/instruments/src/MFD/shared/Adirs.ts index fe2a04b023a..1c265eebef2 100644 --- a/fbw-a380x/src/systems/instruments/src/MFD/shared/Adirs.ts +++ b/fbw-a380x/src/systems/instruments/src/MFD/shared/Adirs.ts @@ -60,6 +60,10 @@ export class ADIRS { return ADIRS.getFromAnyAdiru('ADR', 'ALTITUDE'); } + static getStaticAirTemperature() { + return ADIRS.getFromAnyAdiru('ADR', 'STATIC_AIR_TEMPERATURE'); + } + /** * * @param type IR or ADR diff --git a/fbw-common/src/systems/shared/src/MathUtils.ts b/fbw-common/src/systems/shared/src/MathUtils.ts index a835dee0608..3a39a1cd198 100644 --- a/fbw-common/src/systems/shared/src/MathUtils.ts +++ b/fbw-common/src/systems/shared/src/MathUtils.ts @@ -322,6 +322,17 @@ export class MathUtils { return MathUtils.convertTasToKCas(MathUtils.convertMachToKTas(mach, oat), oat, pressure); } + /** + * Convert Mach to Calibrated Air Speed + * @param kcas velocity true air speed + * @param oat Kelvin + * @param pressure current pressure hpa + * @returns Calibrated Air Speed + */ + public static convertKCasToMach(kcas: number, oat: number, pressure: number): number { + return MathUtils.convertKTASToMach(MathUtils.convertKCasToKTAS(kcas, oat, pressure), oat); + } + /** * Gets the horizontal distance between 2 points, given in lat/lon * @param pos0Lat {number} Position 0 lat From 4239ebb0a70c3467807fe7c52b95ac156fcbaff6 Mon Sep 17 00:00:00 2001 From: Florian Gross <63071941+flogross89@users.noreply.github.com> Date: Fri, 17 Jan 2025 07:17:41 +0200 Subject: [PATCH 3/7] review comments --- .github/CHANGELOG.md | 1 + .../instruments/src/MFD/FMC/FmcAircraftInterface.ts | 13 +++++++++---- .../src/systems/instruments/src/MFD/shared/Adirs.ts | 13 +++++++++++++ fbw-common/src/systems/shared/src/MathUtils.ts | 11 ----------- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index b396639427e..3d6431f986e 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -124,6 +124,7 @@ 1. [A380X/FCU] Add TRUE indication on FCU when TRUE North reference is selected on AFS CP - @heclak (Heclak) 1. [A380X/MFD] Add airport data page into the MFD (DATA > AIRPORT) - @bulenteroglu (senolitam) 1. [A380X/EFB] Adds PRIM/SEC/FCDC failures to EFB - @flogross89 (floridude) +1. [A380X/FMS] Use cruise mach above crossover altitude - @flogross89 (floridude) ## 0.12.0 diff --git a/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts b/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts index 424c34f6b82..7d1d9d2ea4a 100644 --- a/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts +++ b/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts @@ -1613,15 +1613,20 @@ export class FmcAircraftInterface { getManagedTargets(v: number, m: number): [number, boolean] { const sat = ADIRS.getStaticAirTemperature(); - const alt = ADIRS.getBaroCorrectedAltitude(); + const press = ADIRS.getCorrectedAverageStaticPressure(); - if (sat !== undefined && sat.isNormalOperation() && alt !== undefined && alt.isNormalOperation()) { + if ( + sat !== undefined && + (sat.isNormalOperation() || sat.isFunctionalTest()) && + press !== undefined && + (press.isNormalOperation() || press.isFunctionalTest()) + ) { const vM = MathUtils.convertMachToKCas( m, MathUtils.convertCtoK(sat.value), - SimVar.GetSimVarValue('AMBIENT PRESSURE', 'millibar'), + UnitType.HPA.convertTo(press.value, UnitType.MB), ); - return alt.value > 20_000 && v > vM ? [vM, true] : [v, false]; + return v > vM ? [vM, true] : [v, false]; } else { return [v, false]; } diff --git a/fbw-a380x/src/systems/instruments/src/MFD/shared/Adirs.ts b/fbw-a380x/src/systems/instruments/src/MFD/shared/Adirs.ts index 1c265eebef2..6f3dde15515 100644 --- a/fbw-a380x/src/systems/instruments/src/MFD/shared/Adirs.ts +++ b/fbw-a380x/src/systems/instruments/src/MFD/shared/Adirs.ts @@ -31,39 +31,52 @@ export class ADIRS { ); } + /** in degrees */ static getLatitude() { return ADIRS.getFromAnyAdiru('IR', 'LATITUDE'); } + /** in degrees */ static getLongitude() { return ADIRS.getFromAnyAdiru('IR', 'LONGITUDE'); } + /** in degrees */ static getTrueTrack() { return ADIRS.getFromAnyAdiru('IR', 'TRUE_TRACK'); } + /** in knots */ static getTrueAirspeed() { return ADIRS.getFromAnyAdiru('ADR', 'TRUE_AIRSPEED'); } + /** in knots */ static getCalibratedAirspeed() { return ADIRS.getFromAnyAdiru('ADR', 'COMPUTED_AIRSPEED'); } + /** in knots */ static getGroundSpeed() { return ADIRS.getFromAnyAdiru('IR', 'GROUND_SPEED'); } // FIXME there should be baro corrected altitude 1 (capt) and 2 (f/o) + /** in feet */ static getBaroCorrectedAltitude() { return ADIRS.getFromAnyAdiru('ADR', 'ALTITUDE'); } + /** in degrees celsius */ static getStaticAirTemperature() { return ADIRS.getFromAnyAdiru('ADR', 'STATIC_AIR_TEMPERATURE'); } + /** in hPa */ + static getCorrectedAverageStaticPressure() { + return ADIRS.getFromAnyAdiru('ADR', 'CORRECTED_AVERAGE_STATIC_PRESSURE'); + } + /** * * @param type IR or ADR diff --git a/fbw-common/src/systems/shared/src/MathUtils.ts b/fbw-common/src/systems/shared/src/MathUtils.ts index 3a39a1cd198..a835dee0608 100644 --- a/fbw-common/src/systems/shared/src/MathUtils.ts +++ b/fbw-common/src/systems/shared/src/MathUtils.ts @@ -322,17 +322,6 @@ export class MathUtils { return MathUtils.convertTasToKCas(MathUtils.convertMachToKTas(mach, oat), oat, pressure); } - /** - * Convert Mach to Calibrated Air Speed - * @param kcas velocity true air speed - * @param oat Kelvin - * @param pressure current pressure hpa - * @returns Calibrated Air Speed - */ - public static convertKCasToMach(kcas: number, oat: number, pressure: number): number { - return MathUtils.convertKTASToMach(MathUtils.convertKCasToKTAS(kcas, oat, pressure), oat); - } - /** * Gets the horizontal distance between 2 points, given in lat/lon * @param pos0Lat {number} Position 0 lat From 23605e2b36ee4300c1c9b736b91a8e7e475241a5 Mon Sep 17 00:00:00 2001 From: Michael Corcoran Date: Fri, 17 Jan 2025 18:29:10 +1300 Subject: [PATCH 4/7] fix(mathutils): remove machToKCas temperature dependency (cherry picked from commit 3f77cd546183db6a9d1ae779af412bb3ed1b7cf7) --- .../systems/shared/src/OperatingSpeeds.tsx | 19 ++----------------- .../src/systems/shared/src/MathUtils.spec.ts | 10 ++++++++++ .../src/systems/shared/src/MathUtils.ts | 11 +++++++---- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/fbw-a380x/src/systems/shared/src/OperatingSpeeds.tsx b/fbw-a380x/src/systems/shared/src/OperatingSpeeds.tsx index f5fcd90d7c3..c8fd7d26b9a 100644 --- a/fbw-a380x/src/systems/shared/src/OperatingSpeeds.tsx +++ b/fbw-a380x/src/systems/shared/src/OperatingSpeeds.tsx @@ -402,29 +402,14 @@ function getVfeNIdx(fi: number): number { } } -/** - * Convert degrees Celsius into Kelvin - * @param T degrees Celsius - * @returns degrees Kelvin - */ -function convertCtoK(T: number): number { - return T + 273.15; -} - /** * Get correct Vmax for Vmo and Mmo in knots * @returns Min(Vmo, Mmo) * @private */ function getVmo() { - return Math.min( - Vmo, - MathUtils.convertMachToKCas( - Mmo, - convertCtoK(Simplane.getAmbientTemperature()), - SimVar.GetSimVarValue('AMBIENT PRESSURE', 'millibar'), - ), - ); + // FIXME use ADR corrected average static pressure + return Math.min(Vmo, MathUtils.convertMachToKCas(Mmo, SimVar.GetSimVarValue('AMBIENT PRESSURE', 'millibar'))); } export class A380OperatingSpeeds { diff --git a/fbw-common/src/systems/shared/src/MathUtils.spec.ts b/fbw-common/src/systems/shared/src/MathUtils.spec.ts index 5ff140552f5..51600fc9239 100644 --- a/fbw-common/src/systems/shared/src/MathUtils.spec.ts +++ b/fbw-common/src/systems/shared/src/MathUtils.spec.ts @@ -143,4 +143,14 @@ describe('MathUtils.correctMsfsLocaliserError', () => { expect(MathUtils.correctMsfsLocaliserError(177.5)).toBeCloseTo(2.5); expect(MathUtils.correctMsfsLocaliserError(90.1)).toBeCloseTo(89.9); }); + + describe('MathUtils.convertMachToKCas', () => { + it('correctly converts mach to CAS', () => { + expect(MathUtils.convertMachToKCas(0, 1013.25)).toBeCloseTo(0); + expect(MathUtils.convertMachToKCas(0.84, 1013.25)).toBeCloseTo(555.634); + // FL350 = 238.423 hPa + expect(MathUtils.convertMachToKCas(0, 238.423)).toBeCloseTo(0); + expect(MathUtils.convertMachToKCas(0.84, 238.423)).toBeCloseTo(287.097); + }); + }); }); diff --git a/fbw-common/src/systems/shared/src/MathUtils.ts b/fbw-common/src/systems/shared/src/MathUtils.ts index a835dee0608..1ecf06db53a 100644 --- a/fbw-common/src/systems/shared/src/MathUtils.ts +++ b/fbw-common/src/systems/shared/src/MathUtils.ts @@ -289,7 +289,7 @@ export class MathUtils { return ( 1479.1 * Math.sqrt( - ((pressure / 1013) * ((1 + (1 / (oat / 288.15)) * (tas / 1479.1) ** 2) ** 3.5 - 1) + 1) ** (1 / 3.5) - 1, + ((pressure / 1013.25) * ((1 + (1 / (oat / 288.15)) * (tas / 1479.1) ** 2) ** 3.5 - 1) + 1) ** (1 / 3.5) - 1, ) ); } @@ -306,7 +306,7 @@ export class MathUtils { 1479.1 * Math.sqrt( (oat / 288.15) * - (((1 / (pressure / 1013)) * ((1 + 0.2 * (kcas / 661.4786) ** 2) ** 3.5 - 1) + 1) ** (1 / 3.5) - 1), + (((1 / (pressure / 1013.25)) * ((1 + 0.2 * (kcas / 661.4786) ** 2) ** 3.5 - 1) + 1) ** (1 / 3.5) - 1), ) ); } @@ -318,8 +318,11 @@ export class MathUtils { * @param pressure current pressure hpa * @returns Calibrated Air Speed */ - public static convertMachToKCas(mach: number, oat: number, pressure: number): number { - return MathUtils.convertTasToKCas(MathUtils.convertMachToKTas(mach, oat), oat, pressure); + public static convertMachToKCas(mach: number, pressure: number): number { + // Formula from Jet Transport Performance Methods 2009. + return ( + 1479.1 * Math.sqrt(Math.pow((pressure / 1013.25) * (Math.pow(0.2 * mach * mach + 1, 3.5) - 1) + 1, 1 / 3.5) - 1) + ); } /** From 93bcb9860b941c96611879c2a82c6847b7fe0bb5 Mon Sep 17 00:00:00 2001 From: Florian Gross <63071941+flogross89@users.noreply.github.com> Date: Fri, 17 Jan 2025 07:43:59 +0200 Subject: [PATCH 5/7] some updates --- .../systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts | 6 +----- fbw-a380x/src/systems/shared/src/OperatingSpeeds.tsx | 5 ++++- fbw-common/src/systems/shared/src/MathUtils.ts | 1 - 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts b/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts index 7d1d9d2ea4a..d2e09fa33e5 100644 --- a/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts +++ b/fbw-a380x/src/systems/instruments/src/MFD/FMC/FmcAircraftInterface.ts @@ -1621,11 +1621,7 @@ export class FmcAircraftInterface { press !== undefined && (press.isNormalOperation() || press.isFunctionalTest()) ) { - const vM = MathUtils.convertMachToKCas( - m, - MathUtils.convertCtoK(sat.value), - UnitType.HPA.convertTo(press.value, UnitType.MB), - ); + const vM = MathUtils.convertMachToKCas(m, press.value); return v > vM ? [vM, true] : [v, false]; } else { return [v, false]; diff --git a/fbw-a380x/src/systems/shared/src/OperatingSpeeds.tsx b/fbw-a380x/src/systems/shared/src/OperatingSpeeds.tsx index c8fd7d26b9a..fac565dd198 100644 --- a/fbw-a380x/src/systems/shared/src/OperatingSpeeds.tsx +++ b/fbw-a380x/src/systems/shared/src/OperatingSpeeds.tsx @@ -11,6 +11,7 @@ import { MathUtils } from '@flybywiresim/fbw-sdk'; import { Mmo, VfeF1, VfeF1F, VfeF2, VfeF3, VfeFF, Vmcl, Vmo } from '@shared/PerformanceConstants'; import { FmgcFlightPhase } from '@shared/flightphase'; import { LerpLookupTable } from '@microsoft/msfs-sdk'; +import { ADIRS } from 'instruments/src/MFD/shared/Adirs'; export enum ApproachConf { CONF_1 = 1, @@ -409,7 +410,9 @@ function getVfeNIdx(fi: number): number { */ function getVmo() { // FIXME use ADR corrected average static pressure - return Math.min(Vmo, MathUtils.convertMachToKCas(Mmo, SimVar.GetSimVarValue('AMBIENT PRESSURE', 'millibar'))); + const adrPressure = ADIRS.getCorrectedAverageStaticPressure(); + const ambientPressure = adrPressure !== undefined ? adrPressure.valueOr(1013.25) : 1013.25; + return Math.min(Vmo, MathUtils.convertMachToKCas(Mmo, ambientPressure)); } export class A380OperatingSpeeds { diff --git a/fbw-common/src/systems/shared/src/MathUtils.ts b/fbw-common/src/systems/shared/src/MathUtils.ts index 1ecf06db53a..091fbbc14be 100644 --- a/fbw-common/src/systems/shared/src/MathUtils.ts +++ b/fbw-common/src/systems/shared/src/MathUtils.ts @@ -314,7 +314,6 @@ export class MathUtils { /** * Convert Mach to Calibrated Air Speed * @param mach Mach - * @param oat Kelvin * @param pressure current pressure hpa * @returns Calibrated Air Speed */ From 21f931331569554d09f9a80b7748186acdb15dca Mon Sep 17 00:00:00 2001 From: Florian Gross <63071941+flogross89@users.noreply.github.com> Date: Fri, 17 Jan 2025 08:15:28 +0200 Subject: [PATCH 6/7] remove comment --- fbw-a380x/src/systems/shared/src/OperatingSpeeds.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/fbw-a380x/src/systems/shared/src/OperatingSpeeds.tsx b/fbw-a380x/src/systems/shared/src/OperatingSpeeds.tsx index fac565dd198..373c06c8af5 100644 --- a/fbw-a380x/src/systems/shared/src/OperatingSpeeds.tsx +++ b/fbw-a380x/src/systems/shared/src/OperatingSpeeds.tsx @@ -409,7 +409,6 @@ function getVfeNIdx(fi: number): number { * @private */ function getVmo() { - // FIXME use ADR corrected average static pressure const adrPressure = ADIRS.getCorrectedAverageStaticPressure(); const ambientPressure = adrPressure !== undefined ? adrPressure.valueOr(1013.25) : 1013.25; return Math.min(Vmo, MathUtils.convertMachToKCas(Mmo, ambientPressure)); From 3e456f726fff57ef0971dee4616f1c2caf2dc471 Mon Sep 17 00:00:00 2001 From: floridude <63071941+flogross89@users.noreply.github.com> Date: Fri, 17 Jan 2025 22:43:53 +0200 Subject: [PATCH 7/7] Update CHANGELOG.md --- .github/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index 616c9e21128..f47d4467739 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -127,6 +127,7 @@ 1. [A380X/PFD] Fix precision of pitch trim indicator - @flogross89 (floridude) 1. [A380X/FMS] Use cruise mach above crossover altitude - @flogross89 (floridude) + ## 0.12.0 1. [EFB/ATSU] Added NOAA (aviationweather.gov) as a METAR source - @tracernz (Mike)