mirror of
https://github.com/Krafpy/KSP-MGA-Planner.git
synced 2025-12-12 07:40:41 -08:00
Added insertion burn checkbox.
This commit is contained in:
@@ -29,11 +29,12 @@ class TrajectoryCalculator {
|
||||
addPrecomputedOrbits(bodiesOrbits) {
|
||||
this._bodiesOrbits = bodiesOrbits;
|
||||
}
|
||||
setParameters(depAltitude, destAltitude, startDateMin, startDateMax, params) {
|
||||
this._depAltitude = depAltitude;
|
||||
this._destAltitude = destAltitude;
|
||||
this._startDateMin = startDateMin;
|
||||
this._startDateMax = startDateMax;
|
||||
setParameters(settings, params) {
|
||||
this._depAltitude = settings.depAltitude;
|
||||
this._destAltitude = settings.destAltitude;
|
||||
this._startDateMin = settings.startDate;
|
||||
this._startDateMax = settings.endDate;
|
||||
this._noInsertion = settings.noInsertion;
|
||||
this._params = params;
|
||||
this._getDepartureSettings();
|
||||
this._getLegsSettings();
|
||||
@@ -93,7 +94,9 @@ class TrajectoryCalculator {
|
||||
this._computeFirstLegArc(last);
|
||||
this._computeLegSecondArcSimple(last);
|
||||
this._computeInsertion();
|
||||
this._computeCircularization();
|
||||
if (!this._noInsertion) {
|
||||
this._computeCircularization();
|
||||
}
|
||||
}
|
||||
get totalDeltaV() {
|
||||
let total = 0;
|
||||
@@ -128,7 +131,8 @@ class TrajectoryCalculator {
|
||||
infos.duration = Math.max(minLegDuration, infos.duration);
|
||||
}
|
||||
computeStartingMeanAnomalies() {
|
||||
for (let i = 1; i < this.steps.length - 1; i++) {
|
||||
const k = this._noInsertion ? 0 : 1;
|
||||
for (let i = 1; i < this.steps.length - k; i++) {
|
||||
const step = this.steps[i];
|
||||
const { orbitElts, angles } = step;
|
||||
const e = orbitElts.eccentricity;
|
||||
@@ -189,7 +193,7 @@ class TrajectoryCalculator {
|
||||
const t_periapsisState = { pos: t_periPos, vel: t_periVel };
|
||||
const t_flybyOrbit = Physics3D.stateToOrbitElements(t_periapsisState, body);
|
||||
const enterAngle = Physics3D.trueAnomalyAtRadius(t_flybyOrbit, body.soi);
|
||||
const angles = { begin: -enterAngle, end: 0 };
|
||||
const angles = { begin: -enterAngle, end: this._noInsertion ? enterAngle : 0 };
|
||||
const drawAngles = { begin: angles.begin, end: angles.end };
|
||||
const t_incomingVel = Physics3D.orbitElementsToState(t_flybyOrbit, body, angles.begin).vel;
|
||||
const t_incomingVelDir = normalize3(t_incomingVel);
|
||||
@@ -201,6 +205,13 @@ class TrajectoryCalculator {
|
||||
const periapsisState = { pos: periPos, vel: periVel };
|
||||
const insertionOrbit = Physics3D.stateToOrbitElements(periapsisState, body);
|
||||
const tof = Physics3D.tofBetweenAnomalies(insertionOrbit, body, angles.begin, angles.end);
|
||||
const flybyDetails = {
|
||||
bodyId: body.id,
|
||||
soiEnterDate: this._lastStepEndDate,
|
||||
soiExitDate: this._lastStepEndDate + tof,
|
||||
periRadius: periRadius,
|
||||
inclination: insertionOrbit.inclination,
|
||||
};
|
||||
this.steps.push({
|
||||
orbitElts: insertionOrbit,
|
||||
attractorId: body.id,
|
||||
@@ -208,7 +219,8 @@ class TrajectoryCalculator {
|
||||
drawAngles: drawAngles,
|
||||
duration: tof,
|
||||
dateOfStart: this._lastStepEndDate,
|
||||
startM: 0
|
||||
startM: 0,
|
||||
flyby: this._noInsertion ? flybyDetails : undefined
|
||||
});
|
||||
this._vesselState = periapsisState;
|
||||
this._secondArcsData.push({
|
||||
|
||||
20
dist/dedicated-workers/trajectory-optimizer.js
vendored
20
dist/dedicated-workers/trajectory-optimizer.js
vendored
@@ -17,11 +17,8 @@ class TrajectoryOptimizer extends WorkerEnvironment {
|
||||
}
|
||||
}
|
||||
onWorkerDataPass(data) {
|
||||
this._depAltitude = data.depAltitude;
|
||||
this._destAltitude = data.destAltitude;
|
||||
this._sequence = data.sequence;
|
||||
this._startDateMin = data.startDateMin;
|
||||
this._startDateMax = data.startDateMax;
|
||||
this._settings = data.settings;
|
||||
}
|
||||
onWorkerRun(input) {
|
||||
this._newDeltaVs = [];
|
||||
@@ -35,11 +32,20 @@ class TrajectoryOptimizer extends WorkerEnvironment {
|
||||
this._bestTrajectory = trajectory;
|
||||
}
|
||||
const lastIdx = trajectory.steps.length - 1;
|
||||
const finalOrbit = trajectory.steps[lastIdx].orbitElts;
|
||||
const lastStep = trajectory.steps[lastIdx];
|
||||
const finalOrbit = lastStep.orbitElts;
|
||||
const totDV = trajectory.totalDeltaV;
|
||||
this._newDeltaVs.push(totDV);
|
||||
const lastInc = Math.abs(finalOrbit.inclination);
|
||||
return totDV + totDV * lastInc * 0.1;
|
||||
let periVelCost = 0;
|
||||
if (this._settings.noInsertion) {
|
||||
const finalBody = this._system[lastStep.attractorId];
|
||||
const periapsis = this._settings.destAltitude + finalBody.radius;
|
||||
const periVel = Physics3D.velocityAtRadius(finalOrbit, finalBody, periapsis);
|
||||
const circDV = periVel - Physics3D.circularVelocity(finalBody, periapsis);
|
||||
periVelCost = circDV;
|
||||
}
|
||||
return totDV + totDV * lastInc * 0.1 + periVelCost;
|
||||
};
|
||||
const trajConfig = this._config.trajectorySearch;
|
||||
const { diffWeight } = trajConfig;
|
||||
@@ -82,7 +88,7 @@ class TrajectoryOptimizer extends WorkerEnvironment {
|
||||
trajectory.addPrecomputedOrbits(this._bodiesOrbits);
|
||||
let attempts = 0;
|
||||
while (attempts < maxAttempts) {
|
||||
trajectory.setParameters(this._depAltitude, this._destAltitude, this._startDateMin, this._startDateMax, agent);
|
||||
trajectory.setParameters(this._settings, agent);
|
||||
let failed = false;
|
||||
try {
|
||||
trajectory.compute();
|
||||
|
||||
15
dist/main/editor/editor.js
vendored
15
dist/main/editor/editor.js
vendored
@@ -132,6 +132,8 @@ export async function initEditorWithSystem(systems, systemIndex) {
|
||||
};
|
||||
depAltitude.value = config.editor.defaultAltitude;
|
||||
destAltitude.value = config.editor.defaultAltitude;
|
||||
const noInsertionBox = document.getElementById("insertion-checkbox");
|
||||
noInsertionBox.checked = false;
|
||||
const customSequence = document.getElementById("custom-sequence");
|
||||
const deltaVPlot = new EvolutionPlot("evolution-plot");
|
||||
deltaVPlot.hide();
|
||||
@@ -195,8 +197,8 @@ export async function initEditorWithSystem(systems, systemIndex) {
|
||||
else
|
||||
sequence = sequenceSelector.sequence;
|
||||
updateAltitudeRange(depAltitude, sequence.bodies[0]);
|
||||
const seqLen = sequence.length;
|
||||
updateAltitudeRange(destAltitude, sequence.bodies[seqLen - 1]);
|
||||
const slen = sequence.length;
|
||||
updateAltitudeRange(destAltitude, sequence.bodies[slen - 1]);
|
||||
const startDate = timeRangeStart.dateSeconds;
|
||||
const endDate = timeRangeEnd.dateSeconds;
|
||||
if (endDate < startDate)
|
||||
@@ -204,8 +206,15 @@ export async function initEditorWithSystem(systems, systemIndex) {
|
||||
const depAltitudeVal = depAltitude.value * 1000;
|
||||
const destAltitudeVal = destAltitude.value * 1000;
|
||||
resetFoundTrajectory();
|
||||
const userSettings = {
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
depAltitude: depAltitudeVal,
|
||||
destAltitude: destAltitudeVal,
|
||||
noInsertion: noInsertionBox.checked
|
||||
};
|
||||
const perfStart = performance.now();
|
||||
await solver.searchOptimalTrajectory(sequence, startDate, endDate, depAltitudeVal, destAltitudeVal);
|
||||
await solver.searchOptimalTrajectory(sequence, userSettings);
|
||||
console.log(`Search time: ${performance.now() - perfStart} ms`);
|
||||
displayFoundTrajectory();
|
||||
}
|
||||
|
||||
10
dist/main/solvers/trajectory-solver.js
vendored
10
dist/main/solvers/trajectory-solver.js
vendored
@@ -30,12 +30,12 @@ export class TrajectorySolver {
|
||||
if (this._running)
|
||||
this._cancelled = true;
|
||||
}
|
||||
async searchOptimalTrajectory(sequence, startDateMin, startDateMax, depAltitude, destAltitude) {
|
||||
async searchOptimalTrajectory(sequence, settings) {
|
||||
this._running = true;
|
||||
this.plot.clearPlot();
|
||||
this._calculatePopulationSize(sequence);
|
||||
this._calculatePopulationChunks();
|
||||
await this._passSettingsData(sequence.ids, startDateMin, startDateMax, depAltitude, destAltitude);
|
||||
await this._passSettingsData(sequence, settings);
|
||||
await this._createStartPopulation();
|
||||
this._updatePlot(0);
|
||||
const { maxGenerations } = this.config.trajectorySearch;
|
||||
@@ -50,10 +50,8 @@ export class TrajectorySolver {
|
||||
}
|
||||
this._running = false;
|
||||
}
|
||||
async _passSettingsData(sequence, startDateMin, startDateMax, depAltitude, destAltitude) {
|
||||
return this._workerPool.passData({
|
||||
depAltitude, destAltitude, sequence, startDateMin, startDateMax
|
||||
});
|
||||
async _passSettingsData(sequence, settings) {
|
||||
return this._workerPool.passData({ sequence: sequence.ids, settings });
|
||||
}
|
||||
_calculatePopulationChunks() {
|
||||
const { splitLimit } = this.config.trajectorySearch;
|
||||
|
||||
8
dist/main/solvers/trajectory.js
vendored
8
dist/main/solvers/trajectory.js
vendored
@@ -284,13 +284,14 @@ export class Trajectory {
|
||||
date = missionStart;
|
||||
else if (date > missionEnd)
|
||||
date = missionEnd;
|
||||
const k = lastStep.flyby ? 0 : 1;
|
||||
let i = 1;
|
||||
for (; i < this.steps.length - 1; i++) {
|
||||
for (; i < this.steps.length - k; i++) {
|
||||
const { dateOfStart, duration } = this.steps[i];
|
||||
if (date >= dateOfStart && date < dateOfStart + duration)
|
||||
break;
|
||||
}
|
||||
i = Math.min(i, this.steps.length - 2);
|
||||
i = Math.min(i, this.steps.length - k - 1);
|
||||
const step = this.steps[i];
|
||||
const pod = this._spriteObjects[this._podSpriteIndex].pop();
|
||||
const curAttrId = this.steps[this._podSpriteIndex].attractorId;
|
||||
@@ -302,9 +303,8 @@ export class Trajectory {
|
||||
const newGroup = this.system.objectsOfBody(newAttrId);
|
||||
newGroup.add(pod);
|
||||
const orbit = this.orbits[i];
|
||||
const relDate = date - step.dateOfStart;
|
||||
const { startM } = step;
|
||||
const trueAnom = orbit.solveTrueAnomalyAtDate(startM, 0, relDate);
|
||||
const trueAnom = orbit.solveTrueAnomalyAtDate(startM, step.dateOfStart, date);
|
||||
const pos = orbit.positionFromTrueAnomaly(trueAnom);
|
||||
const { scale } = this.config.rendering;
|
||||
pod.position.set(pos.x, pos.y, pos.z);
|
||||
|
||||
@@ -171,6 +171,13 @@
|
||||
km (above surface level)
|
||||
</div>
|
||||
</div>
|
||||
<div id="insertion-checkbox-container">
|
||||
<div class="controls">
|
||||
<input name="insertion-checkbox" id="insertion-checkbox" type="checkbox">
|
||||
<label for="insertion-checkbox">No insertion burn</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sequence optimization buttons and messages -->
|
||||
<div class="form-actions">
|
||||
<button class="submit-btn" id="search-btn">Search trajectory</button>
|
||||
|
||||
@@ -11,6 +11,7 @@ class TrajectoryCalculator {
|
||||
private _destAltitude!: number;
|
||||
private _startDateMin!: number;
|
||||
private _startDateMax!: number;
|
||||
private _noInsertion!: boolean;
|
||||
private _params!: Agent;
|
||||
|
||||
private _bodiesOrbits!: OrbitalElements3D[];
|
||||
@@ -49,17 +50,12 @@ class TrajectoryCalculator {
|
||||
this._bodiesOrbits = bodiesOrbits;
|
||||
}
|
||||
|
||||
public setParameters(
|
||||
depAltitude: number,
|
||||
destAltitude: number,
|
||||
startDateMin: number,
|
||||
startDateMax: number,
|
||||
params: Agent
|
||||
){
|
||||
this._depAltitude = depAltitude;
|
||||
this._destAltitude = destAltitude;
|
||||
this._startDateMin = startDateMin;
|
||||
this._startDateMax = startDateMax;
|
||||
public setParameters(settings: TrajectoryUserSettings, params: Agent){
|
||||
this._depAltitude = settings.depAltitude;
|
||||
this._destAltitude = settings.destAltitude;
|
||||
this._startDateMin = settings.startDate;
|
||||
this._startDateMax = settings.endDate;
|
||||
this._noInsertion = settings.noInsertion;
|
||||
this._params = params;
|
||||
|
||||
this._getDepartureSettings();
|
||||
@@ -146,7 +142,9 @@ class TrajectoryCalculator {
|
||||
// Compute the insertion and circularization around
|
||||
// the destination body
|
||||
this._computeInsertion();
|
||||
this._computeCircularization();
|
||||
if(!this._noInsertion) {
|
||||
this._computeCircularization();
|
||||
}
|
||||
}
|
||||
|
||||
public get totalDeltaV(){
|
||||
@@ -195,7 +193,8 @@ class TrajectoryCalculator {
|
||||
}
|
||||
|
||||
public computeStartingMeanAnomalies(){
|
||||
for(let i = 1; i < this.steps.length-1; i++){ // ignore begin and end circular orbits
|
||||
const k = this._noInsertion ? 0 : 1;
|
||||
for(let i = 1; i < this.steps.length-k; i++){ // ignore begin and end circular (if insertion burn) orbits
|
||||
const step = this.steps[i];
|
||||
const {orbitElts, angles} = step;
|
||||
const e = orbitElts.eccentricity;
|
||||
@@ -296,7 +295,7 @@ class TrajectoryCalculator {
|
||||
|
||||
// Compute the SOI enter and exit angles
|
||||
const enterAngle = Physics3D.trueAnomalyAtRadius(t_flybyOrbit, body.soi);
|
||||
const angles = {begin: -enterAngle, end: 0};
|
||||
const angles = {begin: -enterAngle, end: this._noInsertion ? enterAngle : 0};
|
||||
const drawAngles = {begin: angles.begin, end: angles.end};
|
||||
|
||||
// Compute the angle between the incoming velocity vector and the velocity vector
|
||||
@@ -319,6 +318,15 @@ class TrajectoryCalculator {
|
||||
|
||||
// Compute the duration of the flyby
|
||||
const tof = Physics3D.tofBetweenAnomalies(insertionOrbit, body, angles.begin, angles.end);
|
||||
|
||||
// Flyby details in the case of no circularization
|
||||
const flybyDetails: FlybyInfo = {
|
||||
bodyId: body.id,
|
||||
soiEnterDate: this._lastStepEndDate,
|
||||
soiExitDate: this._lastStepEndDate + tof,
|
||||
periRadius: periRadius,
|
||||
inclination: insertionOrbit.inclination,
|
||||
};
|
||||
|
||||
// Append the insertion orbit
|
||||
this.steps.push({
|
||||
@@ -328,7 +336,8 @@ class TrajectoryCalculator {
|
||||
drawAngles: drawAngles,
|
||||
duration: tof,
|
||||
dateOfStart: this._lastStepEndDate,
|
||||
startM: 0
|
||||
startM: 0,
|
||||
flyby: this._noInsertion ? flybyDetails : undefined
|
||||
});
|
||||
|
||||
// Store the state of the vessel at periapsis for further
|
||||
|
||||
@@ -13,11 +13,8 @@ class TrajectoryOptimizer extends WorkerEnvironment {
|
||||
private _system!: IOrbitingBody[];
|
||||
private _bodiesOrbits!: OrbitalElements3D[];
|
||||
|
||||
private _depAltitude!: number;
|
||||
private _destAltitude!: number;
|
||||
private _sequence!: number[];
|
||||
private _startDateMin!: number;
|
||||
private _startDateMax!: number;
|
||||
private _settings!: TrajectoryUserSettings;
|
||||
|
||||
private _bestTrajectory!: TrajectoryCalculator;
|
||||
private _bestDeltaV!: number;
|
||||
@@ -41,11 +38,8 @@ class TrajectoryOptimizer extends WorkerEnvironment {
|
||||
}
|
||||
|
||||
override onWorkerDataPass(data: any){
|
||||
this._depAltitude = data.depAltitude;
|
||||
this._destAltitude = data.destAltitude;
|
||||
this._sequence = data.sequence;
|
||||
this._startDateMin = data.startDateMin;
|
||||
this._startDateMax = data.startDateMax;
|
||||
this._settings = data.settings;
|
||||
}
|
||||
|
||||
override onWorkerRun(input: any){
|
||||
@@ -67,17 +61,31 @@ class TrajectoryOptimizer extends WorkerEnvironment {
|
||||
|
||||
// Get the circular final orbit
|
||||
const lastIdx = trajectory.steps.length-1;
|
||||
const finalOrbit = trajectory.steps[lastIdx].orbitElts;
|
||||
const lastStep = trajectory.steps[lastIdx];
|
||||
const finalOrbit = lastStep.orbitElts;
|
||||
|
||||
const totDV = trajectory.totalDeltaV;
|
||||
this._newDeltaVs.push(totDV);
|
||||
|
||||
const lastInc = Math.abs(finalOrbit.inclination);
|
||||
|
||||
// If there is no circularization burn, try to minimize the velocity at the periapsis
|
||||
// of the arrival body by actually considering a circularization
|
||||
let periVelCost = 0;
|
||||
if(this._settings.noInsertion) {
|
||||
const finalBody = this._system[lastStep.attractorId];
|
||||
const periapsis = this._settings.destAltitude + finalBody.radius;
|
||||
const periVel = Physics3D.velocityAtRadius(finalOrbit, finalBody, periapsis);
|
||||
const circDV = periVel - Physics3D.circularVelocity(finalBody, periapsis);
|
||||
periVelCost = circDV;
|
||||
}
|
||||
|
||||
// Attempt to force a minimal inclination of the
|
||||
// circular orbit around the destination body
|
||||
// FIX : doesn't work so well...
|
||||
return totDV + totDV*lastInc*0.1;
|
||||
return totDV + totDV*lastInc*0.1 + periVelCost;
|
||||
};
|
||||
|
||||
const trajConfig = this._config.trajectorySearch;
|
||||
const {diffWeight} = trajConfig;
|
||||
const {minCrossProba, maxCrossProba} = trajConfig;
|
||||
@@ -138,13 +146,7 @@ class TrajectoryOptimizer extends WorkerEnvironment {
|
||||
// If an error occurs, the agent is randomized.
|
||||
let attempts = 0;
|
||||
while(attempts < maxAttempts){
|
||||
trajectory.setParameters(
|
||||
this._depAltitude,
|
||||
this._destAltitude,
|
||||
this._startDateMin,
|
||||
this._startDateMax,
|
||||
agent
|
||||
);
|
||||
trajectory.setParameters(this._settings, agent);
|
||||
let failed = false;
|
||||
// FIX: "This radius is never reached" error thrown... why ?
|
||||
try {
|
||||
|
||||
@@ -180,6 +180,10 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
|
||||
depAltitude.value = config.editor.defaultAltitude;
|
||||
destAltitude.value = config.editor.defaultAltitude;
|
||||
|
||||
// No insertion burn checkbox
|
||||
const noInsertionBox = document.getElementById("insertion-checkbox") as HTMLInputElement;
|
||||
noInsertionBox.checked = false;
|
||||
|
||||
// Custom sequence input
|
||||
const customSequence = document.getElementById("custom-sequence") as HTMLInputElement;
|
||||
|
||||
@@ -200,7 +204,7 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
|
||||
stepSlider.disable();
|
||||
|
||||
const getSpan = (id: string) => document.getElementById(id) as HTMLSpanElement;
|
||||
const getDiv = (id: string) => document.getElementById(id) as HTMLDivElement;
|
||||
const getDiv = (id: string) => document.getElementById(id) as HTMLDivElement;
|
||||
|
||||
const resultItems = {
|
||||
dateSpan: getSpan("maneuvre-date"),
|
||||
@@ -259,8 +263,8 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
|
||||
sequence = sequenceSelector.sequence;
|
||||
|
||||
updateAltitudeRange(depAltitude, sequence.bodies[0]);
|
||||
const seqLen = sequence.length;
|
||||
updateAltitudeRange(destAltitude, sequence.bodies[seqLen-1]);
|
||||
const slen = sequence.length;
|
||||
updateAltitudeRange(destAltitude, sequence.bodies[slen-1]);
|
||||
|
||||
const startDate = timeRangeStart.dateSeconds;
|
||||
const endDate = timeRangeEnd.dateSeconds;
|
||||
@@ -272,10 +276,16 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
|
||||
|
||||
resetFoundTrajectory();
|
||||
|
||||
const userSettings: TrajectoryUserSettings = {
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
depAltitude: depAltitudeVal,
|
||||
destAltitude: destAltitudeVal,
|
||||
noInsertion: noInsertionBox.checked
|
||||
};
|
||||
|
||||
const perfStart = performance.now();
|
||||
await solver.searchOptimalTrajectory(
|
||||
sequence, startDate, endDate, depAltitudeVal, destAltitudeVal
|
||||
);
|
||||
await solver.searchOptimalTrajectory(sequence, userSettings);
|
||||
console.log(`Search time: ${performance.now() - perfStart} ms`);
|
||||
|
||||
displayFoundTrajectory();
|
||||
@@ -284,6 +294,7 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
|
||||
if(err instanceof Error && err.message != "TRAJECTORY FINDER CANCELLED")
|
||||
paramsErr.show(err);
|
||||
console.error(err);
|
||||
|
||||
} finally {
|
||||
|
||||
systemSelector.enable();
|
||||
|
||||
@@ -38,13 +38,7 @@ export class TrajectorySolver {
|
||||
if(this._running) this._cancelled = true;
|
||||
}
|
||||
|
||||
public async searchOptimalTrajectory(
|
||||
sequence: FlybySequence,
|
||||
startDateMin: number,
|
||||
startDateMax: number,
|
||||
depAltitude: number,
|
||||
destAltitude: number
|
||||
){
|
||||
public async searchOptimalTrajectory(sequence: FlybySequence, settings: TrajectoryUserSettings){
|
||||
this._running = true;
|
||||
|
||||
this.plot.clearPlot()
|
||||
@@ -52,10 +46,7 @@ export class TrajectorySolver {
|
||||
this._calculatePopulationSize(sequence);
|
||||
this._calculatePopulationChunks();
|
||||
|
||||
await this._passSettingsData(
|
||||
sequence.ids, startDateMin, startDateMax, depAltitude, destAltitude
|
||||
);
|
||||
|
||||
await this._passSettingsData(sequence, settings);
|
||||
await this._createStartPopulation();
|
||||
this._updatePlot(0);
|
||||
|
||||
@@ -73,16 +64,8 @@ export class TrajectorySolver {
|
||||
this._running = false;
|
||||
}
|
||||
|
||||
private async _passSettingsData(
|
||||
sequence: number[],
|
||||
startDateMin: number,
|
||||
startDateMax: number,
|
||||
depAltitude: number,
|
||||
destAltitude: number
|
||||
){
|
||||
return this._workerPool.passData({
|
||||
depAltitude, destAltitude, sequence, startDateMin, startDateMax
|
||||
});
|
||||
private async _passSettingsData(sequence: FlybySequence, settings: TrajectoryUserSettings){
|
||||
return this._workerPool.passData({sequence: sequence.ids, settings});
|
||||
}
|
||||
|
||||
private _calculatePopulationChunks(){
|
||||
|
||||
@@ -404,13 +404,14 @@ export class Trajectory {
|
||||
else if(date > missionEnd) date = missionEnd;
|
||||
|
||||
// Get the step where the pod is at this date
|
||||
const k = lastStep.flyby ? 0 : 1; // ignore circular orbit if insertion burn occured
|
||||
let i = 1;
|
||||
for(; i < this.steps.length-1; i++){
|
||||
for(; i < this.steps.length-k; i++){
|
||||
const {dateOfStart, duration} = this.steps[i];
|
||||
if(date >= dateOfStart && date < dateOfStart + duration)
|
||||
break;
|
||||
}
|
||||
i = Math.min(i, this.steps.length-2);
|
||||
i = Math.min(i, this.steps.length-k-1);
|
||||
|
||||
const step = this.steps[i];
|
||||
|
||||
@@ -427,11 +428,10 @@ export class Trajectory {
|
||||
const newGroup = this.system.objectsOfBody(newAttrId);
|
||||
newGroup.add(pod);
|
||||
|
||||
// Compute its position on the leg arc where the pod is
|
||||
// Compute the position on the arc where the pod is
|
||||
const orbit = this.orbits[i];
|
||||
const relDate = date - step.dateOfStart;
|
||||
const {startM} = step;
|
||||
const trueAnom = orbit.solveTrueAnomalyAtDate(startM, 0, relDate);
|
||||
const trueAnom = orbit.solveTrueAnomalyAtDate(startM, step.dateOfStart, date);
|
||||
const pos = orbit.positionFromTrueAnomaly(trueAnom);
|
||||
|
||||
const {scale} = this.config.rendering;
|
||||
|
||||
8
src/types.d.ts
vendored
8
src/types.d.ts
vendored
@@ -296,6 +296,14 @@ type FlybyDetails = {
|
||||
inclinationDeg: number
|
||||
};
|
||||
|
||||
type TrajectoryUserSettings = {
|
||||
startDate: number,
|
||||
endDate: number,
|
||||
depAltitude: number,
|
||||
destAltitude: number,
|
||||
noInsertion: boolean
|
||||
};
|
||||
|
||||
type ResultPannelItems = {
|
||||
dateSpan: HTMLSpanElement,
|
||||
progradeDVSpan: HTMLSpanElement,
|
||||
|
||||
20
style.css
20
style.css
@@ -206,7 +206,7 @@ input[type="text"]::placeholder
|
||||
|
||||
.control-group .control-label
|
||||
{
|
||||
width: 190px;
|
||||
width: 140px;
|
||||
text-align: right;
|
||||
padding-right: 17px;
|
||||
}
|
||||
@@ -223,7 +223,7 @@ input[type="text"]::placeholder
|
||||
|
||||
.controls
|
||||
{
|
||||
width: 310px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.error-msg, .progress-msg
|
||||
@@ -451,6 +451,22 @@ input[type="range"]
|
||||
width: 413px;
|
||||
}
|
||||
|
||||
#insertion-checkbox-container
|
||||
{
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#insertion-checkbox-container .controls
|
||||
{
|
||||
margin-left: 157px;
|
||||
}
|
||||
|
||||
#insertion-checkbox
|
||||
{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Paragraphs */
|
||||
|
||||
p
|
||||
|
||||
Reference in New Issue
Block a user