Skip to content

Commit

Permalink
fix(a380x): FMS, ECL, BTV fallback fixes (flybywiresim#9306)
Browse files Browse the repository at this point in the history
* FMS: Fix color of mandatory fields with 0 as value

* make DEPARTURE CHANGE somehow deferred

* FMS: Don't allow AIRWAYS for ORIGIN/RWY legs

* BTV Fallback: Don't subtract TDZ distance, remove amber "select landing runway in fms" if rwy is set

* FMS: Disable airways for airport and runways, disable CMS completely for now

* Don't allow key input if not focus, lower auto-blur time from 30s to 10s

* ok no, let's do 20s

* changelog

* improve comment

* Revert "improve comment"

This reverts commit 2efe58a.

* Revert "BTV Fallback: Don't subtract TDZ distance, remove amber "select landing runway in fms" if rwy is set"

This reverts commit 900d964.
  • Loading branch information
flogross89 authored Nov 4, 2024
1 parent 658a8a9 commit 4b356cc
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 22 deletions.
1 change: 1 addition & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
1. [A380X/TELEX] Added popup for telex consent - @saschl (saschl) @Maximilian-Reuter (\_chaoz)
1. [ND] Fix memory leak when using TERR ON ND - @Nufflee (nufflee)
1. [A380X/OVHD] Fix RCDR GND CTL button/logic - @flogross89 (floridude)
1. [A380X] Various fixes in FMS and ECL @flogross89 (floridude)

## 0.12.0

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TurnDirection } from '@flybywiresim/fbw-sdk';
import { TurnDirection, WaypointDescriptor } from '@flybywiresim/fbw-sdk';
import { HoldType } from '@fmgc/flightplanning/data/flightplan';
import { SegmentClass } from '@fmgc/flightplanning/segments/SegmentClass';
import { FlightPlanIndex } from '@fmgc/index';
Expand All @@ -24,6 +24,8 @@ export function getRevisionsMenu(fpln: MfdFmsFpln, type: FplnRevisionsMenuType):
return [];
}

const revisedLeg = fpln.loadedFlightPlan?.legElementAt(legIndex);

