Skip to content

Commit

Permalink
feat: Chase-around chart calculator.
Browse files Browse the repository at this point in the history
  • Loading branch information
mattj65817 committed Feb 29, 2024
1 parent 87ef00f commit 429f706
Show file tree
Hide file tree
Showing 46 changed files with 2,255 additions and 661 deletions.
46 changes: 46 additions & 0 deletions __tests__/chart/ChartLoader.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { ChartLoader } from "../../src/chart";
import { isPerformanceCalculator, PerformanceCalculator } from "../../src/performance/performance-types";

import cruiseAirspeedJson from "./chase/da40-cruise-airspeed.json";
import cruiseAirspeedProjJson from "./chase/wpd/da40-cruise-airspeed.wpd.json";

describe("ChartLoader", () => {
describe("load()", () => {
const instance = ChartLoader.create(new URL("http://localhost"), fetchTestJson);
it("loads the cruise-airspeed chart", async () => {
const chart = await instance.load("http://localhost/cruise-airspeed.json");
expect(isPerformanceCalculator(chart)).toBe(true);
expect(chart.meta.src.href).toEqual("http://localhost/cruise-airspeed.json");
expect(chart.meta.image.src.href).toEqual("http://localhost/cruise-airspeed.png");
expect(chart.meta.image.size).toEqual([978, 692]);
const solution = (chart as unknown as PerformanceCalculator).calculate({
outsideAirTemperature: {
value: 15,
unit: "degrees celsius",
},
power: {
value: 55,
unit: "percent",
},
pressureAltitude: {
value: 5_000,
unit: "feet",
},
});
const { vars: { trueAirspeed } } = solution;
expect(trueAirspeed.unit).toEqual("knots");
expect(trueAirspeed.value).toBeCloseTo(118.46);
});
});
});

function fetchTestJson<B>(url: URL): Promise<B> {
switch (url.href) {
case "http://localhost/cruise-airspeed.json":
return Promise.resolve(cruiseAirspeedJson) as Promise<B>;
case "http://localhost/cruise-airspeed.wpd.json":
return Promise.resolve(cruiseAirspeedProjJson) as Promise<B>;
default:
throw Error("Unsupported URL.");
}
}
68 changes: 0 additions & 68 deletions __tests__/chart/Flow.test.ts

This file was deleted.

196 changes: 196 additions & 0 deletions __tests__/chart/chase/ChaseChart.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
import { WpdProject } from "../../../src/chart/chase/wpd";
import { WpdProjectDef } from "../../../src/chart/chase/wpd";
import { ChaseChartDef } from "../../../src/chart/chase/chase-types";

import cruiseAirspeedJson from "./da40-cruise-airspeed.json";
import cruiseAirspeedProjJson from "./wpd/da40-cruise-airspeed.wpd.json";
import landingDistanceFlapsUpJson from "./da40-landing-distance-flaps-up.json";
import landingDistanceFlapsUpProjJson from "./wpd/da40-landing-distance-flaps-up.wpd.json";
import landingDistanceJson from "./da40-landing-distance.json";
import landingDistanceProjJson from "./wpd/da40-landing-distance.wpd.json";
import takeoffClimbRateJson from "./da40-takeoff-climb-rate.json";
import takeoffClimbRateProjJson from "./wpd/da40-takeoff-climb-rate.wpd.json";
import takeoffDistanceJson from "./da40-takeoff-distance.json";
import takeoffDistanceProjJson from "./wpd/da40-takeoff-distance.wpd.json";
import { ChaseChart } from "../../../src/chart/chase";

