Skip to content

Commit

Permalink
feat: polar heading/track part 1 (#7633)
Browse files Browse the repository at this point in the history
* feat(adiru): polar heading/track

* feat(font): diamond for eis font

* feat(nd): true ref

Still work to be done around radio nav indications.

* feat(pfd): true ref

Still QFU dagger to be done (I think)

* fix(nd): rect vis

* fix(pfd): true flag flashes at slat extension

* feat(nd): true ref for navaids

* fix(nd): svg vis attr always gets me

* doc: changelog and pb simvar

* fix(nd): adjust to 320 ref

* fix(adiru): add new tests and fix old tests

* fix(ND): adjust true indications based on new refs

* fix(fcu): awful hack for AP in hdg/trk when changing true ref

* fix: review feedback

Co-authored-by: David Walschots <[email protected]>

* doc: simvars

Co-authored-by: David Walschots <[email protected]>
  • Loading branch information
tracernz and davidwalschots authored Jan 11, 2023
1 parent 010bd3e commit 82f9ad7
Show file tree
Hide file tree
Showing 41 changed files with 1,026 additions and 221 deletions.
2 changes: 2 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
1. [FMGC] Improved importing flight plans from MSFS World Map - @frankkopp (Frank Kopp)
1. [EFB] Added boarding time indication to Payload page - @ChristianLutzCL (Christian Lutz) @frankkopp (Frank Kopp)
1. [EFB] Show correct runway numbers in landing calculator's runway widget when heading is between 0-5 degrees - @2hwk (2Cas#1022)
1. [ADIRU/ND/PFD] Initial support for polar navigation - @tracernz (Mike)

## 0.9.0

1. [MODEL] Add Wheel Chocks and GSE Safety Cones - @bouveng (Johan Bouveng)
Expand Down
12 changes: 12 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@
"y:/external/src/": "${workspaceFolder}/src/",
"z:/external/src/": "${workspaceFolder}/src/",
}
},
{
"name": "Rust Test Debugger",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceFolder}/target/debug/",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true,
"preLaunchTask": "cargo test build",
}
]
}
13 changes: 13 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@
"kind": "build",
"isDefault": true
}
},
{
"label": "Build Rust Tests",
"type": "shell",
"command": "cargo test build",
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": false
}
}
]
}
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 38 additions & 2 deletions docs/a320-simvars.md
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,7 @@ In the variables below, {number} should be replaced with one item in the set: {
- 0 is CAPT, 1 is NORM, 2 is F/O

- A32NX_ADIRS_ADIRU_{number}_STATE
- Deprecated: use A32NX_ADIRS_IR_{number}_MAINT_WORD instead.
- Enum
- The Inertial Reference alignment state.
Description | Value
Expand All @@ -1505,6 +1506,7 @@ In the variables below, {number} should be replaced with one item in the set: {
Aligned | 2

- A32NX_ADIRS_REMAINING_IR_ALIGNMENT_TIME
- Deprecated: use A32NX_ADIRS_IR_{number}_MAINT_WORD instead.
- Seconds
- The remaining alignment duration. Zero seconds when the system is aligned or the system is not aligning.

Expand Down Expand Up @@ -1558,15 +1560,15 @@ In the variables below, {number} should be replaced with one item in the set: {

- A32NX_ADIRS_IR_{number}_HEADING
- Arinc429Word<Degrees>
- The inertial heading of the aircraft.
- The magnetic heading of the aircraft (true in polar region).

- A32NX_ADIRS_IR_{number}_TRUE_HEADING
- Arinc429Word<Degrees>
- The true inertial heading of the aircraft.

- A32NX_ADIRS_IR_{number}_TRACK
- Arinc429Word<Degrees>
- The inertial track of the aircraft.
- The magnetic track of the aircraft (true in polar region).

- A32NX_ADIRS_IR_{number}_TRUE_TRACK
- Arinc429Word<Degrees>
Expand Down Expand Up @@ -1652,10 +1654,44 @@ In the variables below, {number} should be replaced with one item in the set: {
- Arinc429Word<Degrees per second>
- The roll rate (φ^dot) of the aircraft

- A32NX_ADIRS_IR_{number}_MAINT_WORD
- Arinc429Word<flags>
- Indicates state of the IR
Bit | Meaning
--- | ---
0 | ALIGNMENT_NOT_READY
1 | REV_ATT_MODE
2 | NAV_MODE
3 | VALID_SET_HEADING
4 | ATTITUDE_INVALID
5 | DC_FAIL
6 | ON_DC
7 | ADR_FAULT
8 | IR_FAULT
9 | DC_FAIL_ON_DC
10 | ALIGN_FAULT
11 | NO_IRS_INITIAL
12 | EXCESS_MOTION_ERROR
13 | ADR_IR_FAULT
14 | EXTREME_LATITUDE
15,16,17 | ALIGN_7_10_MINUTES
16,17 | ALIGN_6_MINUTES
15,17 | ALIGN_5_MINUTES
16 | ALIGN_4_MINUTES
15,16 | ALIGN_3_MINUTES
16 | ALIGN_2_MINUTES
15 | ALIGN_1_MINUTES
18 | COMPUTED_LATITUDE_MISCOMPARE

- A32NX_ADIRS_USES_GPS_AS_PRIMARY
- Deprecated, this is an FM function, not ADIRU
- Bool
- Whether or not the GPS is used as the primary means of navigation/position determination.

- A32NX_PUSH_TRUE_REF
- Bool
- True reference pushbutton status

## Radio Receivers

- A32NX_RADIO_RECEIVER_USAGE_ENABLED
Expand Down
Binary file modified flybywire-aircraft-a320-neo/html_ui/Fonts/ECAMFontRegular.ttf
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ class A320_Neo_FCU_Heading extends A320_Neo_FCU_Component {
super(...arguments);
this.backToIdleTimeout = 45000;
this.inSelection = false;
this.trueRef = false;

this._rotaryEncoderCurrentSpeed = 1;
this._rotaryEncoderMaximumSpeed = 5;
Expand Down Expand Up @@ -574,11 +575,13 @@ class A320_Neo_FCU_Heading extends A320_Neo_FCU_Component {
}

getCurrentHeading() {
return ((Math.round(SimVar.GetSimVarValue("PLANE HEADING DEGREES MAGNETIC", "degree")) % 360) + 360) % 360;
const heading = SimVar.GetSimVarValue(this.trueRef ? "PLANE HEADING DEGREES TRUE" : "PLANE HEADING DEGREES MAGNETIC", "degree");
return ((Math.round(heading) % 360) + 360) % 360;
}

getCurrentTrack() {
return ((Math.round(SimVar.GetSimVarValue("GPS GROUND MAGNETIC TRACK", "degree")) % 360) + 360) % 360;
const track = SimVar.GetSimVarValue(this.trueRef ? "GPS GROUND TRUE TRACK" : "GPS GROUND MAGNETIC TRACK", "degree");
return ((Math.round(track) % 360) + 360) % 360;
}

onPush() {
Expand Down Expand Up @@ -621,15 +624,19 @@ class A320_Neo_FCU_Heading extends A320_Neo_FCU_Component {
const isManagedArmed = this.isManagedModeArmed(lateralArmed);
const showSelectedValue = (this.isSelectedValueActive || this.inSelection || this.isPreselectionModeActive);

const isHeadingSync = SimVar.GetSimVarValue("L:A32NX_FCU_HEADING_SYNC", "Number");
this.trueRef = SimVar.GetSimVarValue('L:A32NX_FMGC_TRUE_REF', 'boolean');

const isHeadingSync = SimVar.GetSimVarValue("L:A32NX_FCU_HEADING_SYNC", "Number") || SimVar.GetSimVarValue("L:A32NX_FM_HEADING_SYNC", "boolean");
if (!this.wasHeadingSync && isHeadingSync) {
console.log('Sync heading', this.selectedValue);
if (isTRKMode) {
this.selectedValue = this.getCurrentTrack();
} else {
this.selectedValue = this.getCurrentHeading();
}
this.isSelectedValueActive = true;
this.onRotate();
SimVar.SetSimVarValue("L:A32NX_FM_HEADING_SYNC", "boolean", false);
}
this.wasHeadingSync = isHeadingSync;

Expand Down Expand Up @@ -679,10 +686,19 @@ class A320_Neo_FCU_Heading extends A320_Neo_FCU_Component {
}
}
}

// ugly hack because the FG doesn't understand true heading
// FIXME teach the FG about true/mag
const correctedHeading = this.trueRef ? (_value - SimVar.GetSimVarValue('MAGVAR', 'degree')) % 360 : _value;

SimVar.SetSimVarValue("L:A320_FCU_SHOW_SELECTED_HEADING", "number", _showSelectedHeading == true ? 1 : 0);
if (_value !== this.currentValue) {
SimVar.SetSimVarValue("L:A32NX_AUTOPILOT_HEADING_SELECTED", "Degrees", _value);
Coherent.call("HEADING_BUG_SET", 1, Math.max(0, _value)).catch(console.error);
SimVar.SetSimVarValue("L:A32NX_FCU_HEADING_SELECTED", "Degrees", _value);
SimVar.SetSimVarValue("L:A32NX_AUTOPILOT_HEADING_SELECTED", "Degrees", correctedHeading);
Coherent.call("HEADING_BUG_SET", 1, Math.max(0, correctedHeading)).catch(console.error);
} else if (this.trueRef) {
SimVar.SetSimVarValue("L:A32NX_AUTOPILOT_HEADING_SELECTED", "Degrees", correctedHeading);
Coherent.call("HEADING_BUG_SET", 1, Math.max(0, correctedHeading)).catch(console.error);
}
this.isActive = _isActive;
this.isManagedActive = _isManagedActive;
Expand Down
28 changes: 28 additions & 0 deletions src/fmgc/src/components/FcuSync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Arinc429Word } from '@shared/arinc429';
import { LateralMode } from '@shared/autopilot';
import { FmgcComponent } from './FmgcComponent';

// Note the logic for this is different on A330/350/380

export class FcuSync implements FmgcComponent {
private trueRef = false;

// eslint-disable-next-line no-empty-function
init(): void {}

update(_deltaTime: number): void {
const irMaint = Arinc429Word.fromSimVarValue('L:A32NX_ADIRS_IR_1_MAINT_WORD');
const trueRefPb = SimVar.GetSimVarValue('L:A32NX_PUSH_TRUE_REF', 'bool');

const trueRef = (irMaint.getBitValueOr(15, false) || trueRefPb) && !irMaint.getBitValueOr(2, false);

if (trueRef !== this.trueRef) {
this.trueRef = trueRef;
SimVar.SetSimVarValue('L:A32NX_FMGC_TRUE_REF', 'boolean', trueRef);
const activeMode = SimVar.GetSimVarValue('L:A32NX_FMA_LATERAL_MODE', 'number');
if (activeMode === LateralMode.HDG || activeMode === LateralMode.TRACK) {
SimVar.SetSimVarValue('L:A32NX_FM_HEADING_SYNC', 'boolean', true);
}
}
}
}
2 changes: 2 additions & 0 deletions src/fmgc/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { FcuSync } from '@fmgc/components/FcuSync';
import { ReadySignal } from '@fmgc/components/ReadySignal';
import { FlightPlanManager } from '@fmgc/wtsdk';
import { EfisLabels } from './EfisLabels';
Expand All @@ -10,6 +11,7 @@ const components: FmgcComponent[] = [
fmsMessages,
new EfisLabels(),
new ReadySignal(),
new FcuSync(),
];

export function initComponents(baseInstrument: BaseInstrument, flightPlanManager: FlightPlanManager): void {
Expand Down
7 changes: 5 additions & 2 deletions src/fmgc/src/guidance/lnav/LnavDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,9 @@ export class LnavDriver implements GuidanceComponent {
private updateEfisData(activeLeg: Leg, gs: Knots) {
const termination = activeLeg instanceof XFLeg ? activeLeg.fix.infos.coordinates : activeLeg.getPathEndPoint();

const efisTrueBearing = termination ? Avionics.Utils.computeGreatCircleHeading(this.ppos, termination) : -1;
const efisBearing = termination ? A32NX_Util.trueToMagnetic(
Avionics.Utils.computeGreatCircleHeading(this.ppos, termination),
efisTrueBearing,
Facilities.getMagVar(this.ppos.lat, this.ppos.long),
) : -1;

Expand All @@ -423,10 +424,12 @@ export class LnavDriver implements GuidanceComponent {
// FIXME should be NCD if no FM position

SimVar.SetSimVarValue('L:A32NX_EFIS_L_TO_WPT_BEARING', 'Degrees', efisBearing);
SimVar.SetSimVarValue('L:A32NX_EFIS_L_TO_WPT_TRUE_BEARING', 'Degrees', efisTrueBearing);
SimVar.SetSimVarValue('L:A32NX_EFIS_L_TO_WPT_DISTANCE', 'Number', efisDistance);
SimVar.SetSimVarValue('L:A32NX_EFIS_L_TO_WPT_ETA', 'Seconds', efisEta);

SimVar.SetSimVarValue('L:A32NX_EFIS_R_TO_WPT_BEARING', 'Degrees', efisBearing);
SimVar.SetSimVarValue('L:A32NX_EFIS_R_TO_WPT_TRUE_BEARING', 'Degrees', efisTrueBearing);
SimVar.SetSimVarValue('L:A32NX_EFIS_R_TO_WPT_DISTANCE', 'Number', efisDistance);
SimVar.SetSimVarValue('L:A32NX_EFIS_R_TO_WPT_ETA', 'Seconds', efisEta);
}
Expand Down Expand Up @@ -481,7 +484,7 @@ export class LnavDriver implements GuidanceComponent {
if (lateralModel === LateralMode.NAV) {
// Set HDG (current heading)
SimVar.SetSimVarValue('H:A320_Neo_FCU_HDG_PULL', 'number', 0);
SimVar.SetSimVarValue('L:A32NX_AUTOPILOT_HEADING_SELECTED', 'number', Simplane.getHeadingMagnetic());
SimVar.SetSimVarValue('L:A32NX_FM_HEADING_SYNC', 'boolean', true);
reverted = true;
}

Expand Down
81 changes: 58 additions & 23 deletions src/fonts/ECAMFontRegular_Source.sfd
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ OS2Version: 4
OS2_WeightWidthSlopeOnly: 0
OS2_UseTypoMetrics: 1
CreationTime: 1630565342
ModificationTime: 1634010783
ModificationTime: 1670146205
PfmFamily: 17
TTFWeight: 400
TTFWidth: 5
Expand Down Expand Up @@ -89,8 +89,15 @@ NameList: AGL For New Fonts
DisplaySize: -48
AntiAlias: 1
FitToEm: 0
WinInfo: 0 29 12
BeginChars: 65538 382
WinInfo: 9541 29 12
Grid
-4096 3112.08334351 m 0
8192 3112.08334351 l 1024
Named: "top"
-4053.02087402 5324 m 0
-4053.02087402 -2868 l 1024
EndSplineSet
BeginChars: 65538 383

StartChar: .notdef
Encoding: 65536 -1 0
Expand Down Expand Up @@ -537,7 +544,7 @@ StartChar: period
Encoding: 46 46 11
Width: 2568
GlyphClass: 2
Flags: WO
Flags: W
LayerCount: 2
Fore
SplineSet
Expand Down Expand Up @@ -2497,24 +2504,24 @@ Flags: W
LayerCount: 2
Fore
SplineSet
120 2969 m 2,0,1
120 3028 120 3028 161.5 3070 c 128,-1,2
203 3112 203 3112 263 3112 c 2,3,-1
1949 3112 l 2,4,5
2008 3112 2008 3112 2050 3070.5 c 128,-1,6
2092 3029 2092 3029 2092 2969 c 2,7,-1
2092 144 l 2,8,9
2092 85 2092 85 2050 43 c 128,-1,10
2008 1 2008 1 1949 1 c 2,11,-1
263 1 l 2,12,13
204 1 204 1 162 43 c 128,-1,14
120 85 120 85 120 144 c 2,15,-1
120 2969 l 2,0,1
402 2829 m 1,16,-1
402 284 l 1,17,-1
1809 284 l 1,18,-1
1809 2829 l 1,19,-1
402 2829 l 1,16,-1
120 2969 m 6,0,1
120 3028 120 3028 161.5 3070 c 132,-1,2
203 3112 203 3112 263 3112 c 6,3,-1
1949 3112 l 6,4,5
2008 3112 2008 3112 2050 3070.5 c 132,-1,6
2092 3029 2092 3029 2092 2969 c 6,7,-1
2092 144 l 6,8,9
2092 85 2092 85 2050 43 c 132,-1,10
2008 1 2008 1 1949 1 c 6,11,-1
263 1 l 6,12,13
204 1 204 1 162 43 c 132,-1,14
120 85 120 85 120 144 c 6,15,-1
120 2969 l 6,0,1
402 2829 m 5,16,-1
402 284 l 5,17,-1
1809 284 l 5,18,-1
1809 2829 l 5,19,-1
402 2829 l 5,16,-1
EndSplineSet
Validated: 1
EndChar
Expand Down Expand Up @@ -2946,7 +2953,7 @@ EndChar
StartChar: at
Encoding: 64 64 98
Width: 2568
Flags: WO
Flags: W
LayerCount: 2
Fore
SplineSet
Expand Down Expand Up @@ -5521,5 +5528,33 @@ LayerCount: 2
Fore
Validated: 1
EndChar

StartChar: uni25C7
Encoding: 9671 9671 382
Width: 2568
Flags: WO
LayerCount: 2
Fore
SplineSet
1188.15136719 3063.99804688 m 2,0,1
1221.84960938 3112.5625 1221.84960938 3112.5625 1269.76855469 3113.11035156 c 0,2,3
1317.45019531 3113.72949219 1317.45019531 3113.72949219 1351.95898438 3063.99804688 c 2,4,-1
2317.62597656 1672.34667969 l 2,5,6
2351.64257812 1623.06738281 2351.64257812 1623.06738281 2351.70605469 1554.72460938 c 0,7,8
2351.64257812 1485.29980469 2351.64257812 1485.29980469 2317.62597656 1436.27734375 c 2,9,-1
1352.53222656 45.453125 l 2,10,11
1318.89257812 -3.001953125 1318.89257812 -3.001953125 1270.51660156 -3.0849609375 c 0,12,13
1222.34667969 -3.001953125 1222.34667969 -3.001953125 1188.72363281 45.453125 c 2,14,-1
223.056640625 1437.10449219 l 2,15,16
189.584960938 1485.33984375 189.584960938 1485.33984375 191.372070312 1560.03125 c 0,17,18
192.993164062 1630.0703125 192.993164062 1630.0703125 223.056640625 1673.17285156 c 2,19,-1
1188.15136719 3063.99804688 l 2,0,1
1269.48242188 2715.67285156 m 1,20,-1
464.759765625 1555.96386719 l 1,21,-1
1270.62792969 394.603515625 l 1,22,-1
2075.35058594 1554.31347656 l 1,23,-1
1269.48242188 2715.67285156 l 1,20,-1
EndSplineSet
EndChar
EndChars
EndSplineFont
Loading

0 comments on commit 82f9ad7

Please sign in to comment.