Skip to content

Commit

Permalink
feat(a380x/fma): disconnect ap for ldg message (#9606)
Browse files Browse the repository at this point in the history
* feat(a380x/fma): disconnect ap for ldg message

* Address notation & subject usage with tracer suggestions

Co-Authored-By: Michael Corcoran <[email protected]>

---------

Co-authored-by: Michael Corcoran <[email protected]>
  • Loading branch information
BravoMike99 and tracernz authored Dec 29, 2024
1 parent 3bf1438 commit 125a86d
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 27 deletions.
1 change: 1 addition & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
1. [ELEC] Improved elec system startup behaviour - @Gurgel100 (Pascal) - @saschl
1. [A380X] Improve pilot and copilot camera positions - @heclak (Heclak)
1. [A380X/EFIS] Illuminate ND range and mode selectors during light test - @BravoMike99 (bruno_pt99)
1. [A380/PFD] Add DISCONNECT AP FOR LDG FMA message - @BravoMike99 (bruno_pt99)
1. [A380X/ENG] Adjust climb thrust to be more accurate - @BlueberryKing (BlueberryKing)
1. [A380X/ANIM] Animation of flaps now from FPPU position. Interim fix for spoiler low end animation - @Crocket63 (crocket)
1. [A380X/ENGINES] Adjust climb thrust to be more accurate - @BlueberryKing (BlueberryKing)
Expand Down
119 changes: 92 additions & 27 deletions fbw-a380x/src/systems/instruments/src/PFD/FMA.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
/* eslint-disable no-constant-condition */
import {
ComponentProps,
ConsumerSubject,
DisplayComponent,
EventBus,
FSComponent,
MappedSubject,
Subject,
Subscribable,
VNode,
Expand Down Expand Up @@ -43,9 +45,9 @@ abstract class ShowForSecondsComponent<T extends ComponentProps> extends Display
}

export class FMA extends DisplayComponent<{ bus: EventBus; isAttExcessive: Subscribable<boolean> }> {
private activeLateralMode: number = 0;
private sub = this.props.bus.getSubscriber<PFDSimvars & Arinc429Values>();

private activeVerticalMode: number = 0;
private activeLateralMode: number = 0;

private armedVerticalModeSub = Subject.create(0);

Expand All @@ -69,12 +71,56 @@ export class FMA extends DisplayComponent<{ bus: EventBus; isAttExcessive: Subsc

private AB3Message = Subject.create(false);

private readonly radioHeight = ConsumerSubject.create(this.sub.on('chosenRa'), Arinc429Word.empty());

private readonly altitude = ConsumerSubject.create(this.sub.on('altitudeAr'), Arinc429Word.empty());

private readonly landingElevation = ConsumerSubject.create(this.sub.on('landingElevation'), Arinc429Word.empty());

private readonly ap1Active = ConsumerSubject.create(this.sub.on('ap1Active'), false);

private readonly ap2Active = ConsumerSubject.create(this.sub.on('ap2Active'), false);

private readonly activeVerticalMode = ConsumerSubject.create(this.sub.on('activeVerticalMode'), 0);

private readonly selectedVerticalSpeed = ConsumerSubject.create(this.sub.on('apVsSelected'), null);

private readonly selectedFpa = ConsumerSubject.create(this.sub.on('selectedFpa'), null);

private readonly approachCapability = ConsumerSubject.create(this.sub.on('approachCapability'), 0);

private disconnectApForLdg = MappedSubject.create(
([ap1, ap2, ra, altitude, landingElevation, verticalMode, selectedFpa, selectedVs, approachCapability]) => {
return (
(ap1 || ap2) &&
(ra.isNormalOperation() ? ra.value <= 150 : altitude.valueOr(Infinity) - landingElevation.valueOr(0) <= 150) &&
(approachCapability === 1 || // CAT 1 or FLS
approachCapability === 6 ||
approachCapability === 7 ||
approachCapability === 8 ||
verticalMode === VerticalMode.DES ||
verticalMode === VerticalMode.OP_DES ||
(verticalMode === VerticalMode.FPA && selectedFpa <= 0) ||
(verticalMode === VerticalMode.VS && selectedVs <= 0))
);
},
this.ap1Active,
this.ap2Active,
this.radioHeight,
this.altitude,
this.landingElevation,
this.activeVerticalMode,
this.selectedFpa,
this.selectedVerticalSpeed,
this.approachCapability,
);

private handleFMABorders() {
const sharedModeActive =
this.activeLateralMode === 32 ||
this.activeLateralMode === 33 ||
this.activeLateralMode === 34 ||
(this.activeLateralMode === 20 && this.activeVerticalMode === 24);
(this.activeLateralMode === 20 && this.activeVerticalMode.get() === 24);
const BC3Message =
getBC3Message(
this.props.isAttExcessive.get(),
Expand All @@ -83,6 +129,7 @@ export class FMA extends DisplayComponent<{ bus: EventBus; isAttExcessive: Subsc
this.trkFpaDeselected.get(),
this.tcasRaInhibited.get(),
this.tdReached,
this.disconnectApForLdg.get(),
)[0] !== null;

const engineMessage = this.athrModeMessage;
Expand Down Expand Up @@ -115,60 +162,55 @@ export class FMA extends DisplayComponent<{ bus: EventBus; isAttExcessive: Subsc
onAfterRender(node: VNode): void {
super.onAfterRender(node);

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

this.props.isAttExcessive.sub((_a) => {
this.handleFMABorders();
});

sub
this.sub
.on('fmaVerticalArmed')
.whenChanged()
.handle((a) => {
this.armedVerticalModeSub.set(a);
this.handleFMABorders();
});

sub
this.sub
.on('activeLateralMode')
.whenChanged()
.handle((activeLateralMode) => {
this.activeLateralMode = activeLateralMode;
this.handleFMABorders();
});
sub
.on('activeVerticalMode')
.whenChanged()
.handle((activeVerticalMode) => {
this.activeVerticalMode = activeVerticalMode;
this.handleFMABorders();
});

sub
this.activeVerticalMode.sub(() => this.handleFMABorders());

this.sub
.on('setHoldSpeed')
.whenChanged()
.handle((shs) => {
this.setHoldSpeed = shs;
this.handleFMABorders();
});

sub
this.sub
.on('tcasRaInhibited')
.whenChanged()
.handle((tra) => {
this.tcasRaInhibited.set(tra);
this.handleFMABorders();
});

sub
this.sub
.on('trkFpaDeselectedTCAS')
.whenChanged()
.handle((trk) => {
this.trkFpaDeselected.set(trk);
this.handleFMABorders();
});

sub
this.sub
.on('tdReached')
.whenChanged()
.handle((tdr) => {
Expand All @@ -189,7 +231,12 @@ export class FMA extends DisplayComponent<{ bus: EventBus; isAttExcessive: Subsc

<Row1 bus={this.props.bus} isAttExcessive={this.props.isAttExcessive} />
<Row2 bus={this.props.bus} isAttExcessive={this.props.isAttExcessive} />
<Row3 bus={this.props.bus} isAttExcessive={this.props.isAttExcessive} AB3Message={this.AB3Message} />
<Row3
bus={this.props.bus}
isAttExcessive={this.props.isAttExcessive}
disconnectApForLdg={this.disconnectApForLdg}
AB3Message={this.AB3Message}
/>
</g>
);
}
Expand Down Expand Up @@ -347,6 +394,7 @@ class A2Cell extends DisplayComponent<{ bus: EventBus }> {
class Row3 extends DisplayComponent<{
bus: EventBus;
isAttExcessive: Subscribable<boolean>;
disconnectApForLdg: Subscribable<boolean>;
AB3Message: Subscribable<boolean>;
}> {
private cellsToHide = FSComponent.createRef<SVGGElement>();
Expand All @@ -371,7 +419,11 @@ class Row3 extends DisplayComponent<{
<AB3Cell bus={this.props.bus} />
<D3Cell bus={this.props.bus} />
</g>
<BC3Cell isAttExcessive={this.props.isAttExcessive} bus={this.props.bus} />
<BC3Cell
isAttExcessive={this.props.isAttExcessive}
disconnectApForLdg={this.props.disconnectApForLdg}
bus={this.props.bus}
/>
<E3Cell bus={this.props.bus} />
</g>
);
Expand Down Expand Up @@ -1298,6 +1350,7 @@ const getBC3Message = (
trkFpaDeselectedTCAS: boolean,
tcasRaInhibited: boolean,
tdReached: boolean,
disconnectApForLdg: boolean,
) => {
const armedVerticalBitmask = armedVerticalMode;
const TCASArmed = (armedVerticalBitmask >> 6) & 1;
Expand All @@ -1312,6 +1365,9 @@ const getBC3Message = (
} else if (false) {
text = 'FOR GA: SET TOGA';
className = 'PulseAmber9Seconds Amber';
} else if (disconnectApForLdg) {
text = 'DISCONNECT AP FOR LDG';
className = 'FontSmall PulseAmber9Seconds Amber';
} else if (TCASArmed && !isAttExcessive) {
text = 'TCAS ';
className = 'FontMediumSmaller Cyan';
Expand Down Expand Up @@ -1346,7 +1402,13 @@ const getBC3Message = (
return [text, className];
};

class BC3Cell extends DisplayComponent<{ isAttExcessive: Subscribable<boolean>; bus: EventBus }> {
class BC3Cell extends DisplayComponent<{
isAttExcessive: Subscribable<boolean>;
disconnectApForLdg: Subscribable<boolean>;
bus: EventBus;
}> {
private sub = this.props.bus.getSubscriber<PFDSimvars & Arinc429Values>();

private bc3Cell = FSComponent.createRef<SVGTextElement>();

private classNameSub = Subject.create('');
Expand All @@ -1371,6 +1433,7 @@ class BC3Cell extends DisplayComponent<{ isAttExcessive: Subscribable<boolean>;
this.trkFpaDeselected,
this.tcasRaInhibited,
this.tdReached,
this.props.disconnectApForLdg.get(),
);
this.classNameSub.set(`FontMedium MiddleAlign ${className}`);
if (text !== null) {
Expand All @@ -1383,46 +1446,48 @@ class BC3Cell extends DisplayComponent<{ isAttExcessive: Subscribable<boolean>;
onAfterRender(node: VNode): void {
super.onAfterRender(node);

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

this.props.isAttExcessive.sub((e) => {
this.isAttExcessive = e;
this.fillBC3Cell();
});

sub
this.props.disconnectApForLdg.sub(() => {
this.fillBC3Cell();
});

this.sub
.on('fmaVerticalArmed')
.whenChanged()
.handle((v) => {
this.armedVerticalMode = v;
this.fillBC3Cell();
});

sub
this.sub
.on('setHoldSpeed')
.whenChanged()
.handle((shs) => {
this.setHoldSpeed = shs;
this.fillBC3Cell();
});

sub
this.sub
.on('tcasRaInhibited')
.whenChanged()
.handle((tra) => {
this.tcasRaInhibited = tra;
this.fillBC3Cell();
});

sub
this.sub
.on('trkFpaDeselectedTCAS')
.whenChanged()
.handle((trk) => {
this.trkFpaDeselected = trk;
this.fillBC3Cell();
});

sub
this.sub
.on('tdReached')
.whenChanged()
.handle((tdr) => {
Expand Down

0 comments on commit 125a86d

Please sign in to comment.