Live CG calculation
This commit is contained in:
parent
aca476b6bf
commit
afa806de61
@ -1,17 +1,138 @@
|
||||
import ThemeProvider from '@mui/material/styles/ThemeProvider';
|
||||
import { FC, StrictMode } from 'react';
|
||||
import styles from './App.module.scss';
|
||||
import { ArmsFreight, PayloadFreight } from './configs/freighter';
|
||||
import { ArmsPax, PayloadPax } from './configs/pax';
|
||||
import { ArmsFuel, EmptyArm, Fuel, toPercentMAC } from './configs/shared';
|
||||
|
||||
interface IAppProps {
|
||||
dataListener: ViewListener.ViewListener;
|
||||
}
|
||||
|
||||
const App: FC<IAppProps> = ({ dataListener }) => {
|
||||
const App: FC<IAppProps> = () => {
|
||||
// TODO: Get from EFB settings
|
||||
const [unit, setUnit] = useState<'lbs' | 'kg'>('lbs');
|
||||
// TODO: Look into EFB, infer the same way
|
||||
const [aircraft, setAircraft] = useState<'f' | 'pax'>('f');
|
||||
const [payload, setPayload] = useState<PayloadPax | PayloadFreight>();
|
||||
const [fuel, setFuel] = useState<Fuel>();
|
||||
|
||||
const [ZFWCG, setZFWCG] = useState(0);
|
||||
const [TOCG, setTOCG] = useState(0);
|
||||
|
||||
const requestRef = useRef<number | undefined>(undefined);
|
||||
|
||||
const mainLoop = () => {
|
||||
try {
|
||||
if (SimVar.IsReady()) {
|
||||
const conversion = SimVar.GetSimVarValue('FUEL WEIGHT PER GALLON', unit);
|
||||
const emptyWeight = SimVar.GetSimVarValue('EMPTY WEIGHT', unit);
|
||||
|
||||
const payload: PayloadPax | PayloadFreight = {
|
||||
pilot: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:1', unit),
|
||||
firstOfficer: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:2', unit),
|
||||
engineer: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:3', unit),
|
||||
upper1Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:4', unit),
|
||||
cabinCrewFront: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:4', unit),
|
||||
upper1Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:5', unit),
|
||||
business1Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:5', unit),
|
||||
upper2Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:6', unit),
|
||||
business1Center: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:6', unit),
|
||||
upper2Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:7', unit),
|
||||
business1Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:7', unit),
|
||||
upper3Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:8', unit),
|
||||
business2Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:8', unit),
|
||||
upper3Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:9', unit),
|
||||
business2Center: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:9', unit),
|
||||
upper4Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:10', unit),
|
||||
business2Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:10', unit),
|
||||
upper4Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:11', unit),
|
||||
economy1Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:11', unit),
|
||||
lowerForward: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:12', unit),
|
||||
economy1Center: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:12', unit),
|
||||
lowerRear: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:13', unit),
|
||||
economy1Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:13', unit),
|
||||
leftAuxF: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:14', unit),
|
||||
economy2Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:14', unit),
|
||||
rightAuxF: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:15', unit),
|
||||
economy2Center: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:15', unit),
|
||||
economy2Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:16', unit),
|
||||
cabinCrewRear: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:17', unit),
|
||||
forwardCargo: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:18', unit),
|
||||
rearCargo: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:19', unit),
|
||||
leftAuxPax: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:20', unit),
|
||||
rightAuxPax: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:21', unit),
|
||||
};
|
||||
|
||||
const fuel = {
|
||||
main1: SimVar.GetSimVarValue('FUEL TANK LEFT MAIN QUANTITY', 'gal') * conversion,
|
||||
main3: SimVar.GetSimVarValue('FUEL TANK RIGHT MAIN QUANTITY', 'gal') * conversion,
|
||||
main2: SimVar.GetSimVarValue('FUEL TANK CENTER QUANTITY', 'gal') * conversion,
|
||||
upperAux: SimVar.GetSimVarValue('FUEL TANK CENTER2 QUANTITY', 'gal') * conversion,
|
||||
lowerAux: SimVar.GetSimVarValue('FUEL TANK CENTER3 QUANTITY', 'gal') * conversion,
|
||||
main1Tip: SimVar.GetSimVarValue('FUEL TANK LEFT TIP QUANTITY', 'gal') * conversion,
|
||||
main3Tip: SimVar.GetSimVarValue('FUEL TANK RIGHT TIP QUANTITY', 'gal') * conversion,
|
||||
tail: SimVar.GetSimVarValue('FUEL TANK EXTERNAL1 QUANTITY', 'gal') * conversion,
|
||||
forwardAux1: SimVar.GetSimVarValue('FUEL TANK LEFT AUX QUANTITY', 'gal') * conversion,
|
||||
forwardAux2: SimVar.GetSimVarValue('FUEL TANK RIGHT AUX QUANTITY', 'gal') * conversion,
|
||||
};
|
||||
|
||||
let totalMoment = EmptyArm * emptyWeight;
|
||||
let totalWeight = emptyWeight;
|
||||
const arms = aircraft === 'f' ? ArmsFreight : ArmsPax;
|
||||
for (const key in arms) {
|
||||
if (Object.prototype.hasOwnProperty.call(payload, key)) {
|
||||
const stationWeight = payload[key as keyof (PayloadFreight | PayloadPax)];
|
||||
const arm = arms[key as keyof typeof arms];
|
||||
|
||||
totalWeight += stationWeight;
|
||||
totalMoment += arm * stationWeight;
|
||||
}
|
||||
}
|
||||
setZFWCG(toPercentMAC(totalMoment / totalWeight));
|
||||
|
||||
for (const key in ArmsFuel) {
|
||||
if (Object.prototype.hasOwnProperty.call(fuel, key)) {
|
||||
const stationWeight = fuel[key as keyof Fuel];
|
||||
const arm = ArmsFuel[key as keyof typeof ArmsFuel];
|
||||
|
||||
totalWeight += stationWeight;
|
||||
totalMoment += arm * stationWeight;
|
||||
}
|
||||
}
|
||||
setTOCG(toPercentMAC(totalMoment / totalWeight));
|
||||
|
||||
setPayload(payload);
|
||||
setFuel(fuel);
|
||||
}
|
||||
} catch {}
|
||||
|
||||
requestRef.current = requestAnimationFrame(mainLoop);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
requestRef.current = requestAnimationFrame(mainLoop);
|
||||
|
||||
if (requestRef.current !== undefined) return () => cancelAnimationFrame(requestRef.current as number);
|
||||
}, [unit, aircraft]);
|
||||
|
||||
return (
|
||||
<StrictMode>
|
||||
<div className={styles.app}>
|
||||
<ThemeProvider>
|
||||
</ThemeProvider>
|
||||
<button onClick={() => (unit === 'lbs' ? setUnit('kg') : setUnit('lbs'))}>Change unit from {unit}</button>
|
||||
<button onClick={() => (aircraft === 'f' ? setAircraft('pax') : setAircraft('f'))}>
|
||||
Change aircraft from {aircraft}
|
||||
</button>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<div>
|
||||
<pre>{JSON.stringify(payload, null, 2)}</pre>
|
||||
<strong>ZFWCG: {ZFWCG}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<pre>{JSON.stringify(fuel, null, 2)}</pre>
|
||||
<strong>TOCG: {TOCG}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
36
PackageSources/js-bundle/src/configs/freighter.ts
Normal file
36
PackageSources/js-bundle/src/configs/freighter.ts
Normal file
@ -0,0 +1,36 @@
|
||||
export interface PayloadFreight {
|
||||
pilot: number;
|
||||
firstOfficer: number;
|
||||
engineer: number;
|
||||
upper1Left: number;
|
||||
upper1Right: number;
|
||||
upper2Left: number;
|
||||
upper2Right: number;
|
||||
upper3Left: number;
|
||||
upper3Right: number;
|
||||
upper4Left: number;
|
||||
upper4Right: number;
|
||||
lowerForward: number;
|
||||
lowerRear: number;
|
||||
leftAuxF: number;
|
||||
rightAuxF: number;
|
||||
}
|
||||
|
||||
// TODO: Extract from CFG at runtime.
|
||||
export const ArmsFreight = {
|
||||
pilot: 984,
|
||||
firstOfficer: 984,
|
||||
engineer: 960,
|
||||
upper1Left: 660,
|
||||
upper1Right: 660,
|
||||
upper2Left: 240,
|
||||
upper2Right: 240,
|
||||
upper3Left: -240,
|
||||
upper3Right: -240,
|
||||
upper4Left: -600,
|
||||
upper4Right: -600,
|
||||
lowerForward: 360,
|
||||
lowerRear: -360,
|
||||
leftAuxF: 60,
|
||||
rightAuxF: 60,
|
||||
}
|
||||
49
PackageSources/js-bundle/src/configs/pax.ts
Normal file
49
PackageSources/js-bundle/src/configs/pax.ts
Normal file
@ -0,0 +1,49 @@
|
||||
export interface PayloadPax {
|
||||
pilot: number;
|
||||
firstOfficer: number;
|
||||
engineer: number;
|
||||
cabinCrewFront: number;
|
||||
business1Left: number;
|
||||
business1Center: number;
|
||||
business1Right: number;
|
||||
business2Left: number;
|
||||
business2Center: number;
|
||||
business2Right: number;
|
||||
economy1Left: number;
|
||||
economy1Center: number;
|
||||
economy1Right: number;
|
||||
economy2Left: number;
|
||||
economy2Center: number;
|
||||
economy2Right: number;
|
||||
cabinCrewRear: number;
|
||||
forwardCargo: number;
|
||||
rearCargo: number;
|
||||
leftAuxPax: number;
|
||||
rightAuxPax: number;
|
||||
}
|
||||
|
||||
// TODO: Extract from CFG at runtime.
|
||||
// FIXME: Copy over values
|
||||
export const ArmsPax = {
|
||||
pilot: 0,
|
||||
firstOfficer: 0,
|
||||
engineer: 0,
|
||||
cabinCrewFront: 0,
|
||||
business1Left: 0,
|
||||
business1Center: 0,
|
||||
business1Right: 0,
|
||||
business2Left: 0,
|
||||
business2Center: 0,
|
||||
business2Right: 0,
|
||||
economy1Left: 0,
|
||||
economy1Center: 0,
|
||||
economy1Right: 0,
|
||||
economy2Left: 0,
|
||||
economy2Center: 0,
|
||||
economy2Right: 0,
|
||||
cabinCrewRear: 0,
|
||||
forwardCargo: 0,
|
||||
rearCargo: 0,
|
||||
leftAuxPax: 0,
|
||||
rightAuxPax: 0,
|
||||
};
|
||||
45
PackageSources/js-bundle/src/configs/shared.ts
Normal file
45
PackageSources/js-bundle/src/configs/shared.ts
Normal file
@ -0,0 +1,45 @@
|
||||
export interface Fuel {
|
||||
main1: number;
|
||||
main3: number;
|
||||
main2: number;
|
||||
upperAux: number;
|
||||
lowerAux: number;
|
||||
main1Tip: number;
|
||||
main3Tip: number;
|
||||
tail: number;
|
||||
forwardAux1: number;
|
||||
forwardAux2: number;
|
||||
}
|
||||
|
||||
// TODO: Extract from CFG at runtime.
|
||||
export const EmptyArm = -159.6;
|
||||
|
||||
// TODO: Extract from CFG at runtime.
|
||||
export const ArmsFuel = {
|
||||
main1: -240,
|
||||
main3: -240,
|
||||
main2: 120,
|
||||
upperAux: 0,
|
||||
lowerAux: 0,
|
||||
main1Tip: -468,
|
||||
main3Tip: -468,
|
||||
tail: -840,
|
||||
forwardAux1: 60,
|
||||
forwardAux2: 60,
|
||||
};
|
||||
|
||||
// TODO: Extract following four from CFG at runtime
|
||||
const rootChord = 34.68;
|
||||
const wingSpan = 170.5;
|
||||
const wingArea = 3648;
|
||||
const quarterMAC = -165; //aero_center
|
||||
|
||||
const tipChord = (2 * wingArea) / wingSpan - rootChord;
|
||||
const taperRatio = tipChord / rootChord;
|
||||
|
||||
const MAC = (2 / 3) * rootChord * ((1 + taperRatio + taperRatio ** 2) / (1 + taperRatio)) * 12;
|
||||
const LEMAC = quarterMAC + (1 / 4) * MAC;
|
||||
|
||||
export const toPercentMAC = (positionInInches: number) => {
|
||||
return Math.abs(((positionInInches - LEMAC) / MAC) * 100);
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user