mirror of
https://github.com/Krafpy/KSP-MGA-Planner.git
synced 2025-12-12 07:40:41 -08:00
Added custom sequence input.
This commit is contained in:
10
dist/main/editor/editor.js
vendored
10
dist/main/editor/editor.js
vendored
@@ -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;
|
||||
|
||||
2
dist/main/solvers/sequence-solver.js
vendored
2
dist/main/solvers/sequence-solver.js
vendored
@@ -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;
|
||||
|
||||
32
dist/main/solvers/sequence.js
vendored
32
dist/main/solvers/sequence.js
vendored
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
14
index.html
14
index.html
@@ -97,13 +97,20 @@
|
||||
<p class="error-msg" id="sequence-params-error" hidden><strong>Error:</strong> <span></span></p>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="sequence-selector">Flyby sequence:</label>
|
||||
<label class="control-label" for="sequence-selector">Generated sequence:</label>
|
||||
<div class="controls">
|
||||
<select name="sequence-selector" id="sequence-selector" disabled>
|
||||
<!-- filled by js -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="custom-sequence-group">
|
||||
<label class="control-label" for="custom-sequence">Custom sequence:</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="custom-sequence" name="custom-sequence" placeholder="Leave empty to ignore">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End of flyby sequence configuration panel -->
|
||||
|
||||
@@ -325,6 +332,11 @@
|
||||
this back leg has a spacing of 1.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
|
||||
<h3>Trajectory calculation</h3>
|
||||
<p>
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
37
style.css
37
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
|
||||
|
||||
Reference in New Issue
Block a user