From 4e39c35b4876dc0c4c45d7f7cbb84d0015d555fb Mon Sep 17 00:00:00 2001 From: Michael Corcoran Date: Wed, 7 Dec 2022 21:52:39 +1300 Subject: [PATCH] feat(nd): true ref for navaids --- .../src/ND/elements/RadioNavInfo.tsx | 64 +++++++++++++------ .../src/ND/elements/RadioNeedles.tsx | 30 +++++---- src/instruments/src/ND/index.tsx | 14 +++- src/instruments/src/ND/pages/ArcMode.tsx | 14 ++-- src/instruments/src/ND/pages/RoseMode.tsx | 14 ++-- 5 files changed, 82 insertions(+), 54 deletions(-) diff --git a/src/instruments/src/ND/elements/RadioNavInfo.tsx b/src/instruments/src/ND/elements/RadioNavInfo.tsx index a1cb64f9a05..7a46d465a73 100644 --- a/src/instruments/src/ND/elements/RadioNavInfo.tsx +++ b/src/instruments/src/ND/elements/RadioNavInfo.tsx @@ -1,7 +1,7 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { useSimVar } from '@instruments/common/simVars'; import { TuningMode } from '@fmgc/radionav'; -import { EfisSide } from '@shared/NavigationDisplay'; +import { EfisSide, Mode } from '@shared/NavigationDisplay'; export enum NavAidMode { Off = 0, @@ -9,9 +9,12 @@ export enum NavAidMode { VOR, } -// TODO true ref - -export type RadioNavInfoProps = { index: 1 | 2, side: EfisSide } +export type RadioNavInfoProps = { + index: 1 | 2, + side: EfisSide, + trueRef: boolean, + mode: Mode, +} const TuningModeIndicator: React.FC<{ index: 1 | 2, frequency: number }> = ({ index, frequency }) => { const [tuningMode] = useSimVar(`L:A32NX_FMGC_RADIONAV_${index}_TUNING_MODE`, 'enum'); @@ -23,12 +26,28 @@ const TuningModeIndicator: React.FC<{ index: 1 | 2, frequency: number }> = ({ in ); }; -const VorInfo: React.FC<{index: 1 | 2}> = ({ index }) => { +const VorInfo: React.FC<{index: 1 | 2, trueRef: boolean, mode: Mode }> = ({ index, trueRef, mode }) => { const [vorIdent] = useSimVar(`NAV IDENT:${index}`, 'string'); const [vorFrequency] = useSimVar(`NAV ACTIVE FREQUENCY:${index}`, 'megahertz'); const [vorHasDme] = useSimVar(`NAV HAS DME:${index}`, 'bool'); const [dmeDistance] = useSimVar(`NAV DME:${index}`, 'nautical miles'); const [vorAvailable] = useSimVar(`NAV HAS NAV:${index}`, 'boolean'); + const [stationDeclination] = useSimVar(`NAV MAGVAR:${index}`, 'degrees'); + const [stationLocation] = useSimVar(`NAV VOR LATLONALT:${index}`, 'latlonalt'); + const [stationRefTrue, setStationRefTrue] = useState(false); + const [corrected, setCorrected] = useState(false); + const [magWarning, setMagWarning] = useState(false); + const [trueWarning, setTrueWarning] = useState(false); + + useEffect(() => { + setStationRefTrue(stationLocation.lat > 75 && stationDeclination < Number.EPSILON); + }, [stationDeclination, stationLocation.lat]); + + useEffect(() => { + setCorrected(vorAvailable && !!(trueRef) !== stationRefTrue && mode !== Mode.ROSE_VOR && mode !== Mode.ROSE_ILS); + setMagWarning(vorAvailable && !!(trueRef) && !stationRefTrue && (mode === Mode.ROSE_VOR || mode === Mode.ROSE_ILS)); + setTrueWarning(vorAvailable && !(trueRef) && stationRefTrue && (mode === Mode.ROSE_VOR || mode === Mode.ROSE_ILS)); + }, [trueRef, stationRefTrue, mode, vorAvailable]); const x = index === 1 ? 37 : 668; @@ -60,21 +79,24 @@ const VorInfo: React.FC<{index: 1 | 2}> = ({ index }) => { return ( - {(vorAvailable && ( - - ))} + VOR {index} {(vorAvailable || vorHasDme) && vorFrequency > 1 && ( - {vorIdent} + <> + {vorIdent} + CORR + MAG + TRUE + )} {!(vorAvailable || vorHasDme) && vorFrequency > 1 && ( {freqText} @@ -122,13 +144,13 @@ const AdfInfo: React.FC<{index: 1 | 2}> = ({ index }) => { ); }; -export const RadioNavInfo: React.FC = ({ index, side }) => { - const [mode] = useSimVar(`L:A32NX_EFIS_${side}_NAVAID_${index}_MODE`, 'enum'); +export const RadioNavInfo: React.FC = ({ index, side, trueRef, mode }) => { + const [navaidMode] = useSimVar(`L:A32NX_EFIS_${side}_NAVAID_${index}_MODE`, 'enum'); - if (mode === NavAidMode.VOR) { - return ; + if (navaidMode === NavAidMode.VOR) { + return ; } - if (mode === NavAidMode.ADF) { + if (navaidMode === NavAidMode.ADF) { return ; } return <>; diff --git a/src/instruments/src/ND/elements/RadioNeedles.tsx b/src/instruments/src/ND/elements/RadioNeedles.tsx index 201ae0b4972..2bb57d303c1 100644 --- a/src/instruments/src/ND/elements/RadioNeedles.tsx +++ b/src/instruments/src/ND/elements/RadioNeedles.tsx @@ -1,9 +1,9 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { useSimVar } from '@instruments/common/simVars'; import { Mode, EfisSide } from '@shared/NavigationDisplay'; import { NavAidMode } from './RadioNavInfo'; -type RadioNavPointerProps = { index: 1 | 2, side: EfisSide, displayMode: Mode, centreHeight: number }; +type RadioNavPointerProps = { index: 1 | 2, side: EfisSide, displayMode: Mode, centreHeight: number, trueRef: boolean }; const AdfNeedle: React.FC> = ({ index, displayMode, centreHeight }) => { const [relativeBearing] = useSimVar(`ADF RADIAL:${index}`, 'degrees'); @@ -36,20 +36,28 @@ const AdfNeedle: React.FC> = ({ index, displa ); }; -const VorNeedle: React.FC> = ({ index, displayMode, centreHeight }) => { +const VorNeedle: React.FC> = ({ index, displayMode, centreHeight, trueRef }) => { const [relativeBearing] = useSimVar(`NAV RELATIVE BEARING TO STATION:${index}`, 'degrees'); const [available] = useSimVar(`NAV HAS NAV:${index}`, 'number'); + const [isLoc] = useSimVar(`NAV HAS LOCALIZER:${index}`, 'number'); + const [stationDeclination] = useSimVar(`NAV MAGVAR:${index}`, 'degrees'); + const [stationLocation] = useSimVar(`NAV VOR LATLONALT:${index}`, 'latlonalt'); + const [stationRefTrue, setStationRefTrue] = useState(false); + + useEffect(() => { + setStationRefTrue(stationLocation.lat > 75 && stationDeclination < Number.EPSILON); + }, [stationDeclination, stationLocation.lat]); let paths: Array; @@ -73,30 +81,30 @@ const VorNeedle: React.FC> = ({ index, displa return null; } - return available && ( + return available && !isLoc && ( ); }; -export const RadioNeedle: React.FC = ({ index, side, displayMode, centreHeight }) => { +export const RadioNeedle: React.FC = ({ index, side, displayMode, centreHeight, trueRef }) => { const [mode] = useSimVar(`L:A32NX_EFIS_${side}_NAVAID_${index}_MODE`, 'enum'); switch (mode) { case NavAidMode.ADF: - return ; + return ; case NavAidMode.VOR: - return ; + return ; case NavAidMode.Off: default: return null; diff --git a/src/instruments/src/ND/index.tsx b/src/instruments/src/ND/index.tsx index 0bbd9e46c14..8889ac467fd 100644 --- a/src/instruments/src/ND/index.tsx +++ b/src/instruments/src/ND/index.tsx @@ -98,6 +98,14 @@ const NavigationDisplay: React.FC = () => { } }, [])); + const irMaint = useArinc429Var('L:A32NX_ADIRS_IR_1_MAINT_WORD'); + const [trueRefPb] = useSimVar('L:A32NX_PUSH_TRUE_REF', 'bool'); + const [trueRef, setTrueRef] = useState(false); + + useEffect(() => { + setTrueRef((irMaint.getBitValueOr(15, false) || trueRefPb) && !irMaint.getBitValueOr(2, false)); + }, [irMaint.value, trueRefPb]); + return ( { side={side} ppos={ppos} mapHidden={modeChangeShown || rangeChangeShown} + trueRef={trueRef} /> )} {(modeIndex === Mode.ROSE_ILS || modeIndex === Mode.ROSE_VOR || modeIndex === Mode.ROSE_NAV) @@ -143,6 +152,7 @@ const NavigationDisplay: React.FC = () => { ppos={ppos} mode={modeIndex} mapHidden={modeChangeShown || rangeChangeShown} + trueRef={trueRef} /> )} @@ -151,8 +161,8 @@ const NavigationDisplay: React.FC = () => { {(adirsAlign && modeIndex !== Mode.PLAN) && ( <> - - + + )} diff --git a/src/instruments/src/ND/pages/ArcMode.tsx b/src/instruments/src/ND/pages/ArcMode.tsx index 25041deeeb4..9bce9db9658 100644 --- a/src/instruments/src/ND/pages/ArcMode.tsx +++ b/src/instruments/src/ND/pages/ArcMode.tsx @@ -22,9 +22,10 @@ export interface ArcModeProps { side: EfisSide, ppos: LatLongData, mapHidden: boolean, + trueRef: boolean, } -export const ArcMode: React.FC = ({ symbols, adirsAlign, rangeSetting, side, ppos, mapHidden }) => { +export const ArcMode: React.FC = ({ symbols, adirsAlign, rangeSetting, side, ppos, mapHidden, trueRef }) => { // TODO arinc var selector const magHeading = useArinc429Var('L:A32NX_ADIRS_IR_1_HEADING'); const magTrack = useArinc429Var('L:A32NX_ADIRS_IR_1_TRACK'); @@ -36,9 +37,6 @@ export const ArcMode: React.FC = ({ symbols, adirsAlign, rangeSett const [lsDisplayed] = useSimVar(`L:BTN_LS_${side === 'L' ? 1 : 2}_FILTER_ACTIVE`, 'bool'); // TODO rename simvar const [fmaLatMode] = useSimVar('L:A32NX_FMA_LATERAL_MODE', 'enum', 200); const [armedLateralBitmask] = useSimVar('L:A32NX_FMA_LATERAL_ARMED', 'enum', 200); - const irMaint = useArinc429Var('L:A32NX_ADIRS_IR_1_MAINT_WORD'); - const [trueRefPb] = useSimVar('L:A32NX_PUSH_TRUE_REF', 'bool'); - const [trueRef, setTrueRef] = useState(false); const heading = Number(MathUtils.fastToFixed((trueRef ? trueHeading.value : magHeading.value), 2)); const track = Number(MathUtils.fastToFixed((trueRef ? trueTrack.value : magTrack.value), 2)); @@ -54,10 +52,6 @@ export const ArcMode: React.FC = ({ symbols, adirsAlign, rangeSett mapParams.compute(ppos, rangeSetting, 492, trueHeading.value); }, [ppos.lat, ppos.long, trueHeading.value, rangeSetting].map((n) => MathUtils.fastToFixed(n, 6))); - useEffect(() => { - setTrueRef((irMaint.getBitValueOr(15, false) || trueRefPb) && !irMaint.getBitValueOr(2, false)); - }, [irMaint.value, trueRefPb]); - if (adirsAlign) { return ( <> @@ -87,8 +81,8 @@ export const ArcMode: React.FC = ({ symbols, adirsAlign, rangeSett )} - - + + diff --git a/src/instruments/src/ND/pages/RoseMode.tsx b/src/instruments/src/ND/pages/RoseMode.tsx index e6b2f8558f3..00b6800328d 100644 --- a/src/instruments/src/ND/pages/RoseMode.tsx +++ b/src/instruments/src/ND/pages/RoseMode.tsx @@ -24,9 +24,10 @@ export interface RoseModeProps { side: EfisSide, ppos: LatLongData, mapHidden: boolean, + trueRef: boolean, } -export const RoseMode: FC = ({ symbols, adirsAlign, rangeSetting, mode, side, ppos, mapHidden }) => { +export const RoseMode: FC = ({ symbols, adirsAlign, rangeSetting, mode, side, ppos, mapHidden, trueRef }) => { const magHeading = useArinc429Var('L:A32NX_ADIRS_IR_1_HEADING'); const magTrack = useArinc429Var('L:A32NX_ADIRS_IR_1_TRACK'); const trueHeading = useArinc429Var('L:A32NX_ADIRS_IR_1_TRUE_HEADING'); @@ -37,9 +38,6 @@ export const RoseMode: FC = ({ symbols, adirsAlign, rangeSetting, const [lsDisplayed] = useSimVar(`L:BTN_LS_${side === 'L' ? 1 : 2}_FILTER_ACTIVE`, 'bool'); // TODO rename simvar const [fmaLatMode] = useSimVar('L:A32NX_FMA_LATERAL_MODE', 'enum', 200); const [armedLateralBitmask] = useSimVar('L:A32NX_FMA_LATERAL_ARMED', 'enum', 200); - const irMaint = useArinc429Var('L:A32NX_ADIRS_IR_1_MAINT_WORD'); - const [trueRefPb] = useSimVar('L:A32NX_PUSH_TRUE_REF', 'bool'); - const [trueRef, setTrueRef] = useState(false); const heading = Number(MathUtils.fastToFixed((trueRef ? trueHeading.value : magHeading.value), 2)); const track = Number(MathUtils.fastToFixed((trueRef ? trueTrack.value : magTrack.value), 2)); @@ -55,10 +53,6 @@ export const RoseMode: FC = ({ symbols, adirsAlign, rangeSetting, mapParams.compute(ppos, rangeSetting / 2, 250, trueHeading.value); }, [ppos.lat, ppos.long, trueHeading.value, rangeSetting].map((n) => MathUtils.fastToFixed(n, 6))); - useEffect(() => { - setTrueRef((irMaint.getBitValueOr(15, false) || trueRefPb) && !irMaint.getBitValueOr(2, false)); - }, [irMaint.value, trueRefPb]); - if (adirsAlign) { return ( <> @@ -88,8 +82,8 @@ export const RoseMode: FC = ({ symbols, adirsAlign, rangeSetting, )} )} - - + + { mode === Mode.ROSE_VOR && }