Skip to content

Commit

Permalink
use native fms2 sync
Browse files Browse the repository at this point in the history
  • Loading branch information
Saschl committed Mar 1, 2024
1 parent 3ef891e commit b9f2f1f
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* eslint-disable no-await-in-loop */

import { Fix, NXDataStore, Waypoint, WaypointArea } from '@flybywiresim/fbw-sdk';
import { Discontinuity, SerializedFlightPlanLeg } from '@fmgc/flightplanning/new/legs/FlightPlanLeg';
import { Discontinuity, FlightPlanLeg, SerializedFlightPlanLeg } from '@fmgc/flightplanning/new/legs/FlightPlanLeg';
import { FlightPlanRpcClient } from '@fmgc/flightplanning/new/rpc/FlightPlanRpcClient';

import { FlightPlanEvents, PerformanceDataFlightPlanSyncEvents, SyncFlightPlanEvents } from '@fmgc/flightplanning/new/sync/FlightPlanEvents';
Expand All @@ -21,16 +21,6 @@ export class FlightPlanAsoboSync {

private facilityLoaderCustom: FacilityLoader;

private cruiseFlightLevel = undefined;

private originAirport = undefined;

private destinationAirport = undefined;

private procedureDetails = undefined;

private enrouteLegs: (SerializedFlightPlanLeg | Discontinuity)[] = undefined;

private rpcClient: FlightPlanRpcClient<A320FlightPlanPerformanceData>;

private mapping: MsfsMapping;
Expand Down Expand Up @@ -62,62 +52,40 @@ export class FlightPlanAsoboSync {

// initial sync
if (NXDataStore.get('FP_SYNC', 'LOAD') === 'SAVE') {
const pub = this.bus.getPublisher<FlightPlanEvents>();
pub.pub('flightPlanManager.syncRequest', undefined, true);
this.syncFlightPlanToGame();
}

sub.on('flightPlanManager.syncResponse').handle(async (event) => {
if (NXDataStore.get('FP_SYNC', 'LOAD') === 'SAVE') {
console.log('SYNC RESPONSE', event);
const plan = event.plans[FlightPlanIndex.Active];
this.enrouteLegs = plan.segments.enrouteSegment.allLegs;
this.originAirport = plan.originAirport;
this.destinationAirport = plan.destinationAirport;
this.cruiseFlightLevel = plan.performanceData.cruiseFlightLevel;

// TODO not really needed anymore
this.procedureDetails = {
originRunway: plan.originRunway,
departureIdent: plan.segments.departureSegment?.procedureIdent,
departureTransitionIdent: plan.segments.departureRunwayTransitionSegment?.procedureIdent,

arrivalIdent: plan.segments.arrivalSegment?.procedureIdent,
arrivalTransitionIdent: plan.segments.arrivalEnrouteTransitionSegment?.procedureIdent,
arrivalRunwayTransitionIdent: plan.segments?.arrivalRunwayTransitionSegment.procedureIdent,
destinationRunway: plan.destinationRunway,
approachIdent: plan.segments.approachSegment?.procedureIdent,
approachTransitionIdent: plan.segments.approachViaSegment?.procedureIdent,
};

await this.syncFlightPlanToGame();
}
});

sub.on('flightPlan.setPerformanceData.cruiseFlightLevel').handle(async (event) => {
if (event.planIndex === FlightPlanIndex.Active) {
this.cruiseFlightLevel = event.value;
console.log('SET CRUISE FLIGHT LEVEL', this.cruiseFlightLevel);
await Coherent.call('SET_CRUISE_ALTITUDE', this.cruiseFlightLevel * 100);
// this.cruiseFlightLevel = event.value;
console.log('SET CRUISE FLIGHT LEVEL', event.value);
await Coherent.call('SET_CRUISE_ALTITUDE', event.value * 100);
}
});
sub.on('SYNC_flightPlan.setSegmentLegs').handle(async (event) => {
console.log('SEGMENT LEGS', event);
// enroute only
if ((event.planIndex === FlightPlanIndex.Active) && event.segmentIndex === 4) {
this.enrouteLegs = event.legs;
await this.syncFlightPlanToGame();
}
});

sub.on('flightPlanManager.copy').handle(async (event) => {
if (NXDataStore.get('FP_SYNC', 'LOAD') === 'SAVE' && event.targetPlanIndex === FlightPlanIndex.Active) {
const pub = this.bus.getPublisher<FlightPlanEvents>();
pub.pub('flightPlanManager.syncRequest', undefined, true);
this.syncFlightPlanToGame();
}
});
sub.on('flightPlanManager.create').handle(async (event) => {
if (NXDataStore.get('FP_SYNC', 'LOAD') === 'SAVE' && event.planIndex === FlightPlanIndex.Active) {
const pub = this.bus.getPublisher<FlightPlanEvents>();
pub.pub('flightPlanManager.syncRequest', undefined, true);
this.syncFlightPlanToGame();
}
});
}
Expand Down Expand Up @@ -197,11 +165,13 @@ export class FlightPlanAsoboSync {
await Coherent.call('SET_CURRENT_FLIGHTPLAN_INDEX', 0, true);
await Coherent.call('CLEAR_CURRENT_FLIGHT_PLAN');

if (this.originAirport && this.destinationAirport) {
await Coherent.call('SET_ORIGIN', `A ${this.originAirport} `, false);
await Coherent.call('SET_DESTINATION', `A ${this.destinationAirport} `, false);
const plan = this.rpcClient.get(FlightPlanIndex.Active);

if (plan.originAirport && plan.destinationAirport) {
await Coherent.call('SET_ORIGIN', `A ${plan.originAirport.ident} `, false);
await Coherent.call('SET_DESTINATION', `A ${plan.destinationAirport.ident} `, false);

const allEnrouteLegs = this.enrouteLegs;
const allEnrouteLegs = plan.enrouteSegment.allLegs;
console.log('ALL ENROUTE LEGS', allEnrouteLegs);

let globalIndex = 1;
Expand All @@ -210,7 +180,7 @@ export class FlightPlanAsoboSync {
const leg = allEnrouteLegs[i];
console.log('LEG', leg);
if (!leg.isDiscontinuity) {
const fpLeg = leg as SerializedFlightPlanLeg;
const fpLeg = leg as FlightPlanLeg;
if (fpLeg) {
console.log('DEFINITION', fpLeg.definition);
console.log('DBID', fpLeg.definition.waypoint.databaseId);
Expand All @@ -224,22 +194,22 @@ export class FlightPlanAsoboSync {
}
}

const originFacility = await this.facilityLoaderCustom.getFacility(FacilityType.Airport, `A ${this.originAirport.substring(0, 4)} `);
const originFacility = await this.facilityLoaderCustom.getFacility(FacilityType.Airport, `A ${plan.originAirport.ident.substring(0, 4)} `);
let originRw = 0;
let departureRw = 0;
for (const runway of originFacility.runways) {
for (const designation of runway.designation.split('-')) {
console.log('ORIGIN RUNWAY', this.procedureDetails.originRunway);
console.log('ORIGIN RUNWAY', plan.originRunway.ident);
console.log(designation);
if (designation === FlightPlanAsoboSync.extractRunwayNumber(this.procedureDetails.originRunway)) {
if (designation === FlightPlanAsoboSync.extractRunwayNumber(plan.originRunway.ident)) {
console.log(`Runway parent ${originRw} is matching with actual index ${departureRw}. Is ${JSON.stringify(runway)}`);
await Coherent.call('SET_ORIGIN_RUNWAY_INDEX', originRw);
await Coherent.call('SET_DEPARTURE_RUNWAY_INDEX', departureRw);
const departureIndex = originFacility.departures
.findIndex((departure) => departure.name === this.procedureDetails.departureIdent);
.findIndex((departure) => departure.name === plan.departureSegment.procedure.ident);
const departureTransitionIndex = originFacility.departures
.findIndex((departure) => departure.enRouteTransitions
.map((t) => t.name === this.procedureDetails.departureTransitionIdent));
.map((t) => t.name === plan.departureEnrouteTransitionSegment.procedure.ident));

console.log('DEPARTURE INDEX', departureIndex);
console.log('DEPARTURE TransitionIndex', departureIndex);
Expand All @@ -259,64 +229,63 @@ export class FlightPlanAsoboSync {

// console.log('DESTINATION SEGMENT', plan.segments);

if (this.destinationAirport) {
const destinationRunwayIdent = this.procedureDetails.destinationRunway;
console.log('IDENT', destinationRunwayIdent);

const arg = await this.facilityLoaderCustom.getFacility(FacilityType.Airport, `A ${this.destinationAirport.substring(0, 4)} `);
console.log('ARRIVAL', arg);
for (const runway of arg.runways) {
for (const designation of runway.designation.split('-')) {
console.log(destinationRunwayIdent);
console.log(designation);
if (designation === FlightPlanAsoboSync.extractRunwayNumber(destinationRunwayIdent)) {
console.log(`Runway is matching with actual index ${destinationRunwayIndex}. Is ${JSON.stringify(runway)}`);
const arrivalIndex = arg.arrivals
.findIndex((arrival) => arrival.name === this.procedureDetails.arrivalIdent);
const arritvalTransitionIndex = arg.arrivals
.findIndex((arrival) => arrival.enRouteTransitions.map((t) => t.name === this.procedureDetails.arrivalTransitionIdent));

console.log('APPR IDENT', this.procedureDetails.approachIdent);
console.log('available appr', arg.approaches);
let approachName = this.procedureDetails.approachIdent;

// FIXME how to map that properly
if (approachName.startsWith('D')) {
approachName = `VOR ${FlightPlanAsoboSync.extractRunwayNumber(approachName)} ${approachName.substring(approachName.length - 1)}`.trim();
console.log('NEW APPR NAME', approachName);
} else if (approachName.startsWith('I')) {
approachName = `ILS ${FlightPlanAsoboSync.extractRunwayNumber(approachName)} ${approachName.substring(approachName.length - 1)}`.trim();
console.log('NEW APPR NAME', approachName);
} else if (approachName.startsWith('R')) {
approachName = `RNAV ${FlightPlanAsoboSync.extractRunwayNumber(approachName)} ${approachName.substring(approachName.length - 1)}`.trim();
console.log('NEW APPR NAME', approachName);
}
const apoprachIndex = arg.approaches
.findIndex((approach) => approach.name === approachName);
const approachEnrouteTransitionIndex = arg.approaches
.findIndex((approach) => approach.transitions.map((t) => t.name === this.procedureDetails.approachTransitionIdent));

console.log('DESTINATION RUNWAY INDEX', destinationRunwayIndex);
console.log('ARRIVAL INDEX', arrivalIndex);
console.log('ARRIVAL TransitionIndex', arritvalTransitionIndex);
console.log('APPROACH INDEX', apoprachIndex);
console.log('APPROACH TransitionIndex', approachEnrouteTransitionIndex);

await Coherent.call('SET_ARRIVAL_RUNWAY_INDEX', destinationRunwayIndex);
await Coherent.call('SET_ARRIVAL_PROC_INDEX', arrivalIndex);
await Coherent.call('SET_ARRIVAL_ENROUTE_TRANSITION_INDEX', arritvalTransitionIndex);
await Coherent.call('SET_APPROACH_INDEX', apoprachIndex);

await Coherent.call('SET_APPROACH_TRANSITION_INDEX', approachEnrouteTransitionIndex);

// nono
break;
const destinationRunwayIdent = plan.destinationRunway.ident;
console.log('IDENT', destinationRunwayIdent);

const arg = await this.facilityLoaderCustom.getFacility(FacilityType.Airport, `A ${plan.destinationAirport.ident.substring(0, 4)} `);
console.log('ARRIVAL', arg);
for (const runway of arg.runways) {
for (const designation of runway.designation.split('-')) {
console.log(destinationRunwayIdent);
console.log(designation);
if (designation === FlightPlanAsoboSync.extractRunwayNumber(destinationRunwayIdent)) {
console.log(`Runway is matching with actual index ${destinationRunwayIndex}. Is ${JSON.stringify(runway)}`);
const arrivalIndex = arg.arrivals
.findIndex((arrival) => arrival.name === plan.arrival.ident);
const arritvalTransitionIndex = arg.arrivals
.findIndex((arrival) => arrival.enRouteTransitions.map((t) => t.name === plan.arrivalEnrouteTransition.ident));

console.log('APPR IDENT', plan.approach.ident);
console.log('available appr', arg.approaches);
let approachName = plan.approach.ident;

// FIXME how to map that properly
if (approachName.startsWith('D')) {
approachName = `VOR ${FlightPlanAsoboSync.extractRunwayNumber(approachName)} ${approachName.substring(approachName.length - 1)}`.trim();
console.log('NEW APPR NAME', approachName);
} else if (approachName.startsWith('I')) {
approachName = `ILS ${FlightPlanAsoboSync.extractRunwayNumber(approachName)} ${approachName.substring(approachName.length - 1)}`.trim();
console.log('NEW APPR NAME', approachName);
} else if (approachName.startsWith('R')) {
approachName = `RNAV ${FlightPlanAsoboSync.extractRunwayNumber(approachName)} ${approachName.substring(approachName.length - 1)}`.trim();
console.log('NEW APPR NAME', approachName);
}
destinationRunwayIndex++;
const apoprachIndex = arg.approaches
.findIndex((approach) => approach.name === approachName);
const approachEnrouteTransitionIndex = arg.approaches
.findIndex((approach) => approach.transitions.map((t) => t.name === plan.approachVia.ident));

console.log('DESTINATION RUNWAY INDEX', destinationRunwayIndex);
console.log('ARRIVAL INDEX', arrivalIndex);
console.log('ARRIVAL TransitionIndex', arritvalTransitionIndex);
console.log('APPROACH INDEX', apoprachIndex);
console.log('APPROACH TransitionIndex', approachEnrouteTransitionIndex);

await Coherent.call('SET_ARRIVAL_RUNWAY_INDEX', destinationRunwayIndex);
await Coherent.call('SET_ARRIVAL_PROC_INDEX', arrivalIndex);
await Coherent.call('SET_ARRIVAL_ENROUTE_TRANSITION_INDEX', arritvalTransitionIndex);
await Coherent.call('SET_APPROACH_INDEX', apoprachIndex);

await Coherent.call('SET_APPROACH_TRANSITION_INDEX', approachEnrouteTransitionIndex);

// nono
break;
}
destinationRunwayIndex++;
}
}
await Coherent.call('SET_CRUISE_ALTITUDE', this.cruiseFlightLevel * 100);

await Coherent.call('SET_CRUISE_ALTITUDE', plan.performanceData.cruiseFlightLevel * 100);
}
}
await Coherent.call('RECOMPUTE_ACTIVE_WAYPOINT_INDEX', 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export interface FlightPlanRemoteClientRpcEvents<P extends FlightPlanPerformance
}

export class FlightPlanRpcClient<P extends FlightPlanPerformanceData> implements FlightPlanInterface<P> {
constructor(private readonly bus: EventBus) {
constructor(private readonly bus: EventBus, private readonly performanceData: P) {
this.sub.on('flightPlanServer_rpcCommandResponse').handle(([responseId, response]) => {
if (this.rpcCommandsSent.has(responseId)) {
const [resolve] = this.rpcCommandsSent.get(responseId) ?? [];
Expand All @@ -41,7 +41,7 @@ export class FlightPlanRpcClient<P extends FlightPlanPerformanceData> implements

private readonly flightPlanManager = new FlightPlanManager<P>(
this.bus,
{} as P /* This flight plan manager will never create plans, so this is fine */,
this.performanceData,
Math.round(Math.random() * 10_000),
false,
);
Expand All @@ -57,7 +57,7 @@ export class FlightPlanRpcClient<P extends FlightPlanPerformanceData> implements
): Promise<ReturnType<FunctionsOnlyAndUnwrapPromises<FlightPlanInterface<P>>[T]>> {
const id = v4();

this.pub.pub('flightPlanRemoteClient_rpcCommand', [funcName, id, ...args], true);
this.pub.pub('flightPlanRemoteClient_rpcCommand', [funcName, id, ...args], true, false);

const result = await this.waitForRpcCommandResponse<ReturnType<FunctionsOnlyAndUnwrapPromises<FlightPlanInterface<P>>[T]>>(id);

Expand Down

0 comments on commit b9f2f1f

Please sign in to comment.