describe("ChaseChart", () => {
const src = new URL("https://bogus.com/chart.json");
describe("create()", () => {
const proj = WpdProject.create(takeoffDistanceProjJson as unknown as WpdProjectDef);
const chart = ChaseChart.create(takeoffDistanceJson as unknown as ChaseChartDef, proj, src);
it("correctly extracts inputs and outputs", () => {
expect(chart.inputs).toEqual({
obstacleHeight: {
range: [0, 15],
unit: "meters",
},
outsideAirTemperature: {
range: [-20, 50],
unit: "degrees celsius",
},
pressureAltitude: {
range: [0, 10000],
unit: "feet",
},
weight: {
range: [850, 1200],
unit: "kilograms",
},
windComponent: {
range: [-5, 20],
unit: "knots",
},
});
expect(chart.outputs).toEqual({
takeoffDistance: {
unit: "meters",
},
});
});
it("throws an error if inputs are missing", () => {
expect(() => chart.calculate({})).toThrow("Missing inputs: obstacleHeight, outsideAirTemperature, pressureAltitude, weight, windComponent");
});
});
describe("calculate()", () => {
describe("da40-cruise-airspeed.json", () => {
const proj = WpdProject.create(cruiseAirspeedProjJson as unknown as WpdProjectDef);
const chart = ChaseChart.create(cruiseAirspeedJson as unknown as ChaseChartDef, proj, src);
it("calculates cruise airspeed", () => {
const solution = chart.calculate({
outsideAirTemperature: {
value: 15,
unit: "degrees celsius",
},
power: {
value: 55,
unit: "percent",
},
pressureAltitude: {
value: 5_000,
unit: "feet",
},
});
const { vars: { trueAirspeed } } = solution;
expect(trueAirspeed.unit).toEqual("knots");
expect(trueAirspeed.value).toBeCloseTo(118.46);
});
});
describe("da40-landing-distance.json", () => {
const proj = WpdProject.create(landingDistanceProjJson as unknown as WpdProjectDef);
const chart = ChaseChart.create(landingDistanceJson as unknown as ChaseChartDef, proj, src);
it("calculates landing distance", () => {
const solution = chart.calculate({
obstacleHeight: {
value: 15,
unit: "meters",
},
outsideAirTemperature: {
value: 15,
unit: "degrees celsius",
},
pressureAltitude: {
value: 2_000,
unit: "feet",
},
weight: {
value: 1_000,
unit: "kilograms",
},
windComponent: {
value: 10,
unit: "knots",
},
});
const { vars: { landingDistance } } = solution;
expect(landingDistance.unit).toEqual("meters");
expect(landingDistance.value).toBeCloseTo(422.70);
});
});
describe("da40-landing-distance-flaps-up.json", () => {
const proj = WpdProject.create(landingDistanceFlapsUpProjJson as unknown as WpdProjectDef);
const chart = ChaseChart.create(landingDistanceFlapsUpJson as unknown as ChaseChartDef, proj, src);
it("calculates flaps-up landing distance", () => {
const solution = chart.calculate({
obstacleHeight: {
value: 15,
unit: "meters",
},
outsideAirTemperature: {
value: 10,
unit: "degrees celsius",
},
pressureAltitude: {
value: 4_000,
unit: "feet",
},
weight: {
value: 1_000,
unit: "kilograms",
},
windComponent: {
value: 10,
unit: "knots",
},
});
const { vars: { landingDistance } } = solution;
expect(landingDistance.unit).toEqual("meters");
expect(landingDistance.value).toBeCloseTo(567.51);
});
});
describe("da40-takeoff-climb-rate.json", () => {
const proj = WpdProject.create(takeoffClimbRateProjJson as unknown as WpdProjectDef);
const chart = ChaseChart.create(takeoffClimbRateJson as unknown as ChaseChartDef, proj, src);
it("calculates takeoff climb rate", () => {
const solution = chart.calculate({
outsideAirTemperature: {
value: 15,
unit: "degrees celsius",
},
pressureAltitude: {
value: 2_000,
unit: "feet",
},
weight: {
value: 1_000,
unit: "kilograms",
},
});
const { vars: { climbRate } } = solution;
expect(climbRate.unit).toEqual("feet per minute");
expect(climbRate.value).toBeCloseTo(987.17);
});
});
describe("da40-takeoff-distance.json", () => {
const proj = WpdProject.create(takeoffDistanceProjJson as unknown as WpdProjectDef);
const chart = ChaseChart.create(takeoffDistanceJson as unknown as ChaseChartDef, proj, src);
it("calculates takeoff distance", () => {
const solution = chart.calculate({
obstacleHeight: {
value: 15,
unit: "meters",
},
outsideAirTemperature: {
value: 15,
unit: "degrees celsius",
},
pressureAltitude: {
value: 2_000,
unit: "feet",
},
weight: {
value: 1_000,
unit: "kilograms",
},
windComponent: {
value: 10,
unit: "knots",
},
});
const { vars: { takeoffDistance } } = solution;
expect(takeoffDistance.unit).toEqual("meters");
expect(takeoffDistance.value).toBeCloseTo(304.48);
});
});
});
});
41 changes: 41 additions & 0 deletions __tests__/chart/chase/da40-cruise-airspeed.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"kind": "chase",
"version": "1.0",
"image": {
"src": "./cruise-airspeed.png",
"size": [978, 692]
},
"project": {
"src": "./cruise-airspeed.wpd.json"
},
"steps": [
{
"chase": "up",
"along": "outsideAirTemperature",
"until": "pressureAltitude",
"unit": "feet",
"advance": false
},
{
"chase": "right",
"along": "pressureAltitude",
"until": "outsideAirTemperature",
"unit": "degrees celsius"
},
{
"chase": "right",
"along": "densityAltitudeCorrection"
},
{
"chase": "right",
"along": "densityAltitude",
"until": "power",
"unit": "percent"
},
{
"solve": "down",
"using": "trueAirspeed",
"unit": "knots"
}
]
}
Loading

0 comments on commit 429f706

Please sign in to comment.