mirror of
https://github.com/Krafpy/KSP-MGA-Planner.git
synced 2025-12-12 15:49:59 -08:00
Added trajectory duration limit (stock only)
A new trajectory setting has been added to the editor to enter the trajectory duration limit (in number of days). It adds a big cost to the DE algorithm if the duration of a trajectory is longer than the specified duration limit.
This commit is contained in:
@@ -62,6 +62,7 @@ editor:
|
||||
defaultOrigin: 3 # default origin body on start (index of Kerbin in the selector)
|
||||
defaultDest: 0 # default destination body on start (index of Moho in the selector)
|
||||
defaultAltitude: 100 # default altitude from the default body (in km above surface)
|
||||
defaultMaxDuration: 500 # default duration limit for a trajectory (in number of days)
|
||||
|
||||
workers:
|
||||
progressStep: 250 # number of inputs processed per chunk before progress callback
|
||||
|
||||
@@ -110,6 +110,11 @@ class TrajectoryCalculator {
|
||||
}
|
||||
return total;
|
||||
}
|
||||
get totalDuration() {
|
||||
const start = this.steps[0].dateOfStart;
|
||||
const end = this._lastStep.dateOfStart;
|
||||
return end - start;
|
||||
}
|
||||
_computeLegDuration(infos) {
|
||||
const exitedBody = this.system[infos.exitedBodyId];
|
||||
const { durationParam } = infos;
|
||||
|
||||
@@ -45,7 +45,10 @@ class TrajectoryOptimizer extends WorkerEnvironment {
|
||||
const circDV = periVel - Physics3D.circularVelocity(finalBody, periapsis);
|
||||
periVelCost = circDV;
|
||||
}
|
||||
return totDV + totDV * lastInc * 0.1 + periVelCost;
|
||||
const duration = trajectory.totalDuration;
|
||||
const durationOverflow = Math.max(0, duration - this._settings.maxDuration);
|
||||
const durationCost = durationOverflow * totDV;
|
||||
return totDV + totDV * lastInc * 0.1 + periVelCost + durationCost;
|
||||
};
|
||||
const trajConfig = this._config.trajectorySearch;
|
||||
const { diffWeight } = trajConfig;
|
||||
|
||||
18
dist/main/editor/editor.js
vendored
18
dist/main/editor/editor.js
vendored
@@ -136,6 +136,9 @@ export async function initEditorWithSystem(systems, systemIndex) {
|
||||
const timeRangeEnd = new TimeSelector("end", config);
|
||||
timeRangeStart.setToDefault();
|
||||
timeRangeEnd.setToDefault();
|
||||
const maxDuration = new IntegerInput("max-duration");
|
||||
maxDuration.setMinMax(1, Infinity);
|
||||
maxDuration.value = config.editor.defaultMaxDuration;
|
||||
const depAltitude = new IntegerInput("start-altitude");
|
||||
const destAltitude = new IntegerInput("end-altitude");
|
||||
const updateAltitudeRange = (input, body) => {
|
||||
@@ -247,13 +250,26 @@ export async function initEditorWithSystem(systems, systemIndex) {
|
||||
throw new Error("Departure date range end must be greater than the start date.");
|
||||
const depAltitudeVal = depAltitude.value * 1000;
|
||||
const destAltitudeVal = destAltitude.value * 1000;
|
||||
if (!maxDuration.validate()) {
|
||||
throw new Error("Invalid duration limit.");
|
||||
}
|
||||
let maxDurationSeconds;
|
||||
if (config.time.type == "base") {
|
||||
const { hoursPerDay } = config.time;
|
||||
const secondsPerDay = hoursPerDay * 3600;
|
||||
maxDurationSeconds = maxDuration.value * secondsPerDay;
|
||||
}
|
||||
else {
|
||||
maxDurationSeconds = maxDuration.value * 24 * 3600;
|
||||
}
|
||||
resetFoundTrajectory();
|
||||
const userSettings = {
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
depAltitude: depAltitudeVal,
|
||||
destAltitude: destAltitudeVal,
|
||||
noInsertion: noInsertionBox.checked
|
||||
noInsertion: noInsertionBox.checked,
|
||||
maxDuration: maxDurationSeconds
|
||||
};
|
||||
const perfStart = performance.now();
|
||||
await solver.searchOptimalTrajectory(sequence, userSettings);
|
||||
|
||||
@@ -176,6 +176,13 @@
|
||||
km (above surface level)
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="max-duration">Max duration:</label>
|
||||
<div class="controls">
|
||||
<input class="number-input" name="max-duration" id="max-duration" type="number" value="0" min="1">
|
||||
days
|
||||
</div>
|
||||
</div>
|
||||
<div id="insertion-checkbox-container">
|
||||
<div class="controls">
|
||||
<input name="insertion-checkbox" id="insertion-checkbox" type="checkbox">
|
||||
|
||||
@@ -160,6 +160,15 @@ class TrajectoryCalculator {
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the duration of the whole trajectory, in seconds.
|
||||
*/
|
||||
public get totalDuration(){
|
||||
const start = this.steps[0].dateOfStart;
|
||||
const end = this._lastStep.dateOfStart;
|
||||
return end - start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Completes the provided leg infos by calculating the leg duration from the already given
|
||||
* parameters
|
||||
|
||||
@@ -80,10 +80,15 @@ class TrajectoryOptimizer extends WorkerEnvironment {
|
||||
periVelCost = circDV;
|
||||
}
|
||||
|
||||
// Add a big cost value if the duration exceeds the duration limit.
|
||||
const duration = trajectory.totalDuration;
|
||||
const durationOverflow = Math.max(0, duration - this._settings.maxDuration);
|
||||
const durationCost = durationOverflow*totDV;
|
||||
|
||||
// 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 + periVelCost;
|
||||
return totDV + totDV*lastInc*0.1 + periVelCost + durationCost;
|
||||
};
|
||||
|
||||
const trajConfig = this._config.trajectorySearch;
|
||||
|
||||
@@ -180,6 +180,11 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
|
||||
timeRangeStart.setToDefault();
|
||||
timeRangeEnd.setToDefault();
|
||||
|
||||
// Max duration input
|
||||
const maxDuration = new IntegerInput("max-duration");
|
||||
maxDuration.setMinMax(1, Infinity);
|
||||
maxDuration.value = config.editor.defaultMaxDuration;
|
||||
|
||||
// Numerical inputs
|
||||
const depAltitude = new IntegerInput("start-altitude");
|
||||
const destAltitude = new IntegerInput("end-altitude");
|
||||
@@ -320,6 +325,19 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
|
||||
|
||||
const depAltitudeVal = depAltitude.value * 1000;
|
||||
const destAltitudeVal = destAltitude.value * 1000;
|
||||
|
||||
if(!maxDuration.validate()) {
|
||||
throw new Error("Invalid duration limit.");
|
||||
}
|
||||
|
||||
let maxDurationSeconds: number;
|
||||
if(config.time.type == "base") {
|
||||
const {hoursPerDay} = config.time;
|
||||
const secondsPerDay = hoursPerDay * 3600;
|
||||
maxDurationSeconds = maxDuration.value * secondsPerDay;
|
||||
} else {
|
||||
maxDurationSeconds = maxDuration.value * 24*3600;
|
||||
}
|
||||
|
||||
resetFoundTrajectory();
|
||||
|
||||
@@ -328,7 +346,8 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
|
||||
endDate: endDate,
|
||||
depAltitude: depAltitudeVal,
|
||||
destAltitude: destAltitudeVal,
|
||||
noInsertion: noInsertionBox.checked
|
||||
noInsertion: noInsertionBox.checked,
|
||||
maxDuration: maxDurationSeconds
|
||||
};
|
||||
|
||||
const perfStart = performance.now();
|
||||
|
||||
4
src/types.d.ts
vendored
4
src/types.d.ts
vendored
@@ -92,6 +92,7 @@ interface EditorSettings {
|
||||
readonly defaultOrigin: number;
|
||||
readonly defaultDest: number;
|
||||
readonly defaultAltitude: number;
|
||||
readonly defaultMaxDuration: number;
|
||||
}
|
||||
|
||||
interface WorkersSettings {
|
||||
@@ -317,7 +318,8 @@ type TrajectoryUserSettings = {
|
||||
endDate: number,
|
||||
depAltitude: number,
|
||||
destAltitude: number,
|
||||
noInsertion: boolean
|
||||
noInsertion: boolean,
|
||||
maxDuration: number
|
||||
};
|
||||
|
||||
type ResultPannelItems = {
|
||||
|
||||
Reference in New Issue
Block a user