mirror of
https://github.com/Krafpy/KSP-MGA-Planner.git
synced 2026-01-07 10:50:44 -08:00
- The 3D physics functions have been moved into a `Physics3D` namespace - The `TrajectoryCalculator` has been completely recoded and commented - The `TrajectoryOptimizer` has been recoded accordingly - Various optimizations focusing on reducing the number of costly function calls
89 lines
3.2 KiB
JavaScript
89 lines
3.2 KiB
JavaScript
"use strict";
|
|
importScripts("libs/common.js");
|
|
class SequenceGenerator extends WorkerEnvironment {
|
|
onWorkerInitialize(data) {
|
|
this._config = data;
|
|
}
|
|
onWorkerRun(input) {
|
|
const { bodies, params } = input;
|
|
this._bodies = bodies;
|
|
this._params = params;
|
|
this._toHigherOrbit = params.destinationId > params.departureId;
|
|
this._getRelativePositions();
|
|
const feasible = this._generateFeasibleSet();
|
|
sendResult(feasible);
|
|
}
|
|
_generateFeasibleSet() {
|
|
let incFeasibleSet = [{
|
|
sequence: [this._params.departureId],
|
|
resonant: 0,
|
|
backLegs: 0,
|
|
maxBackSpacing: 0
|
|
}];
|
|
let tempSet = [];
|
|
const feasibleSet = [];
|
|
const { maxEvalSequences } = this._config.flybySequence;
|
|
outerloop: while (incFeasibleSet.length > 0) {
|
|
for (const incSeq of incFeasibleSet) {
|
|
for (const bodyId of this._bodies) {
|
|
const tempSeq = {
|
|
sequence: [...incSeq.sequence, bodyId],
|
|
resonant: incSeq.resonant,
|
|
backLegs: incSeq.backLegs,
|
|
maxBackSpacing: incSeq.maxBackSpacing
|
|
};
|
|
this._updateSequenceInfo(tempSeq);
|
|
if (this._isSequenceValid(tempSeq)) {
|
|
if (bodyId == this._params.destinationId) {
|
|
feasibleSet.push(tempSeq.sequence);
|
|
if (feasibleSet.length >= maxEvalSequences)
|
|
break outerloop;
|
|
}
|
|
else {
|
|
tempSet.push(tempSeq);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
incFeasibleSet = tempSet;
|
|
tempSet = [];
|
|
}
|
|
return feasibleSet;
|
|
}
|
|
_getRelativePositions() {
|
|
const maxId = Math.max(...this._bodies);
|
|
const relativePos = Array(maxId + 1).fill(0);
|
|
for (let i = 0; i < this._bodies.length; ++i) {
|
|
relativePos[this._bodies[i]] = i;
|
|
}
|
|
this._relativePos = relativePos;
|
|
}
|
|
_isSequenceValid(info) {
|
|
const params = this._params;
|
|
const numSwingBys = info.sequence.length - 2;
|
|
if (numSwingBys > params.maxSwingBys)
|
|
return false;
|
|
if (info.resonant > params.maxResonant)
|
|
return false;
|
|
if (info.backLegs > params.maxBackLegs)
|
|
return false;
|
|
return info.maxBackSpacing <= params.maxBackSpacing;
|
|
}
|
|
_updateSequenceInfo(info) {
|
|
const { sequence } = info;
|
|
const len = sequence.length;
|
|
const pcur = this._relativePos[sequence[len - 1]];
|
|
const ppre = this._relativePos[sequence[len - 2]];
|
|
const toHO = this._toHigherOrbit;
|
|
if ((toHO && pcur < ppre) || (!toHO && pcur > ppre)) {
|
|
info.backLegs++;
|
|
const spacing = Math.abs(pcur - ppre);
|
|
const cur = info.maxBackSpacing;
|
|
info.maxBackSpacing = Math.max(cur, spacing);
|
|
}
|
|
if (pcur == ppre)
|
|
info.resonant++;
|
|
}
|
|
}
|
|
WorkerEnvironment.init(SequenceGenerator);
|