Skip to content

Commit

Permalink
fix(fcu): awful hack for AP in hdg/trk when changing true ref
Browse files Browse the repository at this point in the history
  • Loading branch information
tracernz committed Dec 21, 2022
1 parent e745f46 commit 22212d6
Show file tree
Hide file tree
Showing 11 changed files with 60 additions and 17 deletions.
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
2 changes: 1 addition & 1 deletion src/fmgc/src/guidance/lnav/LnavDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -484,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
2 changes: 1 addition & 1 deletion src/instruments/src/ND/pages/ArcMode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const ArcMode: React.FC<ArcModeProps> = ({ symbols, adirsAlign, rangeSett
const trueHeading = useArinc429Var('L:A32NX_ADIRS_IR_1_TRUE_HEADING');
const trueTrack = useArinc429Var('L:A32NX_ADIRS_IR_1_TRUE_TRACK');
const [tcasMode] = useSimVar('L:A32NX_SWITCH_TCAS_Position', 'number');
const [selectedHeading] = useSimVar('L:A32NX_AUTOPILOT_HEADING_SELECTED', 'degrees');
const [selectedHeading] = useSimVar('L:A32NX_FCU_HEADING_SELECTED', 'degrees');
const [lsCourse] = useSimVar('L:A32NX_FM_LS_COURSE', 'number');
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);
Expand Down
2 changes: 1 addition & 1 deletion src/instruments/src/ND/pages/RoseMode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const RoseMode: FC<RoseModeProps> = ({ symbols, adirsAlign, rangeSetting,
const trueHeading = useArinc429Var('L:A32NX_ADIRS_IR_1_TRUE_HEADING');
const trueTrack = useArinc429Var('L:A32NX_ADIRS_IR_1_TRUE_TRACK');
const [tcasMode] = useSimVar('L:A32NX_SWITCH_TCAS_Position', 'number');
const [selectedHeading] = useSimVar('L:A32NX_AUTOPILOT_HEADING_SELECTED', 'degrees');
const [selectedHeading] = useSimVar('L:A32NX_FCU_HEADING_SELECTED', 'degrees');
const [lsCourse] = useSimVar('L:A32NX_FM_LS_COURSE', 'number');
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);
Expand Down
3 changes: 1 addition & 2 deletions src/instruments/src/PFD/AttitudeIndicatorHorizon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
import { PFDSimvars } from './shared/PFDSimvarPublisher';
import { Arinc429Values } from './shared/ArincValueProvider';
import { HorizontalTape } from './HorizontalTape';
import { SimplaneValues } from './shared/SimplaneValueProvider';
import { getDisplayIndex } from './PFD';

const DisplayRange = 35;
Expand Down Expand Up @@ -45,7 +44,7 @@ class HeadingBug extends DisplayComponent<{bus: EventBus, isCaptainSide: boolean
onAfterRender(node: VNode): void {
super.onAfterRender(node);

const sub = this.props.bus.getSubscriber<DisplayManagementComputerEvents & PFDSimvars & SimplaneValues & Arinc429Values>();
const sub = this.props.bus.getSubscriber<DisplayManagementComputerEvents & PFDSimvars & Arinc429Values>();

sub.on('selectedHeading').whenChanged().handle((s) => {
this.selectedHeading = s;
Expand Down
5 changes: 1 addition & 4 deletions src/instruments/src/PFD/HeadingIndicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { HorizontalTape } from './HorizontalTape';
import { getSmallestAngle } from './PFDUtils';
import { PFDSimvars } from './shared/PFDSimvarPublisher';
import { Arinc429Values } from './shared/ArincValueProvider';
import { SimplaneValues } from './shared/SimplaneValueProvider';
import { getDisplayIndex } from './PFD';

const DisplayRange = 24;
Expand Down Expand Up @@ -130,9 +129,7 @@ class SelectedHeading extends DisplayComponent<SelectedHeadingProps> {

const sub = this.props.bus.getSubscriber<PFDSimvars>();

const spsub = this.props.bus.getSubscriber<SimplaneValues>();

spsub.on('selectedHeading').whenChanged().handle((h) => {
sub.on('selectedHeading').whenChanged().handle((h) => {
if (this.showSelectedHeading === 1) {
this.selectedHeading = h;
this.handleDelta(this.props.heading.get(), this.selectedHeading);
Expand Down
1 change: 1 addition & 0 deletions src/instruments/src/PFD/instrument.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ class A32NX_PFD extends BaseInstrument {
this.simVarPublisher.subscribe('transAltAppr');

this.simVarPublisher.subscribe('magTrackRaw');
this.simVarPublisher.subscribe('selectedHeading');
this.simVarPublisher.subscribe('showSelectedHeading');
this.simVarPublisher.subscribe('altConstraint');
this.simVarPublisher.subscribe('trkFpaActive');
Expand Down
3 changes: 3 additions & 0 deletions src/instruments/src/PFD/shared/PFDSimvarPublisher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export interface PFDSimvars {
transAlt: number;
transAltAppr: number;
magTrackRaw: number;
selectedHeading: number;
showSelectedHeading: number;
altConstraint: number;
trkFpaActive: boolean;
Expand Down Expand Up @@ -209,6 +210,7 @@ export enum PFDVars {
transAlt = 'L:AIRLINER_TRANS_ALT',
transAltAppr = 'L:AIRLINER_APPR_TRANS_ALT',
magTrackRaw = 'L:A32NX_ADIRS_IR_1_TRACK',
selectedHeading = 'L:A32NX_FCU_HEADING_SELECTED',
showSelectedHeading = 'L:A320_FCU_SHOW_SELECTED_HEADING',
altConstraint = 'L:A32NX_FG_ALTITUDE_CONSTRAINT',
trkFpaActive = 'L:A32NX_TRK_FPA_MODE_ACTIVE',
Expand Down Expand Up @@ -359,6 +361,7 @@ export class PFDSimvarPublisher extends SimVarPublisher<PFDSimvars> {
['transAlt', { name: PFDVars.transAlt, type: SimVarValueType.Number }],
['transAltAppr', { name: PFDVars.transAltAppr, type: SimVarValueType.Number }],
['magTrackRaw', { name: PFDVars.magTrackRaw, type: SimVarValueType.Number }],
['selectedHeading', { name: PFDVars.selectedHeading, type: SimVarValueType.Degree }],
['showSelectedHeading', { name: PFDVars.showSelectedHeading, type: SimVarValueType.Number }],
['altConstraint', { name: PFDVars.altConstraint, type: SimVarValueType.Feet }],
['trkFpaActive', { name: PFDVars.trkFpaActive, type: SimVarValueType.Bool }],
Expand Down
3 changes: 0 additions & 3 deletions src/instruments/src/PFD/shared/SimplaneValueProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export interface SimplaneValues {
holdValue: number;
airSpeedHoldValue: number;
isSelectedSpeed: boolean;
selectedHeading: number;
selectedAltitude: number;
baroMode: 'QNH' | 'QFE' | 'STD';

Expand All @@ -24,7 +23,6 @@ export class SimplaneValueProvider {
const pressure = Simplane.getPressureValue(units);
const isSelected = Simplane.getAutoPilotAirspeedSelected();
const isMach = Simplane.getAutoPilotMachModeActive();
const selectedHeading = Simplane.getAutoPilotSelectedHeadingLockValue(false) || 0;
const selectedAltitude = Simplane.getAutoPilotDisplayedAltitudeLockValue();
const holdValue = isMach ? Simplane.getAutoPilotMachHoldValue() : Simplane.getAutoPilotAirspeedHoldValue();
const baroMode = Simplane.getPressureSelectedMode(Aircraft.A320_NEO) as 'QNH' | 'QFE' | 'STD';
Expand All @@ -34,7 +32,6 @@ export class SimplaneValueProvider {
this.publisher.pub('isSelectedSpeed', isSelected);
this.publisher.pub('machActive', isMach);
this.publisher.pub('holdValue', holdValue);
this.publisher.pub('selectedHeading', selectedHeading);
this.publisher.pub('selectedAltitude', selectedAltitude);
this.publisher.pub('baroMode', baroMode);
}
Expand Down

0 comments on commit 22212d6

Please sign in to comment.