Added custom sequence input.

This commit is contained in:
Krafpy
2021-08-21 00:47:28 +02:00
parent 1af6e1c45b
commit 5f6c1b8a53
8 changed files with 132 additions and 12 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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