return [
{
name: 'FROM P.POS DIR TO',
Expand All @@ -32,7 +34,7 @@ export function getRevisionsMenu(fpln: MfdFmsFpln, type: FplnRevisionsMenuType):
legIndex >= (fpln.loadedFlightPlan?.firstMissedApproachLegIndex ?? Infinity) ||
planIndex === FlightPlanIndex.Temporary ||
[FplnRevisionsMenuType.Discontinuity || FplnRevisionsMenuType.TooSteepPath].includes(type) ||
!fpln.loadedFlightPlan?.legElementAt(legIndex).isXF(),
!revisedLeg?.isXF(),
onPressed: () => {
const ppos = fpln.props.fmcService.master?.navigation.getPpos();
if (ppos) {
Expand Down Expand Up @@ -85,17 +87,16 @@ export function getRevisionsMenu(fpln: MfdFmsFpln, type: FplnRevisionsMenuType):
name: 'HOLD',
disabled: [FplnRevisionsMenuType.Discontinuity || FplnRevisionsMenuType.TooSteepPath].includes(type),
onPressed: async () => {
const waypoint = fpln.props.fmcService.master?.flightPlanService.active.legElementAt(legIndex);
if (waypoint && !waypoint.isHX()) {
const alt = waypoint.definition.altitude1
? waypoint.definition.altitude1
if (revisedLeg && !revisedLeg.isHX()) {
const alt = revisedLeg.definition.altitude1
? revisedLeg.definition.altitude1
: SimVar.GetSimVarValue('INDICATED ALTITUDE', 'feet');

const previousLeg = fpln.props.fmcService.master?.flightPlanService.active.maybeElementAt(legIndex - 1);

let inboundMagneticCourse = 100;
const prevTerm = previousLeg?.isDiscontinuity === false && previousLeg?.terminationWaypoint();
const wptTerm = waypoint.terminationWaypoint();
const wptTerm = revisedLeg.terminationWaypoint();
if (previousLeg && previousLeg.isDiscontinuity === false && previousLeg.isXF() && prevTerm && wptTerm) {
inboundMagneticCourse = Avionics.Utils.computeGreatCircleHeading(prevTerm.location, wptTerm.location);
}
Expand All @@ -122,7 +123,12 @@ export function getRevisionsMenu(fpln: MfdFmsFpln, type: FplnRevisionsMenuType):
},
{
name: 'AIRWAYS',
disabled: [FplnRevisionsMenuType.Discontinuity || FplnRevisionsMenuType.TooSteepPath].includes(type),
disabled:
[
FplnRevisionsMenuType.Runway || FplnRevisionsMenuType.Discontinuity || FplnRevisionsMenuType.TooSteepPath,
].includes(type) ||
revisedLeg?.waypointDescriptor === WaypointDescriptor.Airport ||
revisedLeg?.waypointDescriptor === WaypointDescriptor.Runway,
onPressed: () => {
fpln.props.fmcService.master?.flightPlanService.startAirwayEntry(legIndex);
fpln.props.mfd.uiService.navigateTo(`fms/${fpln.props.mfd.uiService.activeUri.get().category}/f-pln-airways`);
Expand All @@ -132,7 +138,7 @@ export function getRevisionsMenu(fpln: MfdFmsFpln, type: FplnRevisionsMenuType):
name:
!altnFlightPlan &&
![FplnRevisionsMenuType.Discontinuity || FplnRevisionsMenuType.TooSteepPath].includes(type) &&
fpln.loadedFlightPlan?.legElementAt(legIndex).definition.overfly
revisedLeg?.definition.overfly
? 'DELETE OVERFLY *'
: 'OVERFLY *',
disabled:
Expand Down Expand Up @@ -163,9 +169,11 @@ export function getRevisionsMenu(fpln: MfdFmsFpln, type: FplnRevisionsMenuType):
),
},
{
name: 'CMS',
name: '(N/A) CMS',
disabled:
altnFlightPlan || [FplnRevisionsMenuType.Discontinuity || FplnRevisionsMenuType.TooSteepPath].includes(type),
true ||
altnFlightPlan ||
[FplnRevisionsMenuType.Discontinuity || FplnRevisionsMenuType.TooSteepPath].includes(type),
onPressed: () =>
fpln.props.mfd.uiService.navigateTo(
`fms/${fpln.props.mfd.uiService.activeUri.get().category}/f-pln-vert-rev/cms`,
Expand All @@ -185,9 +193,9 @@ export function getRevisionsMenu(fpln: MfdFmsFpln, type: FplnRevisionsMenuType):
disabled: true,
onPressed: () => {
// Find out whether waypoint is CLB, CRZ or DES waypoint and direct to appropriate WIND sub-page
if (fpln.loadedFlightPlan?.legElementAt(legIndex)?.segment?.class === SegmentClass.Arrival) {
if (revisedLeg?.segment?.class === SegmentClass.Arrival) {
fpln.props.mfd.uiService.navigateTo(`fms/${fpln.props.mfd.uiService.activeUri.get().category}/wind/des`);
} else if (fpln.loadedFlightPlan?.legElementAt(legIndex)?.segment?.class === SegmentClass.Enroute) {
} else if (revisedLeg?.segment?.class === SegmentClass.Enroute) {
fpln.props.mfd.uiService.navigateTo(`fms/${fpln.props.mfd.uiService.activeUri.get().category}/wind/crz`);
} else {
fpln.props.mfd.uiService.navigateTo(`fms/${fpln.props.mfd.uiService.activeUri.get().category}/wind/clb`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ export class InputField<T> extends DisplayComponent<InputFieldProps<T>> {
}

private onKeyDown(ev: KeyboardEvent) {
if (!this.isFocused.get()) {
return;
}

if (ev.keyCode === KeyCode.KEY_BACK_SPACE) {
this.handleBackspace();
}
Expand All @@ -185,6 +189,10 @@ export class InputField<T> extends DisplayComponent<InputFieldProps<T>> {
}

private onKeyPress(ev: KeyboardEvent) {
if (!this.isFocused.get()) {
return;
}

// Un-select the text
this.textInputRef.instance.classList.remove('valueSelected');

Expand Down Expand Up @@ -238,12 +246,12 @@ export class InputField<T> extends DisplayComponent<InputFieldProps<T>> {
}
this.isFocused.set(true);

// After 30s, unfocus field, if some other weird focus error happens
// After 20s, unfocus field, if some other weird focus error happens
setTimeout(() => {
if (this.isFocused.get()) {
Coherent.trigger('UNFOCUS_INPUT_FIELD', this.guid);
}
}, 30_000);
}, 20_000);
this.textInputRef.instance.classList.add('valueSelected');
this.textInputRef.instance.classList.add('editing');
if (this.props.mandatory?.get()) {
Expand Down Expand Up @@ -277,7 +285,7 @@ export class InputField<T> extends DisplayComponent<InputFieldProps<T>> {
}

// Restore mandatory class for correct coloring of dot (e.g. non-placeholders)
if (!this.props.value.get() && this.props.mandatory?.get()) {
if (this.props.value.get() === null && this.props.mandatory?.get()) {
this.textInputRef.instance.classList.add('mandatory');
}

Expand Down Expand Up @@ -398,7 +406,7 @@ export class InputField<T> extends DisplayComponent<InputFieldProps<T>> {

this.subs.push(
this.props.mandatory.sub((val) => {
if (val && !this.props.value.get()) {
if (val && this.props.value.get() === null) {
this.textInputRef.instance.classList.add('mandatory');
} else {
this.textInputRef.instance.classList.remove('mandatory');
Expand Down Expand Up @@ -434,15 +442,15 @@ export class InputField<T> extends DisplayComponent<InputFieldProps<T>> {
this.containerRef.instance.classList.add('disabled');
this.textInputRef.instance.classList.add('disabled');

if (this.props.mandatory?.get() && !this.props.value.get()) {
if (this.props.mandatory?.get() && this.props.value.get() === null) {
this.textInputRef.instance.classList.remove('mandatory');
}
} else {
this.textInputRef.instance.tabIndex = -1;
this.containerRef.instance.classList.remove('disabled');
this.textInputRef.instance.classList.remove('disabled');

if (this.props.mandatory?.get() && !this.props.value.get()) {
if (this.props.mandatory?.get() && this.props.value.get() === null) {
this.textInputRef.instance.classList.add('mandatory');
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ export const EcamNormalProcedures: { [n: number]: NormalProcedure } = {
},
1000006: {
title: '<<DEPARTURE CHANGE>>',
deferred: true,
items: [
{
name: 'RWY & SID',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,8 @@ export interface NormalProcedure {
title: string;
/** An array of possible checklist items.. */
items: ChecklistAction[];
/** Checklist is deferred, i.e. only activated by request */
deferred?: boolean;
}

export function isChecklistAction(element: ChecklistAction | ChecklistCondition): element is ChecklistAction {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class FwsNormalChecklists {
const proc = EcamNormalProcedures[k] as NormalProcedure;
this.checklistState.setValue(k, {
id: k,
checklistCompleted: false,
checklistCompleted: proc.deferred ? true : false,
itemsCompleted: Array(proc.items.length).fill(false),
});
});
Expand Down Expand Up @@ -176,7 +176,6 @@ export class FwsNormalChecklists {
this.moveDown();
} else if (this.selectedLine.get() === clState.itemsCompleted.length) {
// C/L complete
console.log('COMPLETE');
clState.checklistCompleted = true;
const proc = EcamNormalProcedures[this.checklistId.get()];
clState.itemsCompleted = clState.itemsCompleted.map((val, index) => (proc.items[index].sensed ? val : true));
Expand All @@ -199,7 +198,7 @@ export class FwsNormalChecklists {
const procFollowing = EcamNormalProcedures[idFollowing];
const clStateFollowing: ChecklistState = {
id: idFollowing,
checklistCompleted: false,
checklistCompleted: procFollowing.deferred ? true : false,
itemsCompleted: [...clFollowing.itemsCompleted].map((val, index) =>
procFollowing.items[index].sensed ? val : false,
),
Expand Down

0 comments on commit 4b356cc

Please sign in to comment.