ZFW Target Set
This commit is contained in:
parent
9224300c85
commit
ee46d0bff1
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "tfdidesign-md11-load-manager",
|
||||
"version": "0.1.15",
|
||||
"version": "0.1.17",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
|
||||
@ -1,104 +1,40 @@
|
||||
import { FC, StrictMode, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import Freight from './components/freight/Freight';
|
||||
import { FC, StrictMode, useCallback, useEffect, useState } from 'react';
|
||||
import Pax from './components/pax/Pax';
|
||||
import { PayloadFreight, calculateCGsFreight, getWeightsFreight } from './configs/freighter';
|
||||
import { PaxConfig, PayloadPax } from './configs/pax';
|
||||
import { Fuel, getFuel, initialFuel, initialPayload } from './configs/shared';
|
||||
import { COHERENT_COMBUS_WASM_CALL, COMM_BUS_LIVE_DATA_EVENT, TFDI_SIMBRIEF_USERNAME_EVENT } from './constants';
|
||||
import { WASMDataPax } from './types/WASMData';
|
||||
|
||||
interface IAppProps {
|
||||
commBus: ViewListener.ViewListener;
|
||||
}
|
||||
|
||||
const App: FC<IAppProps> = ({ commBus }) => {
|
||||
// Inferred
|
||||
const [unit, setUnit] = useState<'lbs' | 'kg'>('lbs');
|
||||
const [isCargo, setIsCargo] = useState(false);
|
||||
const [isER, setIsER] = useState(false);
|
||||
const [SBUsername, setSBUsername] = useState<string>();
|
||||
|
||||
// From sim
|
||||
const [payloadLive, setPayloadLive] = useState<PayloadPax | PayloadFreight>(initialPayload);
|
||||
const [fuel, setFuel] = useState<Fuel>(initialFuel);
|
||||
const [GSXPaxNum, setGSXPaxNum] = useState(0);
|
||||
const [GSXCargoPercent, setGSXCargoPercent] = useState(0);
|
||||
const [GSXState, setGSXState] = useState<'boarding' | 'deboarding' | 'idle'>('idle');
|
||||
|
||||
// Calculated
|
||||
const [CGs, setCGs] = useState<[number, number]>([0, 0]);
|
||||
|
||||
//FIXME: TS Type
|
||||
const [WASMData, setWASMData] = useState<WASMDataPax>();
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
|
||||
const requestRef = useRef<number | undefined>(undefined);
|
||||
|
||||
// Main Loop for Live Payload
|
||||
const mainLoop = () => {
|
||||
try {
|
||||
if (SimVar.IsReady()) {
|
||||
setIsER(SimVar.GetSimVarValue('L:MD11_OPT_ER', 'bool'));
|
||||
setIsCargo(SimVar.GetSimVarValue('L:MD11_EFB_IS_CARGO', 'bool'));
|
||||
setUnit((SimVar.GetSimVarValue('L:MD11_EFB_OPTIONS_GENERAL', 'number') & 1) << 0 ? 'lbs' : 'kg');
|
||||
|
||||
// GSX
|
||||
const boardingState = SimVar.GetSimVarValue('L:FSDT_GSX_BOARDING_STATE', 'number');
|
||||
const deboardingState = SimVar.GetSimVarValue('L:FSDT_GSX_DEBOARDING_STATE', 'number');
|
||||
setGSXState(boardingState === 5 ? 'boarding' : deboardingState === 5 ? 'deboarding' : 'idle');
|
||||
setGSXPaxNum(
|
||||
boardingState === 5
|
||||
? SimVar.GetSimVarValue('L:FSDT_GSX_NUMPASSENGERS_BOARDING_TOTAL', 'number')
|
||||
: deboardingState === 5
|
||||
? SimVar.GetSimVarValue('L:FSDT_GSX_NUMPASSENGERS_DEBOARDING_TOTAL', 'number')
|
||||
: 0
|
||||
);
|
||||
setGSXCargoPercent(
|
||||
boardingState === 5
|
||||
? SimVar.GetSimVarValue('L:FSDT_GSX_BOARDING_CARGO_PERCENT', 'number')
|
||||
: deboardingState === 5
|
||||
? 100 - SimVar.GetSimVarValue('L:FSDT_GSX_DEBOARDING_CARGO_PERCENT', 'number')
|
||||
: 0
|
||||
);
|
||||
|
||||
const payload = isCargo ? getWeightsFreight(unit) : PaxConfig.getWeights(unit);
|
||||
const _fuel = getFuel(unit);
|
||||
|
||||
setCGs(
|
||||
isCargo
|
||||
? calculateCGsFreight(payload as PayloadFreight, _fuel)
|
||||
: PaxConfig.calculateCGs(payload as PayloadPax, _fuel)
|
||||
);
|
||||
setPayloadLive(payload);
|
||||
setFuel(_fuel);
|
||||
}
|
||||
} catch {}
|
||||
|
||||
requestRef.current = requestAnimationFrame(mainLoop);
|
||||
};
|
||||
useEffect(() => {
|
||||
requestRef.current = requestAnimationFrame(mainLoop);
|
||||
|
||||
if (requestRef.current !== undefined) return () => cancelAnimationFrame(requestRef.current as number);
|
||||
}, [unit, isCargo]);
|
||||
|
||||
// CommBus
|
||||
const usernameCallback = useCallback((username: string) => {
|
||||
setSBUsername(username);
|
||||
setIsReady(true);
|
||||
}, []);
|
||||
const wasmCallback = useCallback((data: any) => {
|
||||
console.log('WASM DATA', JSON.parse(data));
|
||||
const wasmCallback = useCallback((data: string) => {
|
||||
setWASMData(JSON.parse(data));
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
console.log('Initializing CommBus');
|
||||
|
||||
commBus.on('receiveSimBriefUsername', usernameCallback);
|
||||
commBus.on('khofmann_tfdi_md-11_load_manager_live_data', wasmCallback);
|
||||
commBus.on(COMM_BUS_LIVE_DATA_EVENT, usernameCallback);
|
||||
commBus.on(COMM_BUS_LIVE_DATA_EVENT, wasmCallback);
|
||||
|
||||
setTimeout(() => {
|
||||
Coherent.call('COMM_BUS_WASM_CALLBACK', 'requestSimBriefUsername', 'null');
|
||||
Coherent.call(COHERENT_COMBUS_WASM_CALL, TFDI_SIMBRIEF_USERNAME_EVENT, 'null');
|
||||
}, 1000);
|
||||
|
||||
return () => {
|
||||
commBus.off('receiveSimBriefUsername', usernameCallback);
|
||||
commBus.off('khofmann_tfdi_md-11_load_manager_live_data', wasmCallback);
|
||||
commBus.off(COMM_BUS_LIVE_DATA_EVENT, wasmCallback);
|
||||
};
|
||||
}, []);
|
||||
|
||||
@ -106,21 +42,11 @@ const App: FC<IAppProps> = ({ commBus }) => {
|
||||
<StrictMode>
|
||||
<div className="flex w-full justify-center pt-2 bg-zinc-900">
|
||||
<div className="flex w-3/4 flex-col items-center">
|
||||
{isReady ? (
|
||||
isCargo ? (
|
||||
<Freight isER={isER} unit={unit} OEW={payloadLive.empty} CGs={CGs} />
|
||||
{isReady && WASMData ? (
|
||||
WASMData.userData.isCargo ? (
|
||||
<>Not yet Implemented</>
|
||||
) : (
|
||||
<Pax
|
||||
isER={isER}
|
||||
unit={unit}
|
||||
CGs={CGs}
|
||||
fuelLive={fuel}
|
||||
payloadLive={payloadLive as PayloadPax}
|
||||
username={SBUsername}
|
||||
GSXPaxNum={GSXPaxNum}
|
||||
GSXCargoPercent={GSXCargoPercent}
|
||||
GSXState={GSXState}
|
||||
/>
|
||||
<Pax WASMData={WASMData} username={SBUsername} />
|
||||
)
|
||||
) : (
|
||||
<h1 className="text-sm font-medium">LOADING</h1>
|
||||
|
||||
@ -1,92 +0,0 @@
|
||||
import { FC, useState } from 'react';
|
||||
import { PayloadFreight } from '../../configs/freighter';
|
||||
import { initialPayload, SharedConfig } from '../../configs/shared';
|
||||
import Profile from '../profile/Profile';
|
||||
import Tabbar from '../tabbar/Tabbar';
|
||||
|
||||
interface FreightProps {
|
||||
isER: boolean;
|
||||
unit: 'kg' | 'lbs';
|
||||
OEW: number;
|
||||
CGs: [number, number];
|
||||
}
|
||||
|
||||
const Freight: FC<FreightProps> = ({ isER, unit, OEW, CGs }) => {
|
||||
const [selectedTab, setSelectedTab] = useState(0);
|
||||
const [payload, setPayload] = useState<PayloadFreight>(initialPayload);
|
||||
const [inPreview, setInPreview] = useState(true);
|
||||
|
||||
const upper1 = () => {
|
||||
return Math.round(payload.upper1Left + payload.upper1Right);
|
||||
};
|
||||
const upper2 = () => {
|
||||
return Math.round(payload.upper2Left + payload.upper2Right);
|
||||
};
|
||||
const upper3 = () => {
|
||||
return Math.round(payload.upper3Left + payload.upper3Right);
|
||||
};
|
||||
const upper4 = () => {
|
||||
return Math.round(payload.upper4Left + payload.upper4Right);
|
||||
};
|
||||
const lower1 = () => {
|
||||
return Math.round(payload.lowerForward);
|
||||
};
|
||||
const lower2 = () => {
|
||||
return Math.round(payload.lowerRear);
|
||||
};
|
||||
const _OEW = () => {
|
||||
return Math.round(OEW + (isER ? SharedConfig.erExtraWeight[unit] * 2 : 1));
|
||||
};
|
||||
const crew = () => {
|
||||
return Math.round(payload.pilot + payload.firstOfficer + payload.engineer);
|
||||
};
|
||||
const cgs = (): [string, string] => {
|
||||
return [CGs[0].toFixed(1), CGs[1].toFixed(1)];
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Profile
|
||||
type="F"
|
||||
isER={isER}
|
||||
upper1={`${upper1()}`}
|
||||
upper2={`${upper2()}`}
|
||||
upper3={`${upper3()}`}
|
||||
upper4={`${upper4()}`}
|
||||
lower1={`${lower1()}`}
|
||||
lower2={`${lower2()}`}
|
||||
OEW={`${_OEW()}`}
|
||||
crew={`${crew()}`}
|
||||
unit={unit.toUpperCase()}
|
||||
inPreview={inPreview}
|
||||
CGs={cgs()}
|
||||
/>
|
||||
<Tabbar tabs={['Simbrief', 'ZFW', 'Cargo']} selectedTab={selectedTab} setSelectedTab={setSelectedTab} />
|
||||
|
||||
<div className="relative flex w-full items-center justify-start gap-x-6">
|
||||
<button
|
||||
className="middle none center rounded-lg bg-green-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-green-500/20 transition-all hover:shadow-lg hover:shadow-green-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||
data-ripple-light="true"
|
||||
onClick={() => {
|
||||
console.log('TODO: SET PAYLOAD IN SIM');
|
||||
setInPreview(false);
|
||||
}}
|
||||
>
|
||||
Load
|
||||
</button>
|
||||
<button
|
||||
className="middle none center rounded-lg bg-red-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-red-500/20 transition-all hover:shadow-lg hover:shadow-red-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||
data-ripple-light="true"
|
||||
onClick={() => {
|
||||
console.log('TODO: CLEAR PAYLOAD IN SIM');
|
||||
setInPreview(true);
|
||||
}}
|
||||
>
|
||||
Unload
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Freight;
|
||||
@ -1,167 +1,97 @@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { PaxConfig, PayloadPax } from '../../configs/pax';
|
||||
import { Fuel, initialPayload, SharedConfig } from '../../configs/shared';
|
||||
import { FC, useState } from 'react';
|
||||
import { WASMDataPax } from '../../types/WASMData';
|
||||
import Profile from '../profile/Profile';
|
||||
import SBEntryPax from '../SBEntry/SBEntryPax';
|
||||
import StationEntryPax from '../stationEntry/StationEntryPax';
|
||||
import Tabbar from '../tabbar/Tabbar';
|
||||
import ZFWEntryPax from '../zfwEntry/ZFWEntryPax';
|
||||
|
||||
interface PaxProps {
|
||||
isER: boolean;
|
||||
unit: 'kg' | 'lbs';
|
||||
CGs: [number, number];
|
||||
payloadLive: PayloadPax;
|
||||
fuelLive: Fuel;
|
||||
WASMData: WASMDataPax;
|
||||
username?: string;
|
||||
GSXPaxNum: number;
|
||||
GSXCargoPercent: number;
|
||||
GSXState: 'boarding' | 'deboarding' | 'idle';
|
||||
}
|
||||
|
||||
const Pax: FC<PaxProps> = ({
|
||||
isER,
|
||||
unit,
|
||||
CGs,
|
||||
fuelLive,
|
||||
payloadLive,
|
||||
username,
|
||||
GSXPaxNum,
|
||||
GSXCargoPercent,
|
||||
GSXState,
|
||||
}) => {
|
||||
const Pax: FC<PaxProps> = ({ WASMData, username }) => {
|
||||
const [selectedTab, setSelectedTab] = useState(0);
|
||||
const [payload, setPayload] = useState<PayloadPax>(initialPayload);
|
||||
const [loadingState, setLoadingState] = useState<'preview' | 'accepted' | 'loaded'>('preview');
|
||||
|
||||
const upper1 = (overrideState: 'preview' | 'accepted' | 'loaded' = loadingState) => {
|
||||
if (overrideState !== 'loaded')
|
||||
return PaxConfig.weightToPax(payload.business1Left + payload.business1Center + payload.business1Right, unit);
|
||||
if (overrideState !== 'loaded') return WASMData.targetPayload.business1;
|
||||
|
||||
return PaxConfig.weightToPax(
|
||||
payloadLive.business1Left + payloadLive.business1Center + payloadLive.business1Right,
|
||||
unit
|
||||
);
|
||||
return WASMData.livePayload.business1;
|
||||
};
|
||||
const upper2 = (overrideState: 'preview' | 'accepted' | 'loaded' = loadingState) => {
|
||||
if (overrideState !== 'loaded')
|
||||
return PaxConfig.weightToPax(payload.business2Left + payload.business2Center + payload.business2Right, unit);
|
||||
if (overrideState !== 'loaded') return WASMData.targetPayload.business2;
|
||||
|
||||
return PaxConfig.weightToPax(
|
||||
payloadLive.business2Left + payloadLive.business2Center + payloadLive.business2Right,
|
||||
unit
|
||||
);
|
||||
return WASMData.livePayload.business2;
|
||||
};
|
||||
const upper3 = (overrideState: 'preview' | 'accepted' | 'loaded' = loadingState) => {
|
||||
if (overrideState !== 'loaded')
|
||||
return PaxConfig.weightToPax(payload.economy1Left + payload.economy1Center + payload.economy1Right, unit);
|
||||
if (overrideState !== 'loaded') return WASMData.targetPayload.economy1;
|
||||
|
||||
return PaxConfig.weightToPax(
|
||||
payloadLive.economy1Left + payloadLive.economy1Center + payloadLive.economy1Right,
|
||||
unit
|
||||
);
|
||||
return WASMData.livePayload.economy1;
|
||||
};
|
||||
const upper4 = (overrideState: 'preview' | 'accepted' | 'loaded' = loadingState) => {
|
||||
if (overrideState !== 'loaded')
|
||||
return PaxConfig.weightToPax(payload.economy2Left + payload.economy2Center + payload.economy2Right, unit);
|
||||
if (overrideState !== 'loaded') return WASMData.targetPayload.economy2;
|
||||
|
||||
return PaxConfig.weightToPax(
|
||||
payloadLive.economy2Left + payloadLive.economy2Center + payloadLive.economy2Right,
|
||||
unit
|
||||
);
|
||||
return WASMData.livePayload.economy2;
|
||||
};
|
||||
const lower1 = () => {
|
||||
if (loadingState !== 'loaded') return Math.round(payload.forwardCargo);
|
||||
if (loadingState !== 'loaded') return Math.round(WASMData.targetPayload.forwardCargo);
|
||||
|
||||
return Math.round(payloadLive.forwardCargo);
|
||||
return Math.round(WASMData.livePayload.forwardCargo);
|
||||
};
|
||||
const lower2 = () => {
|
||||
if (loadingState !== 'loaded') return Math.round(payload.rearCargo);
|
||||
if (loadingState !== 'loaded') return Math.round(WASMData.targetPayload.rearCargo);
|
||||
|
||||
return Math.round(payloadLive.rearCargo);
|
||||
return Math.round(WASMData.livePayload.rearCargo);
|
||||
};
|
||||
const _OEW = () => {
|
||||
if (loadingState !== 'loaded')
|
||||
return Math.round(payloadLive.empty + (isER ? SharedConfig.erExtraWeight[unit] * 2 : 1));
|
||||
const OEW = () => {
|
||||
if (loadingState !== 'loaded') return Math.round(WASMData.targetPayload.empty);
|
||||
|
||||
return Math.round(payloadLive.empty + payloadLive.leftAuxPax + payloadLive.rightAuxPax);
|
||||
return Math.round(WASMData.livePayload.empty);
|
||||
};
|
||||
const crew = () => {
|
||||
if (loadingState !== 'loaded') return PaxConfig.weights.base[unit].total;
|
||||
if (loadingState !== 'loaded') return Math.round(WASMData.targetPayload.crew);
|
||||
|
||||
return Math.round(
|
||||
payloadLive.cabinCrewFront +
|
||||
payloadLive.cabinCrewRear +
|
||||
payloadLive.pilot +
|
||||
payloadLive.firstOfficer +
|
||||
payloadLive.engineer
|
||||
);
|
||||
return Math.round(WASMData.livePayload.crew);
|
||||
};
|
||||
|
||||
const _CGs = (): [string, boolean, string, boolean] => {
|
||||
const CGs = (): [string, boolean, string, boolean] => {
|
||||
if (loadingState !== 'loaded') {
|
||||
const __CGs = PaxConfig.calculateCGs(
|
||||
{
|
||||
...payload,
|
||||
empty: payloadLive.empty,
|
||||
cabinCrewFront: PaxConfig.weights.base[unit].cabinCrewFront,
|
||||
cabinCrewRear: PaxConfig.weights.base[unit].cabinCrewRear,
|
||||
pilot: PaxConfig.weights.base[unit].pilot,
|
||||
firstOfficer: PaxConfig.weights.base[unit].firstOfficer,
|
||||
engineer: PaxConfig.weights.base[unit].engineer,
|
||||
leftAuxPax: isER ? SharedConfig.erExtraWeight[unit] : 0,
|
||||
rightAuxPax: isER ? SharedConfig.erExtraWeight[unit] : 0,
|
||||
},
|
||||
fuelLive
|
||||
);
|
||||
return [
|
||||
__CGs[0].toFixed(1),
|
||||
__CGs[0] < SharedConfig.CGLimits.min || __CGs[0] > SharedConfig.CGLimits.max,
|
||||
__CGs[1].toFixed(1),
|
||||
__CGs[1] < SharedConfig.CGLimits.min || __CGs[1] > SharedConfig.CGLimits.max,
|
||||
WASMData.targetPayload.ZFWCG.toFixed(1),
|
||||
WASMData.targetPayload.ZFWCG < WASMData.limits.minCG || WASMData.targetPayload.ZFWCG > WASMData.limits.maxCG,
|
||||
WASMData.targetPayload.TOCG.toFixed(1),
|
||||
WASMData.targetPayload.TOCG < WASMData.limits.minCG || WASMData.targetPayload.TOCG > WASMData.limits.maxCG,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
CGs[0].toFixed(1),
|
||||
CGs[0] < SharedConfig.CGLimits.min || CGs[0] > SharedConfig.CGLimits.max,
|
||||
CGs[1].toFixed(1),
|
||||
CGs[1] < SharedConfig.CGLimits.min || CGs[1] > SharedConfig.CGLimits.max,
|
||||
WASMData.livePayload.ZFWCG.toFixed(1),
|
||||
WASMData.livePayload.ZFWCG < WASMData.limits.minCG || WASMData.livePayload.ZFWCG > WASMData.limits.maxCG,
|
||||
WASMData.livePayload.TOCG.toFixed(1),
|
||||
WASMData.livePayload.TOCG < WASMData.limits.minCG || WASMData.livePayload.TOCG > WASMData.limits.maxCG,
|
||||
];
|
||||
};
|
||||
|
||||
//TODO: Make GSX optional
|
||||
useEffect(() => {
|
||||
if (GSXState === 'idle') return;
|
||||
|
||||
PaxConfig.setWeightsProgressive(
|
||||
payload,
|
||||
GSXState === 'boarding' ? GSXPaxNum : payload.paxCount.total - GSXPaxNum,
|
||||
GSXCargoPercent,
|
||||
unit
|
||||
);
|
||||
}, [GSXPaxNum, GSXCargoPercent, GSXState]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Profile
|
||||
type="PAX"
|
||||
isER={isER}
|
||||
isER={WASMData.userData.isER}
|
||||
upper1={`${upper1()}`}
|
||||
upper1max={loadingState === 'loaded' ? `${upper1('preview')}` : `${PaxConfig.stationMax.business1}`}
|
||||
upper1max={loadingState === 'loaded' ? `${upper1('preview')}` : `${WASMData.limits.business1}`}
|
||||
upper2={`${upper2()}`}
|
||||
upper2max={loadingState === 'loaded' ? `${upper2('preview')}` : `${PaxConfig.stationMax.business2}`}
|
||||
upper2max={loadingState === 'loaded' ? `${upper2('preview')}` : `${WASMData.limits.business2}`}
|
||||
upper3={`${upper3()}`}
|
||||
upper3max={loadingState === 'loaded' ? `${upper3('preview')}` : `${PaxConfig.stationMax.economy1}`}
|
||||
upper3max={loadingState === 'loaded' ? `${upper3('preview')}` : `${WASMData.limits.economy1}`}
|
||||
upper4={`${upper4()}`}
|
||||
upper4max={loadingState === 'loaded' ? `${upper4('preview')}` : `${PaxConfig.stationMax.economy2}`}
|
||||
upper4max={loadingState === 'loaded' ? `${upper4('preview')}` : `${WASMData.limits.economy2}`}
|
||||
lower1={`${lower1()}`}
|
||||
lower2={`${lower2()}`}
|
||||
OEW={`${_OEW()}`}
|
||||
OEW={`${OEW()}`}
|
||||
crew={`${crew()}`}
|
||||
unit={unit.toUpperCase()}
|
||||
unit={WASMData.userData.isImperial ? 'LBS' : 'KG'}
|
||||
inPreview={loadingState !== 'loaded'}
|
||||
CGs={_CGs()}
|
||||
CGs={CGs()}
|
||||
/>
|
||||
<Tabbar
|
||||
tabs={
|
||||
@ -171,6 +101,7 @@ const Pax: FC<PaxProps> = ({
|
||||
setSelectedTab={setSelectedTab}
|
||||
/>
|
||||
|
||||
{/*
|
||||
{username && selectedTab === 0 && (
|
||||
<SBEntryPax
|
||||
unit={unit}
|
||||
@ -190,26 +121,18 @@ const Pax: FC<PaxProps> = ({
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
*/}
|
||||
{((username && selectedTab === 1) || (!username && selectedTab === 0)) && (
|
||||
<ZFWEntryPax
|
||||
unit={unit}
|
||||
isER={isER}
|
||||
initialPayload={payload}
|
||||
fuelLive={fuelLive}
|
||||
payloadLive={payloadLive}
|
||||
WASMData={WASMData}
|
||||
loadingState={loadingState}
|
||||
setLoadingState={setLoadingState}
|
||||
updateView={(_payload) => {
|
||||
setPayload(_payload);
|
||||
}}
|
||||
loadAircraft={() => {
|
||||
PaxConfig.setBaseWeight(unit, isER);
|
||||
PaxConfig.setWeights(payload, unit);
|
||||
console.log('SET WEIGHT');
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/*
|
||||
{((username && selectedTab === 2) || (!username && selectedTab === 1)) && (
|
||||
<StationEntryPax
|
||||
unit={unit}
|
||||
@ -228,6 +151,7 @@ const Pax: FC<PaxProps> = ({
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
*/}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,106 +1,36 @@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { PaxConfig, PayloadPax } from '../../configs/pax';
|
||||
import { Fuel, SharedConfig } from '../../configs/shared';
|
||||
import { emptyAircraft, SharedConfig } from '../../configs/shared';
|
||||
import { COHERENT_COMBUS_WASM_CALL, COMM_BUS_UPDATE_TARGET_EVENT } from '../../constants';
|
||||
import { WASMDataPax } from '../../types/WASMData';
|
||||
import CGSelect from '../CGSelect/CGSelect';
|
||||
import ActionBar from '../actionbar/ActionBar';
|
||||
|
||||
interface StationEntryProps {
|
||||
unit: 'kg' | 'lbs';
|
||||
isER: boolean;
|
||||
initialPayload: PayloadPax;
|
||||
fuelLive: Fuel;
|
||||
payloadLive: PayloadPax;
|
||||
WASMData: WASMDataPax;
|
||||
loadingState: 'preview' | 'accepted' | 'loaded';
|
||||
setLoadingState: (newState: StationEntryProps['loadingState']) => void;
|
||||
updateView: (payload: PayloadPax) => void;
|
||||
loadAircraft: () => void;
|
||||
}
|
||||
|
||||
const ZFWEntryPax: FC<StationEntryProps> = ({
|
||||
unit,
|
||||
isER,
|
||||
initialPayload,
|
||||
fuelLive,
|
||||
payloadLive,
|
||||
loadingState,
|
||||
setLoadingState,
|
||||
updateView,
|
||||
loadAircraft,
|
||||
}) => {
|
||||
const [targetZFWCG, setTargetZFWCG] = useState(SharedConfig.CGLimits.default);
|
||||
const [fuel, setFuel] = useState(
|
||||
Math.round(
|
||||
fuelLive.main1 +
|
||||
fuelLive.main1Tip +
|
||||
fuelLive.main2 +
|
||||
fuelLive.main3 +
|
||||
fuelLive.main3Tip +
|
||||
fuelLive.upperAux +
|
||||
fuelLive.lowerAux +
|
||||
fuelLive.tail +
|
||||
fuelLive.forwardAux1 +
|
||||
fuelLive.forwardAux2
|
||||
)
|
||||
);
|
||||
const [ZFW, setZFW] = useState(
|
||||
Math.round(
|
||||
PaxConfig.weights.base[unit].total +
|
||||
(isER ? SharedConfig.erExtraWeight[unit] * 2 : 0) +
|
||||
payloadLive.empty +
|
||||
initialPayload.business1Left +
|
||||
initialPayload.business1Center +
|
||||
initialPayload.business1Right +
|
||||
initialPayload.business2Left +
|
||||
initialPayload.business2Center +
|
||||
initialPayload.business2Right +
|
||||
initialPayload.economy1Left +
|
||||
initialPayload.economy1Center +
|
||||
initialPayload.economy1Right +
|
||||
initialPayload.economy2Left +
|
||||
initialPayload.economy2Center +
|
||||
initialPayload.economy2Right +
|
||||
initialPayload.forwardCargo +
|
||||
initialPayload.rearCargo
|
||||
)
|
||||
);
|
||||
const ZFWEntryPax: FC<StationEntryProps> = ({ WASMData, loadingState, setLoadingState, loadAircraft }) => {
|
||||
const [targetZFWCG, setTargetZFWCG] = useState(WASMData.targetPayload.ZFWCG);
|
||||
const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel));
|
||||
const [ZFW, setZFW] = useState(Math.round(Math.max(WASMData.limits.minZFW, WASMData.targetPayload.total)));
|
||||
|
||||
const _ZFW = () => {
|
||||
if (loadingState !== 'loaded') return ZFW;
|
||||
|
||||
return Math.round(
|
||||
payloadLive.empty +
|
||||
payloadLive.pilot +
|
||||
payloadLive.firstOfficer +
|
||||
payloadLive.engineer +
|
||||
payloadLive.cabinCrewFront +
|
||||
payloadLive.business1Left +
|
||||
payloadLive.business1Center +
|
||||
payloadLive.business1Right +
|
||||
payloadLive.business2Left +
|
||||
payloadLive.business2Center +
|
||||
payloadLive.business2Right +
|
||||
payloadLive.economy1Left +
|
||||
payloadLive.economy1Center +
|
||||
payloadLive.economy1Right +
|
||||
payloadLive.economy2Left +
|
||||
payloadLive.economy2Center +
|
||||
payloadLive.economy2Right +
|
||||
payloadLive.cabinCrewRear +
|
||||
payloadLive.forwardCargo +
|
||||
payloadLive.rearCargo +
|
||||
payloadLive.leftAuxPax +
|
||||
payloadLive.rightAuxPax
|
||||
);
|
||||
return Math.round(WASMData.livePayload.total);
|
||||
};
|
||||
const ZFWValid = () => {
|
||||
return _ZFW() <= PaxConfig.maxZWF[unit];
|
||||
return _ZFW() <= WASMData.limits.maxZFW;
|
||||
};
|
||||
|
||||
const GW = () => {
|
||||
return fuel + _ZFW();
|
||||
};
|
||||
const GWValid = () => {
|
||||
return GW() <= (isER ? SharedConfig.maxTOW.er[unit] : SharedConfig.maxTOW.norm[unit]);
|
||||
return GW() <= WASMData.limits.maxTOW;
|
||||
};
|
||||
|
||||
const handleInput = (input: string, maxValue: number, setter: (value: number) => void) => {
|
||||
@ -121,20 +51,13 @@ const ZFWEntryPax: FC<StationEntryProps> = ({
|
||||
|
||||
const converted = parseInt(input);
|
||||
if (converted) {
|
||||
if (converted < 0)
|
||||
setZFW(
|
||||
Math.round(
|
||||
PaxConfig.weights.base[unit].total + (isER ? SharedConfig.erExtraWeight[unit] * 2 : 0) + payloadLive.empty
|
||||
)
|
||||
);
|
||||
else if (converted > PaxConfig.maxZWF[unit]) setZFW(PaxConfig.maxZWF[unit]);
|
||||
if (converted < 0) setZFW(Math.round(WASMData.targetPayload.empty + WASMData.targetPayload.crew));
|
||||
else if (converted > WASMData.limits.maxZFW) setZFW(WASMData.limits.maxZFW);
|
||||
else setZFW(converted);
|
||||
}
|
||||
};
|
||||
const handleBlur = (input: string) => {
|
||||
const minZFW = Math.round(
|
||||
PaxConfig.weights.base[unit].total + (isER ? SharedConfig.erExtraWeight[unit] * 2 : 0) + payloadLive.empty
|
||||
);
|
||||
const minZFW = Math.round(WASMData.targetPayload.empty + WASMData.targetPayload.crew);
|
||||
|
||||
if (!input) {
|
||||
setZFW(minZFW);
|
||||
@ -144,30 +67,39 @@ const ZFWEntryPax: FC<StationEntryProps> = ({
|
||||
const converted = parseInt(input);
|
||||
if (converted) {
|
||||
if (converted < minZFW) setZFW(minZFW);
|
||||
else if (converted > PaxConfig.maxZWF[unit]) setZFW(PaxConfig.maxZWF[unit]);
|
||||
else if (converted > WASMData.limits.maxZFW) setZFW(WASMData.limits.maxZFW);
|
||||
else setZFW(converted);
|
||||
}
|
||||
|
||||
updateView(PaxConfig.distribute(converted, targetZFWCG, payloadLive.empty, fuelLive, unit, isER));
|
||||
updateData(converted);
|
||||
};
|
||||
|
||||
useEffect(
|
||||
() =>
|
||||
setFuel((prev) =>
|
||||
prev > (isER ? SharedConfig.maxFuel.er[unit] : SharedConfig.maxFuel.norm[unit])
|
||||
? isER
|
||||
? SharedConfig.maxFuel.er[unit]
|
||||
: SharedConfig.maxFuel.norm[unit]
|
||||
: prev
|
||||
),
|
||||
[isER]
|
||||
setFuel((prev) => {
|
||||
if (prev > WASMData.limits.maxFuel) return WASMData.limits.maxFuel;
|
||||
return prev;
|
||||
}),
|
||||
[WASMData.userData.isER]
|
||||
);
|
||||
|
||||
const updateData = (ZFWTarget?: number, CGTarget?: number) => {
|
||||
Coherent.call(
|
||||
COHERENT_COMBUS_WASM_CALL,
|
||||
COMM_BUS_UPDATE_TARGET_EVENT,
|
||||
JSON.stringify({
|
||||
mode: 1,
|
||||
ZFWTarget: ZFWTarget ?? ZFW,
|
||||
CGTarget: CGTarget ?? targetZFWCG,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||
<div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
|
||||
<label>Target ZFW ({unit})</label>
|
||||
<label>Target ZFW ({WASMData.userData.isImperial ? 'lbs' : 'kg'})</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
@ -188,14 +120,14 @@ const ZFWEntryPax: FC<StationEntryProps> = ({
|
||||
increase={() =>
|
||||
setTargetZFWCG((prev) => {
|
||||
const _new = prev + 0.1;
|
||||
updateView(PaxConfig.distribute(ZFW, _new, payloadLive.empty, fuelLive, unit, isER));
|
||||
updateData(undefined, _new);
|
||||
return _new;
|
||||
})
|
||||
}
|
||||
decrease={() =>
|
||||
setTargetZFWCG((prev) => {
|
||||
const _new = prev - 0.1;
|
||||
updateView(PaxConfig.distribute(ZFW, _new, payloadLive.empty, fuelLive, unit, isER));
|
||||
updateData(undefined, _new);
|
||||
return _new;
|
||||
})
|
||||
}
|
||||
@ -205,29 +137,27 @@ const ZFWEntryPax: FC<StationEntryProps> = ({
|
||||
|
||||
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||
<div className="relative flex w-full items-center justify-between rounded-md bg-zinc-600 p-2 px-4">
|
||||
<label>Fuel ({unit})</label>
|
||||
<label>Fuel ({WASMData.userData.isImperial ? 'lbs' : 'kg'})</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className={`w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right`}
|
||||
value={fuel}
|
||||
onChange={(e) =>
|
||||
handleInput(
|
||||
e.target.value,
|
||||
isER ? SharedConfig.maxFuel.er[unit] : SharedConfig.maxFuel.norm[unit],
|
||||
setFuel
|
||||
)
|
||||
}
|
||||
onChange={(e) => handleInput(e.target.value, WASMData.limits.maxFuel, setFuel)}
|
||||
disabled={loadingState !== 'preview'}
|
||||
/>
|
||||
<button
|
||||
className="middle none center rounded-lg bg-green-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-green-500/20 transition-all hover:shadow-lg hover:shadow-green-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||
data-ripple-light="true"
|
||||
onClick={() => {
|
||||
SimVar.SetSimVarValue('L:MD11_EFB_PAYLOAD_FUEL', 'lbs', unit === 'kg' ? fuel * 2.20462262185 : fuel);
|
||||
SimVar.SetSimVarValue(
|
||||
'L:MD11_EFB_PAYLOAD_FUEL',
|
||||
'lbs',
|
||||
WASMData.userData.isImperial ? fuel : fuel * 2.20462262185
|
||||
);
|
||||
SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true);
|
||||
}}
|
||||
disabled={loadingState !== 'preview'}
|
||||
disabled={loadingState !== 'preview' || fuel === Math.round(WASMData.livePayload.fuel)}
|
||||
>
|
||||
Load Fuel
|
||||
</button>
|
||||
@ -237,7 +167,7 @@ const ZFWEntryPax: FC<StationEntryProps> = ({
|
||||
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||
<div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
|
||||
<label>
|
||||
{loadingState !== 'loaded' ? 'Expected' : 'Actual'} ZFW ({unit})
|
||||
{loadingState !== 'loaded' ? 'Expected' : 'Actual'} ZFW ({WASMData.userData.isImperial ? 'lbs' : 'kg'})
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
@ -249,7 +179,7 @@ const ZFWEntryPax: FC<StationEntryProps> = ({
|
||||
</div>
|
||||
<div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-700 p-2 px-4">
|
||||
<label>
|
||||
{loadingState !== 'loaded' ? 'Expected' : 'Actual'} GW ({unit})
|
||||
{loadingState !== 'loaded' ? 'Expected' : 'Actual'} GW ({WASMData.userData.isImperial ? 'lbs' : 'kg'})
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
@ -274,7 +204,7 @@ const ZFWEntryPax: FC<StationEntryProps> = ({
|
||||
unload={() => {
|
||||
setLoadingState('preview');
|
||||
|
||||
PaxConfig.unload(unit, isER);
|
||||
emptyAircraft();
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { COHERENT_COMBUS_WASM_CALL, COMM_BUS_LIVE_DATA_EVENT } from '../constants';
|
||||
|
||||
export interface Fuel {
|
||||
main1: number;
|
||||
main3: number;
|
||||
@ -164,3 +166,13 @@ export const getFuel = (unit: 'kg' | 'lbs') => {
|
||||
|
||||
return fuel;
|
||||
};
|
||||
|
||||
export const emptyAircraft = () => {
|
||||
Coherent.call(
|
||||
COHERENT_COMBUS_WASM_CALL,
|
||||
COMM_BUS_LIVE_DATA_EVENT,
|
||||
JSON.stringify({
|
||||
mode: 3,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
export const COMMANDS = 'KHOFMANN_PDF_READER_COMMANDS';
|
||||
export const DATA = 'KHOFMANN_PDF_READER_DATA';
|
||||
export const LIST = 'LIST';
|
||||
export const LOAD = 'LOAD';
|
||||
export const SAVE = 'SAVE';
|
||||
export const MAX_LIST = 10;
|
||||
export const COHERENT_COMBUS_WASM_CALL = 'COMM_BUS_WASM_CALLBACK';
|
||||
export const TFDI_SIMBRIEF_USERNAME_EVENT = 'requestSimBriefUsername';
|
||||
export const COMM_BUS_LIVE_DATA_EVENT = 'khofmann_tfdi_md-11_load_manager_live_data';
|
||||
export const COMM_BUS_UPDATE_TARGET_EVENT = 'khofmann_tfdi_md-11_load_manager_update_target';
|
||||
|
||||
85
PackageSources/js-bundle/src/types/WASMData.d.ts
vendored
Normal file
85
PackageSources/js-bundle/src/types/WASMData.d.ts
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
export interface WASMDataPax {
|
||||
livePayload: LivePayloadPax;
|
||||
targetPayload: TargetPayloadPax;
|
||||
GSX: GSX;
|
||||
userData: UserData;
|
||||
limits: LimitsPax;
|
||||
}
|
||||
|
||||
interface TargetPayloadPax {
|
||||
empty: number;
|
||||
crew: number;
|
||||
business1: number;
|
||||
business2: number;
|
||||
economy1: number;
|
||||
economy2: number;
|
||||
forwardCargo: number;
|
||||
rearCargo: number;
|
||||
ZFWCG: number;
|
||||
TOCG: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
interface LivePayloadPax extends TargetPayloadPax {
|
||||
fuel: number;
|
||||
}
|
||||
|
||||
interface TargetPayloadF {
|
||||
empty: number;
|
||||
crew: number;
|
||||
upper1: number;
|
||||
upper2: number;
|
||||
upper3: number;
|
||||
upper4: number;
|
||||
lowerForward: number;
|
||||
lowerRear: number;
|
||||
ZFWCG: number;
|
||||
TOCG: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
interface LivePayloadF extends TargetPayloadF {
|
||||
fuel: number;
|
||||
}
|
||||
|
||||
interface GSX {
|
||||
boardingState: number;
|
||||
deboardingState: number;
|
||||
passengersBoarded: number;
|
||||
passengersDeboarded: number;
|
||||
cargoBoarded: number;
|
||||
cargoDeboarded: number;
|
||||
}
|
||||
|
||||
interface Limits {
|
||||
minCG: number;
|
||||
maxCG: number;
|
||||
maxFuel: number;
|
||||
maxTOW: number;
|
||||
maxZFW: number;
|
||||
minZFW: number;
|
||||
}
|
||||
|
||||
interface LimitsPax extends Limits {
|
||||
business1: number;
|
||||
business2: number;
|
||||
economy1: number;
|
||||
economy2: number;
|
||||
forwardCargo: number;
|
||||
rearCargo: number;
|
||||
}
|
||||
|
||||
interface LimitsF extends Limits {
|
||||
upper1: number;
|
||||
upper2: number;
|
||||
upper3: number;
|
||||
upper4: number;
|
||||
lowerForward: number;
|
||||
lowerRear: number;
|
||||
}
|
||||
|
||||
interface UserData {
|
||||
isCargo: boolean;
|
||||
isER: boolean;
|
||||
isImperial: boolean;
|
||||
}
|
||||
@ -15,7 +15,7 @@ FuelData_t* liveFuelData;
|
||||
bool commBusCallbackRegistered;
|
||||
HANDLE simConnect;
|
||||
FILE* logFile;
|
||||
char sendTimer = 0;
|
||||
MODULE_VAR tick18 = { TICK18 };
|
||||
|
||||
// Init
|
||||
extern "C" MSFS_CALLBACK void module_init(void) {
|
||||
@ -35,6 +35,8 @@ extern "C" MSFS_CALLBACK void module_init(void) {
|
||||
targetFPayloadData = new fPayloadData_t();
|
||||
liveFuelData = new FuelData_t();
|
||||
|
||||
targetFPayloadData->ZFWCG = targetPaxPayloadData->ZFWCG = 21;
|
||||
|
||||
#pragma region SimConnect
|
||||
|
||||
// SimConnect open
|
||||
@ -414,15 +416,15 @@ extern "C" MSFS_CALLBACK void module_deinit(void) {
|
||||
|
||||
// Main loop
|
||||
extern "C" MSFS_CALLBACK bool Load_Manager_gauge_callback(FsContext ctx, int service_id, void* pData) {
|
||||
/*
|
||||
switch (service_id) {
|
||||
case PANEL_SERVICE_PRE_UPDATE: {
|
||||
|
||||
lookup_var(&tick18);
|
||||
if (fmod(tick18.var_value.n, 3) == 0) sendData();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -431,6 +433,8 @@ void commBusUpdateTargetCallback(const char* args, unsigned int size, void* ctx)
|
||||
printf("Target payload update request: %d", receiveData(args));
|
||||
}
|
||||
|
||||
#pragma region JSON data handling
|
||||
|
||||
// JSON receive
|
||||
int receiveData(const char* buf) {
|
||||
if (liveFPayloadData == nullptr || livePaxPayloadData == nullptr || targetFPayloadData == nullptr || targetPaxPayloadData == nullptr ||
|
||||
@ -440,20 +444,6 @@ int receiveData(const char* buf) {
|
||||
document.Parse(buf);
|
||||
if (document.HasParseError()) return document.GetParseError();
|
||||
|
||||
// Shared part 1
|
||||
targetFPayloadData->empty = targetPaxPayloadData->empty = FROM_POUNDS(UserData->isImperial, liveFPayloadData->empty);
|
||||
targetFPayloadData->pilot = targetPaxPayloadData->pilot = PILOT_WEIGHT(UserData->isImperial);
|
||||
targetFPayloadData->firstOfficer = targetPaxPayloadData->firstOfficer = PILOT_WEIGHT(UserData->isImperial);
|
||||
targetFPayloadData->engineer = targetPaxPayloadData->engineer = PILOT_WEIGHT(UserData->isImperial);
|
||||
// Shared part 2
|
||||
targetFPayloadData->leftAux = targetPaxPayloadData->leftAux = UserData->isER ? AUX_WEIGHT(UserData->isImperial) : 0;
|
||||
targetFPayloadData->rightAux = targetPaxPayloadData->rightAux = UserData->isER ? AUX_WEIGHT(UserData->isImperial) : 0;
|
||||
// Pax only fixed weights
|
||||
if (!UserData->isCargo) {
|
||||
targetPaxPayloadData->cabinCrewFront = FRONT_CREW_WEIGHT(UserData->isImperial);
|
||||
targetPaxPayloadData->cabinCrewRear = REAR_CREW_WEIGHT(UserData->isImperial);
|
||||
}
|
||||
|
||||
if (document.HasMember("mode")) {
|
||||
int mode = document["mode"].GetUint();
|
||||
switch(mode) {
|
||||
@ -512,6 +502,7 @@ int receiveData(const char* buf) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sendData();
|
||||
}
|
||||
else return -1;
|
||||
|
||||
@ -533,6 +524,10 @@ void sendData () {
|
||||
targetPayload.SetObject();
|
||||
rapidjson::Value GSX;
|
||||
GSX.SetObject();
|
||||
rapidjson::Value userData;
|
||||
userData.SetObject();
|
||||
rapidjson::Value limits;
|
||||
limits.SetObject();
|
||||
|
||||
rapidjson::StringBuffer strbuf;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf);
|
||||
@ -558,6 +553,12 @@ void sendData () {
|
||||
livePayload.AddMember("upper4", FROM_POUNDS(UserData->isImperial, liveFPayloadData->upper4Left + liveFPayloadData->upper4Right), allocator);
|
||||
livePayload.AddMember("lowerForward", FROM_POUNDS(UserData->isImperial, liveFPayloadData->lowerForward), allocator);
|
||||
livePayload.AddMember("lowerRear", FROM_POUNDS(UserData->isImperial, liveFPayloadData->lowerRear), allocator);
|
||||
livePayload.AddMember("total", FROM_POUNDS(UserData->isImperial, liveFPayloadData->total), allocator);
|
||||
// CGs
|
||||
//TODO: Enable for F
|
||||
//calculateCGs(liveFPayloadData, liveFuelData, &liveFPayloadData->ZFWCG, &liveFPayloadData->TOCG, true);
|
||||
targetPayload.AddMember("ZFWCG", liveFPayloadData->ZFWCG, allocator);
|
||||
targetPayload.AddMember("TOCG", liveFPayloadData->TOCG, allocator);
|
||||
}
|
||||
// Pax only (converted to passengers)
|
||||
else {
|
||||
@ -566,7 +567,7 @@ void sendData () {
|
||||
FROM_POUNDS(UserData->isImperial, livePaxPayloadData->engineer) + FROM_POUNDS(UserData->isImperial, livePaxPayloadData->cabinCrewFront) +
|
||||
FROM_POUNDS(UserData->isImperial, livePaxPayloadData->cabinCrewRear),
|
||||
allocator);
|
||||
livePayload.AddMember("businnes1",
|
||||
livePayload.AddMember("business1",
|
||||
(short)(FROM_POUNDS(UserData->isImperial, livePaxPayloadData->business1Left + livePaxPayloadData->business1Center +
|
||||
livePaxPayloadData->business1Right) / PAX_WEIGHT(UserData->isImperial)),
|
||||
allocator);
|
||||
@ -584,11 +585,12 @@ void sendData () {
|
||||
allocator);
|
||||
livePayload.AddMember("forwardCargo", FROM_POUNDS(UserData->isImperial, livePaxPayloadData->forwardCargo), allocator);
|
||||
livePayload.AddMember("rearCargo", FROM_POUNDS(UserData->isImperial, livePaxPayloadData->rearCargo), allocator);
|
||||
livePayload.AddMember("total", FROM_POUNDS(UserData->isImperial, livePaxPayloadData->total), allocator);
|
||||
// CGs
|
||||
calculateCGs(livePaxPayloadData, liveFuelData, &livePaxPayloadData->ZFWCG, &livePaxPayloadData->TOCG, true);
|
||||
livePayload.AddMember("ZFWCG",livePaxPayloadData->ZFWCG, allocator);
|
||||
livePayload.AddMember("TOCG", livePaxPayloadData->TOCG, allocator);
|
||||
}
|
||||
// CGs
|
||||
calculateCGs(livePaxPayloadData, liveFuelData, &livePaxPayloadData->ZFWCG, &livePaxPayloadData->TOCG, true);
|
||||
livePayload.AddMember("ZFWCG", UserData->isCargo ? liveFPayloadData->ZFWCG : livePaxPayloadData->ZFWCG, allocator);
|
||||
livePayload.AddMember("TOCG", UserData->isCargo ? liveFPayloadData->ZFWCG : livePaxPayloadData->TOCG, allocator);
|
||||
// Fuel
|
||||
livePayload.AddMember("fuel", FROM_POUNDS(UserData->isImperial, liveFuelData->total), allocator);
|
||||
#pragma endregion
|
||||
@ -610,6 +612,12 @@ void sendData () {
|
||||
targetPayload.AddMember("upper4", targetFPayloadData->upper4Left + targetFPayloadData->upper4Right, allocator);
|
||||
targetPayload.AddMember("lowerForward", targetFPayloadData->lowerForward, allocator);
|
||||
targetPayload.AddMember("lowerRear", targetFPayloadData->lowerRear, allocator);
|
||||
targetPayload.AddMember("total", targetFPayloadData->total, allocator);
|
||||
// CGs
|
||||
//TODO: Enable for F
|
||||
//calculateCGs(targetFPayloadData, liveFuelData, &targetFPayloadData->ZFWCG, &targetFPayloadData->TOCG, UserData->isImperial);
|
||||
targetPayload.AddMember("ZFWCG", targetFPayloadData->ZFWCG, allocator);
|
||||
targetPayload.AddMember("TOCG", targetFPayloadData->TOCG, allocator);
|
||||
}
|
||||
// Pax only (converted to passengers)
|
||||
else {
|
||||
@ -617,16 +625,18 @@ void sendData () {
|
||||
targetPaxPayloadData->pilot + targetPaxPayloadData->firstOfficer + targetPaxPayloadData->engineer +
|
||||
targetPaxPayloadData->cabinCrewFront + targetPaxPayloadData->cabinCrewRear,
|
||||
allocator);
|
||||
targetPayload.AddMember("businnes1", targetPaxPayloadData->paxCount.business1, allocator);
|
||||
targetPayload.AddMember("business1", targetPaxPayloadData->paxCount.business1, allocator);
|
||||
targetPayload.AddMember("business2", targetPaxPayloadData->paxCount.business2, allocator);
|
||||
targetPayload.AddMember("economy1", targetPaxPayloadData->paxCount.economy1, allocator);
|
||||
targetPayload.AddMember("economy2", targetPaxPayloadData->paxCount.economy2, allocator);
|
||||
targetPayload.AddMember("forwardCargo", targetPaxPayloadData->forwardCargo, allocator);
|
||||
targetPayload.AddMember("rearCargo", targetPaxPayloadData->rearCargo, allocator);
|
||||
targetPayload.AddMember("total", targetPaxPayloadData->total, allocator);
|
||||
// CGs
|
||||
calculateCGs(targetPaxPayloadData, liveFuelData, &targetPaxPayloadData->ZFWCG, &targetPaxPayloadData->TOCG, UserData->isImperial);
|
||||
targetPayload.AddMember("ZFWCG", targetPaxPayloadData->ZFWCG, allocator);
|
||||
targetPayload.AddMember("TOCG", targetPaxPayloadData->TOCG, allocator);
|
||||
}
|
||||
// CGs
|
||||
targetPayload.AddMember("ZFWCG", UserData->isCargo ? targetFPayloadData->ZFWCG : targetPaxPayloadData->ZFWCG, allocator);
|
||||
targetPayload.AddMember("TOCG", UserData->isCargo ? targetFPayloadData->TOCG : targetPaxPayloadData->TOCG, allocator);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
@ -639,10 +649,47 @@ void sendData () {
|
||||
GSX.AddMember("cargoBoarded", GSXData->cargoBoarded, allocator);
|
||||
GSX.AddMember("cargoDeboarded", GSXData->cargoDeboarded, allocator);
|
||||
|
||||
// User Data
|
||||
userData.AddMember<bool>("isCargo", UserData->isCargo, allocator);
|
||||
userData.AddMember<bool>("isER", UserData->isER, allocator);
|
||||
userData.AddMember<bool>("isImperial", UserData->isImperial, allocator);
|
||||
|
||||
// Limits
|
||||
limits.AddMember("minCG", MIN_CG, allocator);
|
||||
limits.AddMember("maxCG", MAX_CG, allocator);
|
||||
limits.AddMember("maxFuel", UserData->isER ? MAX_FUEL_ER(UserData->isImperial) : MAX_FUEL(UserData->isImperial), allocator);
|
||||
limits.AddMember("maxTOW", UserData->isER ? MAX_TOW_ER(UserData->isImperial) : MAX_TOW(UserData->isImperial), allocator);
|
||||
// Cargo Only
|
||||
// TODO: Actual F limits
|
||||
if (UserData->isCargo) {
|
||||
limits.AddMember("upper1", -1, allocator);
|
||||
limits.AddMember("upper2", -1, allocator);
|
||||
limits.AddMember("upper3", -1, allocator);
|
||||
limits.AddMember("upper4", -1, allocator);
|
||||
limits.AddMember("lowerForward", MAX_FRONT_CARGO(UserData->isImperial), allocator);
|
||||
limits.AddMember("lowerRear", MAX_REAR_CARGO(UserData->isImperial), allocator);
|
||||
// TODO: Actual F limit
|
||||
//limits.AddMember("MaxZFW", MAX_F_ZFW, allocator);
|
||||
limits.AddMember("minZFW", targetFPayloadData->empty + targetFPayloadData->leftAux + targetFPayloadData->rightAux, allocator);
|
||||
}
|
||||
// Pax only
|
||||
else {
|
||||
limits.AddMember("business1", MAX_BUSINESS_1, allocator);
|
||||
limits.AddMember("business2", MAX_BUSINESS_2, allocator);
|
||||
limits.AddMember("economy1", MAX_ECONOMY_1, allocator);
|
||||
limits.AddMember("economy2", MAX_ECONOMY_2, allocator);
|
||||
limits.AddMember("forwardCargo", MAX_FRONT_CARGO(UserData->isImperial), allocator);
|
||||
limits.AddMember("rearCargo", MAX_REAR_CARGO(UserData->isImperial), allocator);
|
||||
limits.AddMember("maxZFW", MAX_PAX_ZFW(UserData->isImperial), allocator);
|
||||
limits.AddMember("minZFW", targetPaxPayloadData->empty + targetPaxPayloadData->leftAux + targetPaxPayloadData->rightAux, allocator);
|
||||
}
|
||||
|
||||
// Construct document
|
||||
document.AddMember("livePayload", livePayload.Move(), allocator);
|
||||
document.AddMember("targetPayload", targetPayload.Move(), allocator);
|
||||
document.AddMember("GSX", GSX.Move(), allocator);
|
||||
document.AddMember("userData", userData.Move(), allocator);
|
||||
document.AddMember("limits", limits.Move(), allocator);
|
||||
|
||||
// Write to CommBus
|
||||
document.Accept(writer);
|
||||
@ -650,6 +697,8 @@ void sendData () {
|
||||
fsCommBusCall(COMM_BUS_LIVE_DATA_EVENT, strbuf.GetString(), strbuf.GetSize(), FsCommBusBroadcast_JS);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
// Logfile
|
||||
void log(FILE* file, const char* format, void* optionalElement)
|
||||
{
|
||||
@ -670,16 +719,18 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex
|
||||
case DATA_REQUEST_EMPTY_WEIGHT: {
|
||||
liveFPayloadData->empty = livePaxPayloadData->empty = *((double*)&pObjData->dwData);
|
||||
|
||||
sendTimer++;
|
||||
|
||||
break;
|
||||
}
|
||||
case DATA_REQUEST_PAYLOAD_F: {
|
||||
fPayloadData_t* data = (fPayloadData_t*)&pObjData->dwData;
|
||||
data->empty = liveFPayloadData->empty;
|
||||
memcpy(liveFPayloadData, data, sizeof(fPayloadData_t));
|
||||
|
||||
sendTimer++;
|
||||
liveFPayloadData->total = liveFPayloadData->empty + liveFPayloadData->pilot + liveFPayloadData->firstOfficer +
|
||||
liveFPayloadData->engineer + liveFPayloadData->upper1Left + liveFPayloadData->upper1Right +
|
||||
liveFPayloadData->upper2Left + liveFPayloadData->upper2Right + liveFPayloadData->upper3Left +
|
||||
liveFPayloadData->upper3Right + liveFPayloadData->upper4Left + liveFPayloadData->upper4Right +
|
||||
liveFPayloadData->lowerForward + liveFPayloadData->lowerRear + liveFPayloadData->leftAux +
|
||||
liveFPayloadData->rightAux;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -687,8 +738,14 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex
|
||||
paxPayloadData_t* data = (paxPayloadData_t*)&pObjData->dwData;
|
||||
data->empty = livePaxPayloadData->empty;
|
||||
memcpy(livePaxPayloadData, data, sizeof(paxPayloadData_t));
|
||||
|
||||
sendTimer++;
|
||||
livePaxPayloadData->total = livePaxPayloadData->empty + livePaxPayloadData->pilot + livePaxPayloadData->firstOfficer +
|
||||
livePaxPayloadData->engineer + livePaxPayloadData->cabinCrewFront + livePaxPayloadData->business1Left +
|
||||
livePaxPayloadData->business1Center + livePaxPayloadData->business1Right + livePaxPayloadData->business2Left +
|
||||
livePaxPayloadData->business2Center + livePaxPayloadData->business2Right + livePaxPayloadData->economy1Left +
|
||||
livePaxPayloadData->economy1Center + livePaxPayloadData->economy1Right + livePaxPayloadData->economy2Left +
|
||||
livePaxPayloadData->economy2Center + livePaxPayloadData->economy2Right + livePaxPayloadData->cabinCrewRear +
|
||||
livePaxPayloadData->forwardCargo + livePaxPayloadData->rearCargo + livePaxPayloadData->leftAux +
|
||||
livePaxPayloadData->rightAux;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -708,16 +765,12 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex
|
||||
liveFuelData->lowerAux + liveFuelData->main1Tip + liveFuelData->main3Tip + liveFuelData->tail +
|
||||
liveFuelData->forwardAux1 + liveFuelData->forwardAux2;
|
||||
|
||||
sendTimer++;
|
||||
|
||||
break;
|
||||
}
|
||||
case DATA_REQUEST_GSX: {
|
||||
GSXData_t* data = (GSXData_t*)&pObjData->dwData;
|
||||
memcpy(GSXData, data, sizeof(GSXData_t));
|
||||
|
||||
sendTimer++;
|
||||
|
||||
break;
|
||||
}
|
||||
case DATA_REQUEST_USER_DATA: {
|
||||
@ -725,7 +778,19 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex
|
||||
data->isImperial = ((long)data->isImperial) & 1;
|
||||
memcpy(UserData, data, sizeof(UserData_t));
|
||||
|
||||
sendTimer++;
|
||||
// Update static weights
|
||||
// Shared part 1
|
||||
targetFPayloadData->empty = targetPaxPayloadData->empty = FROM_POUNDS(UserData->isImperial, liveFPayloadData->empty);
|
||||
targetFPayloadData->pilot = targetPaxPayloadData->pilot = targetFPayloadData->firstOfficer = targetPaxPayloadData->firstOfficer =
|
||||
targetFPayloadData->engineer = targetPaxPayloadData->engineer = PILOT_WEIGHT(UserData->isImperial);
|
||||
// Shared part 2
|
||||
targetFPayloadData->leftAux = targetPaxPayloadData->leftAux = targetFPayloadData->rightAux = targetPaxPayloadData->rightAux =
|
||||
UserData->isER ? AUX_WEIGHT(UserData->isImperial) : 0;
|
||||
// Pax only fixed weights
|
||||
if (!UserData->isCargo) {
|
||||
targetPaxPayloadData->cabinCrewFront = FRONT_CREW_WEIGHT(UserData->isImperial);
|
||||
targetPaxPayloadData->cabinCrewRear = REAR_CREW_WEIGHT(UserData->isImperial);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@ -734,12 +799,6 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex
|
||||
}
|
||||
}
|
||||
|
||||
// Send once every request "frame"
|
||||
if (sendTimer == 6) {
|
||||
sendData();
|
||||
sendTimer = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SIMCONNECT_RECV_ID_EXCEPTION:
|
||||
|
||||
@ -13,6 +13,11 @@ void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const f
|
||||
|
||||
//SimBrief Entry, SB pax count and total cargo
|
||||
void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, unsigned short numPax, unsigned int cargo, const double CGTarget, const bool isImperial) {
|
||||
// Clear
|
||||
targetPayload->paxCount.business1 = targetPayload->paxCount.business2 = targetPayload->paxCount.economy1 = targetPayload->paxCount.economy2 =
|
||||
targetPayload->paxCount.total = 0;
|
||||
targetPayload->forwardCargo = targetPayload->rearCargo = 0;
|
||||
|
||||
unsigned short _numPax = 0;
|
||||
unsigned int count = MAX_PAX;
|
||||
// Initial distribution pax + bags
|
||||
@ -219,12 +224,22 @@ void generatePayload(paxPayloadData_t* const targetPayload, const bool isImperia
|
||||
targetPayload->business2Left = targetPayload->business2Center = targetPayload->business2Right = (targetPayload->paxCount.business2 / 3.0) * PAX_WEIGHT(isImperial);
|
||||
targetPayload->economy1Left = targetPayload->economy1Center = targetPayload->economy1Right = (targetPayload->paxCount.economy1 / 3.0) * PAX_WEIGHT(isImperial);
|
||||
targetPayload->economy2Left = targetPayload->economy2Center = targetPayload->economy2Right = (targetPayload->paxCount.economy2 / 3.0) * PAX_WEIGHT(isImperial);
|
||||
targetPayload->total = targetPayload->empty + targetPayload->pilot + targetPayload->firstOfficer + targetPayload->engineer + targetPayload->cabinCrewFront +
|
||||
targetPayload->business1Left + targetPayload->business1Center + targetPayload->business1Right + targetPayload->business2Left +
|
||||
targetPayload->business2Center + targetPayload->business2Right + targetPayload->economy1Left + targetPayload->economy1Center +
|
||||
targetPayload->economy1Right + targetPayload->economy2Left + targetPayload->economy2Center + targetPayload->economy2Right +
|
||||
targetPayload->cabinCrewRear + targetPayload->forwardCargo + targetPayload->rearCargo + targetPayload->leftAux + targetPayload->rightAux;
|
||||
}
|
||||
|
||||
// Normalise to Pounds
|
||||
// MANDATORY BEFORE SETTING WEIGHTS
|
||||
// ENSURE ONLY EVER CALLED ONCE PER SET CYCLE
|
||||
void normalisePayload(paxPayloadData_t* const targetPayload, const bool isImperial) {
|
||||
targetPayload->empty = TO_POUNDS(isImperial, targetPayload->empty);
|
||||
targetPayload->pilot = TO_POUNDS(isImperial, targetPayload->pilot);
|
||||
targetPayload->firstOfficer = TO_POUNDS(isImperial, targetPayload->firstOfficer);
|
||||
targetPayload->engineer = TO_POUNDS(isImperial, targetPayload->engineer);
|
||||
targetPayload->cabinCrewFront = TO_POUNDS(isImperial, targetPayload->cabinCrewFront);
|
||||
targetPayload->business1Left = TO_POUNDS(isImperial, targetPayload->business1Left);
|
||||
targetPayload->business1Center = TO_POUNDS(isImperial, targetPayload->business1Center);
|
||||
targetPayload->business1Right = TO_POUNDS(isImperial, targetPayload->business1Right);
|
||||
@ -237,27 +252,32 @@ void normalisePayload(paxPayloadData_t* const targetPayload, const bool isImperi
|
||||
targetPayload->economy2Left = TO_POUNDS(isImperial, targetPayload->economy2Left);
|
||||
targetPayload->economy2Center = TO_POUNDS(isImperial, targetPayload->economy2Center);
|
||||
targetPayload->economy2Right = TO_POUNDS(isImperial, targetPayload->economy2Right);
|
||||
targetPayload->cabinCrewRear = TO_POUNDS(isImperial, targetPayload->cabinCrewRear);
|
||||
targetPayload->forwardCargo = TO_POUNDS(isImperial, targetPayload->forwardCargo);
|
||||
targetPayload->rearCargo = TO_POUNDS(isImperial, targetPayload->rearCargo);
|
||||
}
|
||||
|
||||
void calculateCGs(const paxPayloadData_t* const targetPayload, const FuelData_t* fuel, double* const ZFWCG, double* const TOCG, const bool isImperial) {
|
||||
double totalMoment = targetPayload->empty * ARM_EMPTY + targetPayload->pilot * ARM_PILOT + targetPayload->firstOfficer * ARM_FIRST_OFFICER +
|
||||
targetPayload->engineer * ARM_ENGINEER + targetPayload->cabinCrewFront * ARM_PAX_CABIN_CREW_FRONT +
|
||||
targetPayload->business1Left * ARM_PAX_BUSINESS1_LEFT + targetPayload->business1Center * ARM_PAX_BUSINESS1_CENTER +
|
||||
targetPayload->business1Right * ARM_PAX_BUSINESS1_RIGHT + targetPayload->business2Left * ARM_PAX_BUSINESS2_LEFT +
|
||||
targetPayload->business2Center * ARM_PAX_BUSINESS2_CENTER + targetPayload->business2Right * ARM_PAX_BUSINESS2_RIGHT +
|
||||
targetPayload->economy1Left * ARM_PAX_ECONOMY1_LEFT + targetPayload->economy1Center * ARM_PAX_ECONOMY1_CENTER +
|
||||
targetPayload->economy1Right * ARM_PAX_ECONOMY1_RIGHT + targetPayload->economy2Left * ARM_PAX_ECONOMY2_LEFT +
|
||||
targetPayload->economy2Center * ARM_PAX_ECONOMY2_CENTER + targetPayload->economy2Right * ARM_PAX_ECONOMY2_RIGHT +
|
||||
targetPayload->cabinCrewRear * ARM_PAX_CABIN_CREW_REAR + targetPayload->forwardCargo * ARM_FORWARD_CARGO +
|
||||
targetPayload->rearCargo * ARM_REAR_CARGO + targetPayload->leftAux * ARM_LEFT_AUX + targetPayload->rightAux * ARM_RIGHT_AUX;
|
||||
void calculateCGs(const paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, double* const ZFWCG, double* const TOCG, const bool isImperial) {
|
||||
paxPayloadData_t localPayload = {};
|
||||
memcpy(&localPayload, targetPayload, sizeof(localPayload));
|
||||
normalisePayload(&localPayload, isImperial);
|
||||
|
||||
double totalWeight = targetPayload->empty + targetPayload->pilot + targetPayload->firstOfficer + targetPayload->engineer +
|
||||
targetPayload->cabinCrewFront + targetPayload->business1Left + targetPayload->business1Center +
|
||||
targetPayload->business1Right + targetPayload->business2Left + targetPayload->business2Center +
|
||||
targetPayload->business2Right + targetPayload->economy1Left + targetPayload->economy1Center +
|
||||
targetPayload->economy1Right + targetPayload->economy2Left + targetPayload->economy2Center +
|
||||
targetPayload->economy2Right + targetPayload->cabinCrewRear + targetPayload->forwardCargo +
|
||||
targetPayload->rearCargo + targetPayload->leftAux + targetPayload->rightAux;
|
||||
double totalMoment = localPayload.empty * ARM_EMPTY + localPayload.pilot * ARM_PILOT + localPayload.firstOfficer * ARM_FIRST_OFFICER +
|
||||
localPayload.engineer * ARM_ENGINEER + localPayload.cabinCrewFront * ARM_PAX_CABIN_CREW_FRONT +
|
||||
localPayload.business1Left * ARM_PAX_BUSINESS1_LEFT + localPayload.business1Center * ARM_PAX_BUSINESS1_CENTER +
|
||||
localPayload.business1Right * ARM_PAX_BUSINESS1_RIGHT + localPayload.business2Left * ARM_PAX_BUSINESS2_LEFT +
|
||||
localPayload.business2Center * ARM_PAX_BUSINESS2_CENTER + localPayload.business2Right * ARM_PAX_BUSINESS2_RIGHT +
|
||||
localPayload.economy1Left * ARM_PAX_ECONOMY1_LEFT + localPayload.economy1Center * ARM_PAX_ECONOMY1_CENTER +
|
||||
localPayload.economy1Right * ARM_PAX_ECONOMY1_RIGHT + localPayload.economy2Left * ARM_PAX_ECONOMY2_LEFT +
|
||||
localPayload.economy2Center * ARM_PAX_ECONOMY2_CENTER + localPayload.economy2Right * ARM_PAX_ECONOMY2_RIGHT +
|
||||
localPayload.cabinCrewRear * ARM_PAX_CABIN_CREW_REAR + localPayload.forwardCargo * ARM_FORWARD_CARGO +
|
||||
localPayload.rearCargo * ARM_REAR_CARGO + localPayload.leftAux * ARM_LEFT_AUX + localPayload.rightAux * ARM_RIGHT_AUX;
|
||||
|
||||
double totalWeight = localPayload.empty + localPayload.pilot + localPayload.firstOfficer + localPayload.engineer + localPayload.cabinCrewFront +
|
||||
localPayload.business1Left + localPayload.business1Center + localPayload.business1Right + localPayload.business2Left +
|
||||
localPayload.business2Center + localPayload.business2Right + localPayload.economy1Left + localPayload.economy1Center +
|
||||
localPayload.economy1Right + localPayload.economy2Left + localPayload.economy2Center + localPayload.economy2Right +
|
||||
localPayload.cabinCrewRear + localPayload.forwardCargo + localPayload.rearCargo + localPayload.leftAux + localPayload.rightAux;
|
||||
|
||||
*ZFWCG = TO_PERCENT_MAC(totalMoment / totalWeight);
|
||||
|
||||
|
||||
@ -27,4 +27,4 @@ void generatePayload(paxPayloadData_t* const targetPayload, const bool isImperia
|
||||
// Normalise to Pounds
|
||||
// For Station Entry: CALL AFTER `generatePayload`
|
||||
void normalisePayload(paxPayloadData_t* const targetPayload, const bool isImperial);
|
||||
void calculateCGs(const paxPayloadData_t* const targetPayload, const FuelData_t* fuel, double* const ZFWCG, double* const TOCG, const bool isImperial);
|
||||
void calculateCGs(const paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, double* const ZFWCG, double* const TOCG, const bool isImperial);
|
||||
|
||||
@ -31,6 +31,17 @@
|
||||
// Total
|
||||
#define MAX_PAX 298
|
||||
|
||||
// Max ZFW
|
||||
#define MAX_PAX_ZFW(IS_IMPERIAL) ((IS_IMPERIAL) ? (400000) : (181437))
|
||||
|
||||
// Max TOW
|
||||
#define MAX_TOW(IS_IMPERIAL) ((IS_IMPERIAL) ? (625500) : (283722))
|
||||
#define MAX_TOW_ER(IS_IMPERIAL) ((IS_IMPERIAL) ? (630500) : (285990))
|
||||
|
||||
// Max Fuel
|
||||
#define MAX_FUEL(IS_IMPERIAL) ((IS_IMPERIAL) ? (256207) : (116213))
|
||||
#define MAX_FUEL_ER(IS_IMPERIAL) ((IS_IMPERIAL) ? (282619) : (128193))
|
||||
|
||||
// Arms
|
||||
// Shared part 1
|
||||
#define ARM_EMPTY -159.6
|
||||
@ -132,10 +143,9 @@ typedef struct {
|
||||
|
||||
// Additional properties
|
||||
double empty;
|
||||
|
||||
double total;
|
||||
double ZFWCG;
|
||||
double TOCG;
|
||||
|
||||
struct paxCount {
|
||||
unsigned char business1;
|
||||
unsigned char business2;
|
||||
@ -165,7 +175,7 @@ typedef struct {
|
||||
|
||||
// Additional properties
|
||||
double empty;
|
||||
|
||||
double total;
|
||||
double ZFWCG;
|
||||
double TOCG;
|
||||
} fPayloadData_t;
|
||||
|
||||
15
README.md
15
README.md
@ -5,6 +5,17 @@
|
||||
- https://www.satco-inc.com/product-pallet/?part_number=31086-595
|
||||
- https://www.satco-inc.com/product-container/?part_number=34124-901
|
||||
|
||||
Coherent.call("COMM_BUS_WASM_CALLBACK", "khofmann_tfdi_md-11_load_manager_update_target", '{"value" : 42}');
|
||||
|
||||
Coherent.call("COMM_BUS_WASM_CALLBACK", "khofmann_tfdi_md-11_load_manager_update_target", '{"mode" : 1, "ZFWTarget": 162000, "CGTarget": 20.5}');
|
||||
|
||||
TODO:
|
||||
|
||||
- JS
|
||||
- Connect to WASM as Data Source (sans SB username)
|
||||
- Setting target
|
||||
- SB
|
||||
- Stations
|
||||
- GSX State?
|
||||
- Duplicate Input pages for F
|
||||
- WASM
|
||||
- Setting of payload
|
||||
- GSX synced setting
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user