-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Chase-around chart calculator.
- Loading branch information
1 parent
87ef00f
commit 429f706
Showing
46 changed files
with
2,255 additions
and
661 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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."); | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} | ||
] | ||
} |
Oops, something went wrong.