mirror of
https://github.com/Krafpy/KSP-MGA-Planner.git
synced 2025-12-12 07:40:41 -08:00
Merge pull request #36 from Krafpy/trajectory-duration-limit
Trajectory 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: 150 # 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
|
||||
|
||||
@@ -61,6 +61,7 @@ editor:
|
||||
defaultOrigin: 4 # 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
|
||||
|
||||
@@ -61,6 +61,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
|
||||
|
||||
@@ -60,6 +60,7 @@ editor:
|
||||
defaultOrigin: 2 # 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: 300 # 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
|
||||
|
||||
@@ -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;
|
||||
|
||||
27
dist/main/editor/editor.js
vendored
27
dist/main/editor/editor.js
vendored
@@ -144,6 +144,15 @@ export async function initEditorWithSystem(systems, systemIndex) {
|
||||
};
|
||||
depAltitude.value = config.editor.defaultAltitude;
|
||||
destAltitude.value = config.editor.defaultAltitude;
|
||||
const maxDuration = new IntegerInput("max-duration");
|
||||
maxDuration.setMinMax(1, Infinity);
|
||||
maxDuration.value = config.editor.defaultMaxDuration;
|
||||
const useMaxDuration = document.getElementById("use-max-duration");
|
||||
const updateUseMaxDuration = () => {
|
||||
maxDuration.element.disabled = !useMaxDuration.checked;
|
||||
};
|
||||
useMaxDuration.onchange = updateUseMaxDuration;
|
||||
updateUseMaxDuration();
|
||||
const noInsertionBox = document.getElementById("insertion-checkbox");
|
||||
noInsertionBox.checked = false;
|
||||
const customSequence = document.getElementById("custom-sequence");
|
||||
@@ -247,13 +256,29 @@ 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 = Infinity;
|
||||
if (useMaxDuration.checked) {
|
||||
if (config.time.type == "base") {
|
||||
const { hoursPerDay } = config.time;
|
||||
const secondsPerDay = hoursPerDay * 3600;
|
||||
maxDurationSeconds = maxDuration.value * secondsPerDay;
|
||||
}
|
||||
else {
|
||||
maxDurationSeconds = maxDuration.value * 24 * 3600;
|
||||
}
|
||||
}
|
||||
console.log(maxDurationSeconds);
|
||||
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);
|
||||
|
||||
17
index.html
17
index.html
@@ -176,6 +176,14 @@
|
||||
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
|
||||
<input name="use-max-duration" id="use-max-duration" type="checkbox">
|
||||
</div>
|
||||
</div>
|
||||
<div id="insertion-checkbox-container">
|
||||
<div class="controls">
|
||||
<input name="insertion-checkbox" id="insertion-checkbox" type="checkbox">
|
||||
@@ -421,6 +429,15 @@
|
||||
<strong>Departure and destination altitude:</strong> the altitude of the parking orbit
|
||||
around the departure and destination body.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Max duration:</strong> if checked, forces the trajectory solver to try not to exceed the
|
||||
specified maximum duration (in number of days). Note that it may give a trajectory that exceeds the
|
||||
limit if it cannot find shorter ones.
|
||||
</li>
|
||||
<li>
|
||||
<strong>No insertion burn:</strong> if checked, ignores circularization at the destination body and
|
||||
instead do a flyby at arrival.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
The trajectory search step will then <em>try</em> to find <em>a possible</em> optimal trajectory given the sequence and the
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -192,6 +192,18 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
|
||||
depAltitude.value = config.editor.defaultAltitude;
|
||||
destAltitude.value = config.editor.defaultAltitude;
|
||||
|
||||
// Max duration input
|
||||
const maxDuration = new IntegerInput("max-duration");
|
||||
maxDuration.setMinMax(1, Infinity);
|
||||
maxDuration.value = config.editor.defaultMaxDuration;
|
||||
|
||||
const useMaxDuration = document.getElementById("use-max-duration") as HTMLInputElement;
|
||||
const updateUseMaxDuration = () => {
|
||||
maxDuration.element.disabled = !useMaxDuration.checked;
|
||||
};
|
||||
useMaxDuration.onchange = updateUseMaxDuration;
|
||||
updateUseMaxDuration();
|
||||
|
||||
// No insertion burn checkbox
|
||||
const noInsertionBox = document.getElementById("insertion-checkbox") as HTMLInputElement;
|
||||
noInsertionBox.checked = false;
|
||||
@@ -320,6 +332,22 @@ 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 = Infinity;
|
||||
if(useMaxDuration.checked){
|
||||
if(config.time.type == "base") {
|
||||
const {hoursPerDay} = config.time;
|
||||
const secondsPerDay = hoursPerDay * 3600;
|
||||
maxDurationSeconds = maxDuration.value * secondsPerDay;
|
||||
} else {
|
||||
maxDurationSeconds = maxDuration.value * 24*3600;
|
||||
}
|
||||
}
|
||||
console.log(maxDurationSeconds);
|
||||
|
||||
resetFoundTrajectory();
|
||||
|
||||
@@ -328,7 +356,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