mirror of
https://github.com/Krafpy/KSP-MGA-Planner.git
synced 2025-12-12 15:49:59 -08:00
Trajectory evaluation fix and time display.
- Moved the second leg arc recalculation to the evaluation fonction, so it is always calculated for every trajectories, not the bes one only. It led to wrong "best" deltaV calculations. - Fixed the accuracy of the system time when clicking on a date displayed in maneuver details.
This commit is contained in:
@@ -8,7 +8,6 @@ class TrajectoryCalculator {
|
||||
this._legs = [];
|
||||
this._flybys = [];
|
||||
this._secondArcsData = [];
|
||||
this.totalDeltaV = 0;
|
||||
this.mathError = false;
|
||||
const attractorId = this._departureBody.orbiting;
|
||||
this._mainAttractor = this.system[attractorId];
|
||||
@@ -97,14 +96,18 @@ class TrajectoryCalculator {
|
||||
this.mathError = this._hasNaNValues();
|
||||
if (this.mathError)
|
||||
return;
|
||||
}
|
||||
get totalDeltaV() {
|
||||
let total = 0;
|
||||
for (const step of this.steps) {
|
||||
if (!step.maneuvre)
|
||||
continue;
|
||||
const { maneuvre } = step;
|
||||
const { deltaVToPrevStep } = maneuvre;
|
||||
const dv = mag3(deltaVToPrevStep);
|
||||
this.totalDeltaV += dv;
|
||||
if (step.maneuvre) {
|
||||
const { maneuvre } = step;
|
||||
const { deltaVToPrevStep } = maneuvre;
|
||||
const dv = mag3(deltaVToPrevStep);
|
||||
total += dv;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
_hasNaNValues() {
|
||||
const hasNaN = obj => {
|
||||
@@ -180,7 +183,7 @@ class TrajectoryCalculator {
|
||||
lambertStep.angles = angles;
|
||||
lambertStep.drawAngles = drawAngles;
|
||||
const maneuvre = lambertStep.maneuvre;
|
||||
const dsmDV = sub3(v1, preDSMState.vel);
|
||||
const dsmDV = sub3(postDSMState.vel, preDSMState.vel);
|
||||
maneuvre.deltaVToPrevStep = dsmDV;
|
||||
}
|
||||
_computeFlyby(flybyInfo) {
|
||||
|
||||
@@ -36,7 +36,6 @@ class TrajectoryOptimizer extends WorkerEnvironment {
|
||||
this._bestDeltaV = Infinity;
|
||||
const popChunk = this._evolver.createRandomPopulationChunk();
|
||||
const dvChunk = this._evolver.evaluateChunkFitness(popChunk);
|
||||
this._bestTrajectory.recomputeLegsSecondArcs();
|
||||
sendResult({
|
||||
bestSteps: this._bestTrajectory.steps,
|
||||
bestDeltaV: this._bestDeltaV,
|
||||
@@ -47,7 +46,6 @@ class TrajectoryOptimizer extends WorkerEnvironment {
|
||||
else {
|
||||
const { population, deltaVs } = input;
|
||||
const { popChunk, fitChunk } = this._evolver.evolvePopulationChunk(population, deltaVs);
|
||||
this._bestTrajectory.recomputeLegsSecondArcs();
|
||||
sendResult({
|
||||
popChunk, fitChunk,
|
||||
bestSteps: this._bestTrajectory.steps,
|
||||
@@ -65,6 +63,7 @@ class TrajectoryOptimizer extends WorkerEnvironment {
|
||||
let failed = false;
|
||||
try {
|
||||
trajectory.compute();
|
||||
trajectory.recomputeLegsSecondArcs();
|
||||
}
|
||||
catch {
|
||||
failed = true;
|
||||
|
||||
2
dist/main/editor/editor.js
vendored
2
dist/main/editor/editor.js
vendored
@@ -124,7 +124,7 @@ export function initEditor(controls, system, config, canvas) {
|
||||
const displayFoundTrajectory = () => {
|
||||
trajectory = new Trajectory(solver.bestTrajectorySteps, system, config);
|
||||
trajectory.draw(canvas);
|
||||
trajectory.fillResultControls(maneuvreSelector, resultSpans, stepSlider, systemTime);
|
||||
trajectory.fillResultControls(maneuvreSelector, resultSpans, stepSlider, systemTime, controls);
|
||||
maneuvreSelector.select(0);
|
||||
maneuvreSelector.enable();
|
||||
stepSlider.enable();
|
||||
|
||||
14
dist/main/solvers/trajectory.js
vendored
14
dist/main/solvers/trajectory.js
vendored
@@ -84,14 +84,15 @@ export class Trajectory {
|
||||
}
|
||||
}
|
||||
}
|
||||
fillResultControls(maneuvreSelector, resultSpans, stepSlider, systemTime) {
|
||||
fillResultControls(maneuvreSelector, resultSpans, stepSlider, systemTime, controls) {
|
||||
const depDate = new KSPTime(this.steps[0].dateOfStart, this.config.time);
|
||||
resultSpans.totalDVSpan.innerHTML = this._totalDeltaV.toFixed(1);
|
||||
resultSpans.depDateSpan.innerHTML = depDate.stringYDHMS("hms", "ut");
|
||||
resultSpans.depDateSpan.onclick = () => {
|
||||
this.system.date = depDate.dateSeconds;
|
||||
controls.centerOnTarget();
|
||||
systemTime.time.dateSeconds = depDate.dateSeconds;
|
||||
systemTime.update();
|
||||
systemTime.onChange();
|
||||
};
|
||||
stepSlider.setMinMax(0, this.steps.length - 1);
|
||||
stepSlider.input((index) => this._displayStepsUpTo(index));
|
||||
@@ -128,11 +129,16 @@ export class Trajectory {
|
||||
resultSpans.radialDVSpan.innerHTML = details.radialDV.toFixed(1);
|
||||
resultSpans.maneuvreNumber.innerHTML = (index + 1).toString();
|
||||
resultSpans.dateSpan.onclick = () => {
|
||||
systemTime.time.dateSeconds = depDate.dateSeconds + dateEMT.dateSeconds;
|
||||
const date = depDate.dateSeconds + dateEMT.dateSeconds;
|
||||
this.system.date = date;
|
||||
controls.centerOnTarget();
|
||||
systemTime.time.dateSeconds = date;
|
||||
systemTime.update();
|
||||
systemTime.onChange();
|
||||
};
|
||||
});
|
||||
for (const step of this.steps) {
|
||||
console.log(step);
|
||||
}
|
||||
}
|
||||
_displayStepsUpTo(index) {
|
||||
for (let i = 0; i < this.steps.length; i++) {
|
||||
|
||||
BIN
imgs/jool_system_trajectory.png
Normal file
BIN
imgs/jool_system_trajectory.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@@ -20,8 +20,6 @@ class TrajectoryCalculator {
|
||||
|
||||
private _secondArcsData: SecondArcData[] = [];
|
||||
|
||||
public totalDeltaV: number = 0;
|
||||
|
||||
public mathError: boolean = false;
|
||||
|
||||
constructor(public readonly system: IOrbitingBody[], public readonly config: TrajectorySearchSettings, public readonly sequence: number[]){
|
||||
@@ -145,16 +143,19 @@ class TrajectoryCalculator {
|
||||
this.mathError = this._hasNaNValues();
|
||||
if(this.mathError)
|
||||
return;
|
||||
}
|
||||
|
||||
// Computes the total deltaV from the maneuvers
|
||||
public get totalDeltaV(){
|
||||
let total = 0;
|
||||
for(const step of this.steps){
|
||||
if(!step.maneuvre)
|
||||
continue;
|
||||
const {maneuvre} = step;
|
||||
const {deltaVToPrevStep} = maneuvre;
|
||||
const dv = mag3(deltaVToPrevStep);
|
||||
this.totalDeltaV += dv;
|
||||
if(step.maneuvre) {
|
||||
const {maneuvre} = step;
|
||||
const {deltaVToPrevStep} = maneuvre;
|
||||
const dv = mag3(deltaVToPrevStep);
|
||||
total += dv;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -266,7 +267,7 @@ class TrajectoryCalculator {
|
||||
lambertStep.drawAngles = drawAngles;
|
||||
|
||||
const maneuvre = lambertStep.maneuvre as ManeuvreInfo;
|
||||
const dsmDV = sub3(v1, preDSMState.vel);
|
||||
const dsmDV = sub3(postDSMState.vel, preDSMState.vel);
|
||||
maneuvre.deltaVToPrevStep = dsmDV;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,6 @@ class TrajectoryOptimizer extends WorkerEnvironment {
|
||||
// Create the first generation and evaluate it
|
||||
const popChunk = this._evolver.createRandomPopulationChunk();
|
||||
const dvChunk = this._evolver.evaluateChunkFitness(popChunk);
|
||||
this._bestTrajectory.recomputeLegsSecondArcs();
|
||||
sendResult({
|
||||
bestSteps: this._bestTrajectory.steps,
|
||||
bestDeltaV: this._bestDeltaV,
|
||||
@@ -77,7 +76,6 @@ class TrajectoryOptimizer extends WorkerEnvironment {
|
||||
// If not the first generation, then evolve the current population
|
||||
const {population, deltaVs} = input;
|
||||
const {popChunk, fitChunk} = this._evolver.evolvePopulationChunk(population, deltaVs);
|
||||
this._bestTrajectory.recomputeLegsSecondArcs();
|
||||
sendResult({
|
||||
popChunk, fitChunk,
|
||||
bestSteps: this._bestTrajectory.steps,
|
||||
@@ -108,6 +106,7 @@ class TrajectoryOptimizer extends WorkerEnvironment {
|
||||
// FIX: "This radius is never reached" error thrown... why ?
|
||||
try {
|
||||
trajectory.compute();
|
||||
trajectory.recomputeLegsSecondArcs();
|
||||
} catch {
|
||||
failed = true;
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ export function initEditor(controls: CameraController, system: SolarSystem, conf
|
||||
const displayFoundTrajectory = () => {
|
||||
trajectory = new Trajectory(solver.bestTrajectorySteps, system, config);
|
||||
trajectory.draw(canvas);
|
||||
trajectory.fillResultControls(maneuvreSelector, resultSpans, stepSlider, systemTime);
|
||||
trajectory.fillResultControls(maneuvreSelector, resultSpans, stepSlider, systemTime, controls);
|
||||
|
||||
maneuvreSelector.select(0);
|
||||
maneuvreSelector.enable();
|
||||
|
||||
@@ -60,7 +60,7 @@ export class TrajectorySolver {
|
||||
await this._generateNextPopulation();
|
||||
this._updatePlot(1 + i);
|
||||
}
|
||||
|
||||
|
||||
this._running = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { createOrbitPoints, createLine, createSprite } from "../utilities/geomet
|
||||
import { Orbit } from "../objects/orbit.js";
|
||||
import { SolarSystem } from "../objects/system.js";
|
||||
import { KSPTime } from "../utilities/time.js";
|
||||
import { CameraController } from "../objects/camera.js";
|
||||
|
||||
export class Trajectory {
|
||||
public readonly orbits: Orbit[] = [];
|
||||
@@ -109,16 +110,17 @@ export class Trajectory {
|
||||
}
|
||||
}
|
||||
|
||||
public fillResultControls(maneuvreSelector: Selector, resultSpans: ResultPanelSpans, stepSlider: DiscreteRange, systemTime: TimeSelector){
|
||||
public fillResultControls(maneuvreSelector: Selector, resultSpans: ResultPanelSpans, stepSlider: DiscreteRange, systemTime: TimeSelector, controls: CameraController){
|
||||
const depDate = new KSPTime(this.steps[0].dateOfStart, this.config.time);
|
||||
|
||||
resultSpans.totalDVSpan.innerHTML = this._totalDeltaV.toFixed(1);
|
||||
resultSpans.depDateSpan.innerHTML = depDate.stringYDHMS("hms", "ut");
|
||||
|
||||
resultSpans.depDateSpan.onclick = () => {
|
||||
this.system.date = depDate.dateSeconds;
|
||||
controls.centerOnTarget();
|
||||
systemTime.time.dateSeconds = depDate.dateSeconds;
|
||||
systemTime.update();
|
||||
systemTime.onChange();
|
||||
};
|
||||
|
||||
stepSlider.setMinMax(0, this.steps.length - 1);
|
||||
@@ -158,11 +160,17 @@ export class Trajectory {
|
||||
resultSpans.maneuvreNumber.innerHTML = (index + 1).toString();
|
||||
|
||||
resultSpans.dateSpan.onclick = () => {
|
||||
systemTime.time.dateSeconds = depDate.dateSeconds + dateEMT.dateSeconds;
|
||||
const date = depDate.dateSeconds + dateEMT.dateSeconds;
|
||||
this.system.date = date;
|
||||
controls.centerOnTarget();
|
||||
systemTime.time.dateSeconds = date;
|
||||
systemTime.update();
|
||||
systemTime.onChange();
|
||||
};
|
||||
});
|
||||
|
||||
for(const step of this.steps){
|
||||
console.log(step);
|
||||
}
|
||||
}
|
||||
|
||||
private _displayStepsUpTo(index: number){
|
||||
|
||||
Reference in New Issue
Block a user