diff --git a/dist/main/editor/editor.js b/dist/main/editor/editor.js index c952556..7be30ca 100644 --- a/dist/main/editor/editor.js +++ b/dist/main/editor/editor.js @@ -8,6 +8,7 @@ import { EvolutionPlot } from "./plot.js"; import { ProgressMessage } from "./progress-msg.js"; import { SequenceSelector } from "./sequence-selector.js"; import { SubmitButton, StopButton } from "./buttons.js"; +import { FlybySequence } from "../solvers/sequence.js"; import { Trajectory } from "../solvers/trajectory.js"; import { Selector } from "./selector.js"; import { DiscreteRange } from "./range.js"; @@ -92,6 +93,7 @@ export function initEditor(controls, system, config, canvas) { depAltitude.setMinMax(0, max); }; depAltitude.value = config.editor.defaultAltitude; + const customSequence = document.getElementById("custom-sequence"); const deltaVPlot = new EvolutionPlot("evolution-plot"); deltaVPlot.hide(); const solver = new TrajectorySolver(system, config, deltaVPlot); @@ -131,7 +133,13 @@ export function initEditor(controls, system, config, canvas) { const findTrajectory = async () => { paramsErr.hide(); try { - const sequence = sequenceSelector.sequence; + let sequence; + if (customSequence.value == "") { + sequence = sequenceSelector.sequence; + } + else { + sequence = FlybySequence.fromString(customSequence.value, system); + } updateAltitudeRange(sequence); const startDate = timeRangeStart.dateSeconds; const endDate = timeRangeEnd.dateSeconds; diff --git a/dist/main/solvers/sequence-solver.js b/dist/main/solvers/sequence-solver.js index bc881d4..bf1fddf 100644 --- a/dist/main/solvers/sequence-solver.js +++ b/dist/main/solvers/sequence-solver.js @@ -26,7 +26,7 @@ export class FlybySequenceGenerator { const sequences = []; for (let i = 0; i < Math.min(maxPropositions, evaluations.length); i++) { const result = evaluations[i]; - const sequence = new FlybySequence(this.system, feasibleSet[result.seq], result.cost); + const sequence = new FlybySequence(this.system, feasibleSet[result.seq]); sequences.push(sequence); } return sequences; diff --git a/dist/main/solvers/sequence.js b/dist/main/solvers/sequence.js index 52da042..e110517 100644 --- a/dist/main/solvers/sequence.js +++ b/dist/main/solvers/sequence.js @@ -1,7 +1,6 @@ export class FlybySequence { - constructor(system, ids, cost) { + constructor(system, ids) { this.ids = ids; - this.cost = cost; this.bodies = []; for (const id of ids) { this.bodies.push(system.bodyFromId(id)); @@ -14,4 +13,33 @@ export class FlybySequence { } this.seqString = str; } + static fromString(str, system) { + str = str.trim(); + const initials = str.split('-'); + const ids = []; + let attractor = 0; + for (let i = 0; i < initials.length; i++) { + let valid = false; + for (const body of system.orbiting) { + if (body.name.substring(0, 2) == initials[i]) { + if (i == 0) { + attractor = body.attractor.id; + } + else if (body.attractor.id != attractor) { + throw "All bodies of the sequence must orbit around the same body."; + } + ids.push(body.id); + valid = true; + break; + } + } + if (!valid) { + throw "Invalid custom sequence input."; + } + } + if (ids.length <= 1) { + throw "The sequence must contain at least two bodies."; + } + return new FlybySequence(system, ids); + } } diff --git a/index.html b/index.html index e652c97..9748c15 100644 --- a/index.html +++ b/index.html @@ -97,13 +97,20 @@
Error:
+ Alternatively, it is possible to set a custom sequence if no interesting sequences is proposed by the generator, + or to define custom routes. The input text must be a valid sequence representation. + The trajectory calculation step will choose the custom sequence first if defined. +
diff --git a/src/main/editor/editor.ts b/src/main/editor/editor.ts index 8c69716..4ac4943 100644 --- a/src/main/editor/editor.ts +++ b/src/main/editor/editor.ts @@ -108,7 +108,7 @@ export function initEditor(controls: CameraController, system: SolarSystem, conf new StopButton("sequence-stop-btn").click(() => generator.cancel()); } - { + { // Time inputs const timeRangeStart = new TimeSelector("start", config, true); const timeRangeEnd = new TimeSelector("end", config, true); @@ -121,6 +121,9 @@ export function initEditor(controls: CameraController, system: SolarSystem, conf depAltitude.setMinMax(0, max); }; depAltitude.value = config.editor.defaultAltitude; + + // Custom sequence input + const customSequence = document.getElementById("custom-sequence") as HTMLInputElement; // Trajectory solver const deltaVPlot = new EvolutionPlot("evolution-plot"); @@ -172,7 +175,12 @@ export function initEditor(controls: CameraController, system: SolarSystem, conf const findTrajectory = async () => { paramsErr.hide(); try { - const sequence = sequenceSelector.sequence; + let sequence: FlybySequence; + if(customSequence.value == ""){ + sequence = sequenceSelector.sequence; + } else { + sequence = FlybySequence.fromString(customSequence.value, system); + } updateAltitudeRange(sequence); diff --git a/src/main/solvers/sequence-solver.ts b/src/main/solvers/sequence-solver.ts index 7ae5bd9..4b1838c 100644 --- a/src/main/solvers/sequence-solver.ts +++ b/src/main/solvers/sequence-solver.ts @@ -37,7 +37,7 @@ export class FlybySequenceGenerator { const sequences: FlybySequence[] = []; for(let i = 0; i < Math.min(maxPropositions, evaluations.length); i++){ const result = evaluations[i]; - const sequence = new FlybySequence(this.system, feasibleSet[result.seq], result.cost); + const sequence = new FlybySequence(this.system, feasibleSet[result.seq]); sequences.push(sequence); } diff --git a/src/main/solvers/sequence.ts b/src/main/solvers/sequence.ts index 460a4a7..6703bf8 100644 --- a/src/main/solvers/sequence.ts +++ b/src/main/solvers/sequence.ts @@ -6,7 +6,7 @@ export class FlybySequence { public readonly length!: number; public readonly seqString!: string; - constructor(system: SolarSystem, public readonly ids: number[], public readonly cost: number) { + constructor(system: SolarSystem, public readonly ids: number[]) { this.bodies = []; for(const id of ids){ this.bodies.push(system.bodyFromId(id) as OrbitingBody); @@ -20,4 +20,37 @@ export class FlybySequence { } this.seqString = str; } + + static fromString(str: string, system: SolarSystem){ + str = str.trim(); + const initials = str.split('-'); + const ids: number[] = []; + + let attractor = 0; + + for(let i = 0; i < initials.length; i++){ + let valid = false; + for(const body of system.orbiting){ + if(body.name.substring(0, 2) == initials[i]){ + if(i == 0) { + attractor = body.attractor.id; + } else if(body.attractor.id != attractor) { + throw "All bodies of the sequence must orbit around the same body."; + } + ids.push(body.id); + valid = true; + break; + } + } + if(!valid){ + throw "Invalid custom sequence input."; + } + } + + if(ids.length <= 1){ + throw "The sequence must contain at least two bodies."; + } + + return new FlybySequence(system, ids); + } } \ No newline at end of file diff --git a/style.css b/style.css index 5ec60a9..d2d942d 100644 --- a/style.css +++ b/style.css @@ -56,7 +56,7 @@ strong display: inline-block; margin-left: auto; margin-right: auto; - max-width: 1155px; + max-width: 1175px; margin-top: 30px; } @@ -91,7 +91,7 @@ strong #calculator-panel { margin-right: 30px; - min-width: 375px; + min-width: 395px; } #calculator-panel h2 @@ -171,6 +171,27 @@ input[type=number]::-webkit-inner-spin-button { opacity: 0.5; } +input[type="text"] +{ + box-sizing: border-box; + width: 15em; + font-size: inherit; + border: 1px solid black; + background-color: #222425; + scrollbar-color: #3b4042 #222425; + color: inherit; + border-color: rgb(67, 73, 76); + height: 2em; + padding-left: 5px; + padding-right: 5px; +} + +input[type="text"]::placeholder +{ + font-style: italic; + opacity: 0.25; +} + .control-group { margin-bottom: 10px; @@ -185,7 +206,7 @@ input[type=number]::-webkit-inner-spin-button { .control-group .control-label { - width: 120px; + width: 190px; text-align: right; padding-right: 17px; } @@ -200,6 +221,11 @@ input[type=number]::-webkit-inner-spin-button { width: 5em; } +.controls +{ + width: 310px; +} + .error-msg, .progress-msg { max-width: 356px; @@ -210,6 +236,11 @@ input[type=number]::-webkit-inner-spin-button { margin-top: 25px; } +#custom-sequence-group +{ + margin-top: 15px; +} + /* Editor forms' action buttons */ .form-actions