Merge pull request #36 from Krafpy/trajectory-duration-limit

Trajectory duration limit
This commit is contained in:
Nazar Misyats
2023-05-25 20:12:18 +02:00
committed by GitHub
13 changed files with 105 additions and 5 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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
View File

@@ -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 = {