Skip to content

Commit

Permalink
feat(efb): wip payload v2 - working efb broken a32nx_boarding
Browse files Browse the repository at this point in the history
  • Loading branch information
2hwk committed Dec 21, 2022
1 parent aa48e96 commit 7f87227
Show file tree
Hide file tree
Showing 10 changed files with 547 additions and 276 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-undef */
function airplaneCanBoard() {
const busDC2 = SimVar.GetSimVarValue("L:A32NX_ELEC_DC_2_BUS_IS_POWERED", "Bool");
const busDCHot1 = SimVar.GetSimVarValue("L:A32NX_ELEC_DC_HOT_1_BUS_IS_POWERED", "Bool");
Expand Down Expand Up @@ -28,6 +29,7 @@ class A32NX_Boarding {
}

async init() {
/*
const inDeveloperState = SimVar.GetSimVarValue("L:A32NX_DEVELOPER_STATE", "Bool");
if (!inDeveloperState) {
// Set default pax (0)
Expand All @@ -36,12 +38,32 @@ class A32NX_Boarding {
this.loadCargoZero();
this.loadCargoPayload();
}
*/
}

async fillPaxStation(station, paxToFill) {
const pax = Math.min(paxToFill, station.seats);
const paxDiff = pax - station.pax;
const paxDelta = Math.abs(pax - station.pax);

// bitwise SeatFlags implementation
if (paxDiff >= 0) {
console.log(`paxDiff positive, filling ${paxToFill} pax`);
// TODO FIXME: Fill from desired Flags
const toFill = station.desiredFlags.getFilledSeatIds();
console.log('toFill', toFill.toString());
station.activeFlags.fillSeats(paxDelta, toFill);
console.log('active flags', station.activeFlags.toString());
} else {
console.log('paxDiff negative, emptying');
station.activeFlags.emptyFilledSeats(paxDelta);
}
console.log(`setting L:${station.bitFlags} as ${station.activeFlags.toString()}`);
await SimVar.SetSimVarValue(`L:${station.bitFlags}`, "string", station.activeFlags.toString());
station.pax = pax;
await SimVar.SetSimVarValue(`L:${station.simVar}`, "Number", parseInt(pax));

// TODO REFACTOR: Change this
// await SimVar.SetSimVarValue(`L:${station.simVar}`, "Number", parseInt(pax));
}

async fillCargoStation(station, loadToFill) {
Expand All @@ -55,7 +77,10 @@ class A32NX_Boarding {
async function fillStation(station, percent, paxToFill) {
const pax = Math.min(Math.trunc(percent * paxToFill), station.seats);
station.pax = pax;
await SimVar.SetSimVarValue(`L:${station.simVar}_DESIRED`, "Number", parseInt(pax));
// SeatFlags implementation
station.activeFlags.setFlags(pax);
await SimVar.SetSimVarValue(`L:${station.bitFlags}_DESIRED`, "string", station.activeFlags.toString());
// await SimVar.SetSimVarValue(`L:${station.simVar}_DESIRED`, "Number", parseInt(pax));
paxRemaining -= pax;
}

Expand Down Expand Up @@ -100,21 +125,31 @@ class A32NX_Boarding {
return;
}

const currentPax = Object.values(this.paxStations).map((station) => SimVar.GetSimVarValue(`L:${station.simVar}`, "Number")).reduce((acc, cur) => acc + cur);
const paxTarget = Object.values(this.paxStations).map((station) => SimVar.GetSimVarValue(`L:${station.simVar}_DESIRED`, "Number")).reduce((acc, cur) => acc + cur);
const currentLoad = Object.values(this.cargoStations).map((station) => SimVar.GetSimVarValue(`L:${station.simVar}`, "Number")).reduce((acc, cur) => acc + cur);
const loadTarget = Object.values(this.cargoStations).map((station) => SimVar.GetSimVarValue(`L:${station.simVar}_DESIRED`, "Number")).reduce((acc, cur) => acc + cur);

// SeatFlags Implementation
let currentPax = 0;
let paxTarget = 0;
let isAllPaxStationFilled = true;
for (const _station of Object.values(this.paxStations)) {
const stationCurrentPax = SimVar.GetSimVarValue(`L:${_station.simVar}`, "Number");
const stationCurrentPaxTarget = SimVar.GetSimVarValue(`L:${_station.simVar}_DESIRED`, "Number");
Object.values(this.paxStations).map((station) => {
station.activeFlags.setFlags(SimVar.GetSimVarValue(`L:${station.bitFlags}`, 'Number'));
const stationCurrentPax = station.activeFlags.getTotalFilledSeats();
currentPax += stationCurrentPax;

station.desiredFlags.setFlags(SimVar.GetSimVarValue(`L:${station.bitFlags}_DESIRED`, 'Number'));
const stationCurrentPaxTarget = station.desiredFlags.getTotalFilledSeats();
paxTarget += stationCurrentPaxTarget;

if (stationCurrentPax !== stationCurrentPaxTarget) {
isAllPaxStationFilled = false;
break;
/*
console.log('not pax filled');
console.log('station current passengers', station.name, stationCurrentPax);
console.log('station target passengers', station.name, 'target', stationCurrentPaxTarget);
*/
}
}
});

const currentLoad = Object.values(this.cargoStations).map((station) => SimVar.GetSimVarValue(`L:${station.simVar}`, "Number")).reduce((acc, cur) => acc + cur);
const loadTarget = Object.values(this.cargoStations).map((station) => SimVar.GetSimVarValue(`L:${station.simVar}_DESIRED`, "Number")).reduce((acc, cur) => acc + cur);

let isAllCargoStationFilled = true;
for (const _station of Object.values(this.cargoStations)) {
Expand Down Expand Up @@ -149,6 +184,13 @@ class A32NX_Boarding {
if (currentPax === paxTarget && currentLoad === loadTarget && isAllPaxStationFilled && isAllCargoStationFilled) {
// Finish boarding
this.boardingState = "finished";

// SeatFlags: Balance pax flags
/*
station.desiredFlags.setFlags(station.activeFlags.toNumber());
await SimVar.SetSimVarValue(`L:${station.bitFlags}_DESIRED`, "string", station.activeFlags.toString());
*/

await SimVar.SetSimVarValue("L:A32NX_BOARDING_STARTED_BY_USR", "Bool", false);

} else if ((currentPax < paxTarget) || (currentLoad < loadTarget)) {
Expand All @@ -160,7 +202,12 @@ class A32NX_Boarding {
if (boardingRate == 'INSTANT') {
// Instant
for (const paxStation of Object.values(this.paxStations)) {
const stationCurrentPaxTarget = SimVar.GetSimVarValue(`L:${paxStation.simVar}_DESIRED`, "Number");
// const stationCurrentPaxTarget = SimVar.GetSimVarValue(`L:${paxStation.simVar}_DESIRED`, "Number");

// TODO: Replace with flags
paxStation.desiredFlags.setFlags(SimVar.GetSimVarValue(`L:${paxStation.bitFlags}_DESIRED`, "Number"));
const stationCurrentPaxTarget = paxStation.desiredFlags.getTotalFilledSeats();

await this.fillPaxStation(paxStation, stationCurrentPaxTarget);
}
for (const loadStation of Object.values(this.cargoStations)) {
Expand All @@ -187,8 +234,16 @@ class A32NX_Boarding {

// Stations logic:
for (const paxStation of Object.values(this.paxStations).reverse()) {
const stationCurrentPax = SimVar.GetSimVarValue(`L:${paxStation.simVar}`, "Number");
const stationCurrentPaxTarget = SimVar.GetSimVarValue(`L:${paxStation.simVar}_DESIRED`, "Number");

// TODO REFACTOR: Replace with flags
// const stationCurrentPax = SimVar.GetSimVarValue(`L:${paxStation.simVar}`, "Number");
// const stationCurrentPaxTarget = SimVar.GetSimVarValue(`L:${paxStation.simVar}_DESIRED`, "Number");

paxStation.activeFlags.setFlags(SimVar.GetSimVarValue(`L:${paxStation.bitFlags}`, "Number"));
const stationCurrentPax = paxStation.activeFlags.getTotalFilledSeats();

paxStation.desiredFlags.setFlags(SimVar.GetSimVarValue(`L:${paxStation.bitFlags}_DESIRED`, "Number"));
const stationCurrentPaxTarget = paxStation.desiredFlags.getTotalFilledSeats();

if (stationCurrentPax < stationCurrentPaxTarget) {
this.fillPaxStation(paxStation, stationCurrentPax + 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ class A32NX_PayloadConstructor {
stationIndex: 0 + 1,
position: 21.98,
seatsRange: [1, 36],
simVar: "A32NX_PAX_TOTAL_ROWS_1_6"
simVar: "A32NX_PAX_TOTAL_ROWS_1_6",
bitFlags: "A32NX_PAX_FLAGS_A",
activeFlags: new SeatFlags(SimVar.GetSimVarValue('L:A32NX_PAX_FLAGS_A', 'Number'), 36),
desiredFlags: new SeatFlags(SimVar.GetSimVarValue('L:A32NX_PAX_FLAGS_A_DESIRED', 'Number'), 36),

},
rows7_13: {
name: 'ROWS [7-13]',
Expand All @@ -21,7 +25,10 @@ class A32NX_PayloadConstructor {
stationIndex: 1 + 1,
position: 2.86,
seatsRange: [37, 78],
simVar: "A32NX_PAX_TOTAL_ROWS_7_13"
simVar: "A32NX_PAX_TOTAL_ROWS_7_13",
bitFlags: "A32NX_PAX_FLAGS_B",
activeFlags: new SeatFlags(SimVar.GetSimVarValue('L:A32NX_PAX_FLAGS_B', 'Number'), 42),
desiredFlags: new SeatFlags(SimVar.GetSimVarValue('L:A32NX_PAX_FLAGS_B_DESIRED', 'Number'), 42),
},
rows14_21: {
name: 'ROWS [14-21]',
Expand All @@ -32,7 +39,10 @@ class A32NX_PayloadConstructor {
stationIndex: 2 + 1,
position: -15.34,
seatsRange: [79, 126],
simVar: "A32NX_PAX_TOTAL_ROWS_14_21"
simVar: "A32NX_PAX_TOTAL_ROWS_14_21",
bitFlags: "A32NX_PAX_FLAGS_C",
activeFlags: new SeatFlags(SimVar.GetSimVarValue('L:A32NX_PAX_FLAGS_C', 'Number'), 48),
desiredFlags: new SeatFlags(SimVar.GetSimVarValue('L:A32NX_PAX_FLAGS_C_DESIRED', 'Number'), 48),
},
rows22_29: {
name: 'ROWS [22-29]',
Expand All @@ -43,7 +53,10 @@ class A32NX_PayloadConstructor {
stationIndex: 3 + 1,
position: -32.81,
seatsRange: [127, 174],
simVar: "A32NX_PAX_TOTAL_ROWS_22_29"
simVar: "A32NX_PAX_TOTAL_ROWS_22_29",
bitFlags: "A32NX_PAX_FLAGS_D",
activeFlags: new SeatFlags(SimVar.GetSimVarValue('L:A32NX_PAX_FLAGS_D', 'Number'), 48),
desiredFlags: new SeatFlags(SimVar.GetSimVarValue('L:A32NX_PAX_FLAGS_D_DESIRED', 'Number'), 48),
},
};

Expand Down Expand Up @@ -94,8 +107,8 @@ const cargoStations = payloadConstruct.cargoStations;
const MAX_SEAT_AVAILABLE = 174;

/**
* Calculate %MAC ZWFCG of all stations
*/
* Calculate %MAC ZWFCG of all stations
*/
function getZfwcg() {

const leMacZ = -5.386; // Accurate to 3 decimals, replaces debug weight values
Expand Down
151 changes: 151 additions & 0 deletions flybywire-aircraft-a320-neo/html_ui/Pages/A32NX_Utils/bitFlags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
class BitFlags {
constructor(number) {
this.f64View = new Float64Array(1);
this.u32View = new Uint32Array(this.f64View.buffer);
this.setFlags(number);
}

setFlags(number) {
this.flags = Array.from(this.u32View);
const bigNumberAsBinaryStr = number.toString(2);

let bigNumberAsBinaryStr2 = '';
for (let i = 0; i < 64 - bigNumberAsBinaryStr.length; i++) {
bigNumberAsBinaryStr2 += '0';
}

bigNumberAsBinaryStr2 += bigNumberAsBinaryStr;

this.flags[1] = parseInt(bigNumberAsBinaryStr2.substring(0, 32), 2);
this.flags[0] = parseInt(bigNumberAsBinaryStr2.substring(32), 2);
}

getBitIndex(bit) {
if (bit > 63) {
return false;
}
const f = Math.floor(bit / 31);
const b = bit % 31;

return ((this.flags[f] >> b) & 1) !== 0;
}

toggleBitIndex(bit) {
if (bit > 63) {
return;
}
const f = Math.floor(bit / 31);
const b = bit % 31;

this.flags[f] ^= (1 << b);
}

toDouble() {
return (new Float64Array(Uint32Array.from(this.flags).buffer))[0];
}

toDebug() {
const debug = [];
this.flags.forEach((flag, index) => {
debug.push(flag.toString(2));
const fL = 32 - flag.toString(2).length;
for (let i = 0; i < fL; i++) {
debug[index] = '0'.concat(debug[index]);
}
});
return (`HIGH [ ${debug[1]} | ${debug[0]} ] LOW`);
}

toNumber() {
return this.flags[1] * 2 ** 32 + this.flags[0];
}

toString() {
return this.toNumber().toString();
}

getTotalBits() {
let total = 0;
this.flags.forEach((flag) => {
const n = 32;
let i = 0;
while (i++ < n) {
if ((1 << i & flag) === (1 << i)) {
total++;
}
}
});
return total;
}
}

class SeatFlags extends BitFlags {
constructor(number, totalSeats) {
super(number);
// Limit bits utilisation to < totalSeats
this.totalSeats = totalSeats;
}

getEmptySeatIds() {
const emptySeats = [];
for (let seatId = 0; seatId < this.totalSeats; seatId++) {
if (!this.getBitIndex(seatId)) {
emptySeats.push(seatId);
}
}
return emptySeats;
}

getFilledSeatIds() {
const filledSeats = [];
for (let seatId = 0; seatId < this.totalSeats; seatId++) {
if (this.getBitIndex(seatId)) {
filledSeats.push(seatId);
}
}
return filledSeats;
}

isSeatFilled(seatId) {
if (seatId > this.totalSeats) return false;
return this.getBitIndex(seatId);
}

toggleSeatId(seatId) {
if (seatId > this.totalSeats) return;
this.toggleBitIndex(seatId);
}

fillEmptySeats(numFill) {
this.fillSeats(numFill, this.getEmptySeatIds());
}

fillSeats(numFill, choices) {
for (let i = 0; i < numFill; i++) {
if (choices.length > 0) {
const chosen = ~~(Math.random() * choices.length);
this.toggleSeatId(choices[chosen]);
choices.splice(chosen, 1);
}
}
}

emptyFilledSeats(numEmpty) {
const choices = this.getFilledSeatIds();
for (let i = 0; i < numEmpty; i++) {
if (choices.length > 0) {
const chosen = ~~(Math.random() * choices.length);
this.toggleSeatId(choices[chosen]);
choices.splice(chosen, 1);
}
}
}

getTotalFilledSeats() {
return this.getTotalBits();
}

getTotalEmptySeats() {
return this.totalSeats - this.getTotalBits();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<script type="text/html" import-script="/Pages/A32NX_Utils/NXUnits.js"></script>
<script type="text/html" import-script="/Pages/A32NX_Utils/SimBriefApi.js"></script>
<script type="text/html" import-script="/Pages/A32NX_Utils/arinc429.js"></script>
<script type="text/html" import-script="/Pages/A32NX_Utils/bitFlags.js"></script>
<script type="text/html" import-script="/Pages/A32NX_Core/Adirs.js"></script>
<script type="text/html" import-script="/Pages/A32NX_Core/A32NX_PayloadManager.js"></script>

Expand Down
Loading

0 comments on commit 7f87227

Please sign in to comment.