Option to show dates as elapsed time

Added a checkbox which changes the display of dates (UT, not MET)
from Year/Day starting at 1 but elapsed Years/elapsed Days starting
at 0 (T+). This has no effect on the solar system that use
real time (like RSS).
This commit is contained in:
Krafpy
2023-08-08 16:41:52 +02:00
parent 1a90651448
commit 4c02161e43
16 changed files with 180 additions and 73 deletions

View File

@@ -42,7 +42,9 @@ export async function initEditorWithSystem(systems, systemIndex) {
renderer.render(scene, camera);
};
requestAnimationFrame(loop);
const systemTime = new TimeSelector("system", config);
const datesAsElapsedCheckbox = document.getElementById("date-as-elapsed-checkbox");
const initialDateDisplayMode = datesAsElapsedCheckbox.checked ? "elapsed" : "offset";
const systemTime = new TimeSelector("system", config, initialDateDisplayMode);
const updateSystemTime = () => {
if (systemTime.validate()) {
system.date = systemTime.dateSeconds;
@@ -132,10 +134,22 @@ export async function initEditorWithSystem(systems, systemIndex) {
seqStopBtn.click(() => generator.cancel());
}
{
const timeRangeStart = new TimeSelector("start", config);
const timeRangeEnd = new TimeSelector("end", config);
const timeRangeStart = new TimeSelector("start", config, initialDateDisplayMode);
const timeRangeEnd = new TimeSelector("end", config, initialDateDisplayMode);
timeRangeStart.setToDefault();
timeRangeEnd.setToDefault();
const updateTimeSelectorsUTMode = (mode) => {
systemTime.time.utDisplayMode = mode;
systemTime.update();
timeRangeStart.time.utDisplayMode = mode;
timeRangeStart.update();
timeRangeEnd.time.utDisplayMode = mode;
timeRangeEnd.update();
};
datesAsElapsedCheckbox.onchange = () => {
const mode = datesAsElapsedCheckbox.checked ? "elapsed" : "offset";
updateTimeSelectorsUTMode(mode);
};
const depAltitude = new IntegerInput("start-altitude");
const destAltitude = new IntegerInput("end-altitude");
const updateAltitudeRange = (input, body) => {
@@ -206,7 +220,15 @@ export async function initEditorWithSystem(systems, systemIndex) {
const displayFoundTrajectory = (sequence) => {
trajectory = new Trajectory(solver, system, config);
trajectory.draw(canvas);
trajectory.fillResultControls(resultItems, systemTime, controls);
const { depDate, arrDate } = trajectory.fillResultControls(resultItems, systemTime, controls);
datesAsElapsedCheckbox.onchange = () => {
const mode = datesAsElapsedCheckbox.checked ? "elapsed" : "offset";
updateTimeSelectorsUTMode(mode);
depDate.utDisplayMode = mode;
arrDate.utDisplayMode = mode;
resultItems.depDateSpan.innerHTML = depDate.stringYDHMS("hms", "ut");
resultItems.arrDateSpan.innerHTML = arrDate.stringYDHMS("hms", "ut");
};
systemTime.input(() => {
updateSystemTime();
trajectory.updatePodPosition(systemTime);
@@ -216,14 +238,15 @@ export async function initEditorWithSystem(systems, systemIndex) {
stepSlider.enable();
trajectory.updatePodPosition(systemTime);
console.log(solver.bestDeltaV);
const trajText = trajectoryToText(trajectory, sequence);
const currentDateDisplayMode = datesAsElapsedCheckbox.checked ? "elapsed" : "offset";
const trajText = trajectoryToText(trajectory, sequence, currentDateDisplayMode);
console.log(trajText);
trajectoryCounter++;
showTrajDetailsBtn.click(() => {
DraggableTextbox.create(`Trajectory ${trajectoryCounter}`, trajText);
});
showTrajDetailsBtn.enable();
const trajCSV = trajectoryToCSVData(trajectory);
const trajCSV = trajectoryToCSVData(trajectory, currentDateDisplayMode);
downloadTrajDataBtn.click(() => {
let element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(trajCSV));
@@ -334,6 +357,7 @@ export async function initEditorWithSystem(systems, systemIndex) {
scene.remove();
renderer.dispose();
controls.dispose();
datesAsElapsedCheckbox.onchange = null;
initEditorWithSystem(systems, index);
});
}

View File

@@ -1,13 +1,13 @@
import { KSPTime } from "../time/time.js";
export class TimeSelector {
constructor(namePrefix, config) {
constructor(namePrefix, config, dateMode) {
this.config = config;
this.yearInput = document.getElementById(`${namePrefix}-year`);
this.dayInput = document.getElementById(`${namePrefix}-day`);
this.hourInput = document.getElementById(`${namePrefix}-hour`);
this.selector = document.getElementById(`${namePrefix}-time`);
this.selector.oninput = () => this.validate();
this.time = KSPTime(0, this.config.time);
this.time = KSPTime(0, this.config.time, dateMode);
this.validate();
}
get dateSeconds() {

View File

@@ -186,8 +186,8 @@ export class Trajectory {
}
}
fillResultControls(resultItems, systemTime, controls) {
const depDate = KSPTime(this.steps[0].dateOfStart, this.config.time);
const arrDate = KSPTime(this.steps[this.steps.length - 1].dateOfStart, this.config.time);
const depDate = KSPTime(this.steps[0].dateOfStart, this.config.time, systemTime.time.utDisplayMode);
const arrDate = KSPTime(this.steps[this.steps.length - 1].dateOfStart, this.config.time, systemTime.time.utDisplayMode);
resultItems.totalDVSpan.innerHTML = this.totalDeltaV.toFixed(1);
resultItems.depDateSpan.innerHTML = depDate.stringYDHMS("hms", "ut");
resultItems.arrDateSpan.innerHTML = arrDate.stringYDHMS("hms", "ut");
@@ -255,7 +255,7 @@ export class Trajectory {
const option = selectorOptions[index];
if (option.type == "maneuver") {
const details = this.maneuvres[option.origin];
const dateEMT = KSPTime(details.dateMET, this.config.time);
const dateEMT = KSPTime(details.dateMET, this.config.time, systemTime.time.utDisplayMode);
resultItems.dateSpan.innerHTML = dateEMT.stringYDHMS("hm", "emt");
resultItems.progradeDVSpan.innerHTML = details.progradeDV.toFixed(1);
resultItems.normalDVSpan.innerHTML = details.normalDV.toFixed(1);
@@ -275,8 +275,8 @@ export class Trajectory {
}
else if (option.type == "flyby") {
const details = this.flybys[option.origin];
const startDateEMT = KSPTime(details.soiEnterDateMET, this.config.time);
const endDateEMT = KSPTime(details.soiExitDateMET, this.config.time);
const startDateEMT = KSPTime(details.soiEnterDateMET, this.config.time, systemTime.time.utDisplayMode);
const endDateEMT = KSPTime(details.soiExitDateMET, this.config.time, systemTime.time.utDisplayMode);
resultItems.startDateSpan.innerHTML = startDateEMT.stringYDHMS("hm", "emt");
resultItems.endDateSpan.innerHTML = endDateEMT.stringYDHMS("hm", "emt");
resultItems.periAltitudeSpan.innerHTML = details.periAltitude.toFixed(0);
@@ -288,6 +288,7 @@ export class Trajectory {
resultItems.maneuverDiv.hidden = true;
}
});
return { depDate, arrDate };
}
_displayStepsUpTo(index) {
for (let i = 0; i < this.steps.length; i++) {

View File

@@ -1,13 +1,15 @@
export class BaseKSPTime {
constructor(date, config) {
constructor(date, config, dateMode) {
this.config = config;
this._exactDate = 0;
this.utDisplayMode = "offset";
if (typeof date == "number") {
this.dateSeconds = date;
}
else {
this.displayYDHMS = date;
}
this.utDisplayMode = dateMode;
}
stringYDHMS(precision, display) {
let { year, day, hour, minute, second } = this.displayYDHMS;
@@ -21,17 +23,27 @@ export class BaseKSPTime {
hmsStr += "h";
}
if (display == "ut") {
return `Year ${year} - Day ${day} - ${hmsStr}`;
if (this.utDisplayMode == "offset") {
return `Year ${year} - Day ${day} - ${hmsStr}`;
}
else {
return `T+ ${year}y - ${day}d - ${hmsStr}`;
}
}
else {
return `T+ ${year - 1}y - ${day - 1}d - ${hmsStr}`;
if (this.utDisplayMode == "offset") {
return `T+ ${year - 1}y - ${day - 1}d - ${hmsStr}`;
}
else {
return `T+ ${year}y - ${day}d - ${hmsStr}`;
}
}
}
toUT(from) {
if (typeof from == "number")
return new BaseKSPTime(from + this._exactDate, this.config);
return new BaseKSPTime(from + this._exactDate, this.config, this.utDisplayMode);
else
return new BaseKSPTime(from.dateSeconds + this._exactDate, this.config);
return new BaseKSPTime(from.dateSeconds + this._exactDate, this.config, this.utDisplayMode);
}
get dateSeconds() {
return this._exactDate;
@@ -46,12 +58,21 @@ export class BaseKSPTime {
const hour = Math.floor((t % this._secondsPerDay) / 3600);
const minute = Math.floor((t % 3600) / 60);
const second = (t % 60);
return { year: years + 1, day: days + 1, hour, minute, second };
if (this.utDisplayMode == "offset") {
return { year: years + 1, day: days + 1, hour, minute, second };
}
else {
return { year: years, day: days, hour, minute, second };
}
}
set displayYDHMS(date) {
let { year, day, hour, minute, second } = date;
let t = this._secondsPerYear * (year - 1);
t += this._secondsPerDay * (day - 1);
if (this.utDisplayMode == "offset") {
year -= 1;
day -= 1;
}
let t = this._secondsPerYear * year;
t += this._secondsPerDay * day;
t += 3600 * hour;
t += 60 * minute;
t += second;

View File

@@ -2,6 +2,7 @@ export class RealKSPTime {
constructor(date, config) {
this.config = config;
this._exactDate = 0;
this.utDisplayMode = "offset";
if (typeof date == "number") {
this.dateSeconds = date;
}

View File

@@ -1,11 +1,11 @@
import { RealKSPTime } from "./realtime.js";
import { BaseKSPTime } from "./basetime.js";
export function KSPTime(date, config) {
export function KSPTime(date, config, dateMode) {
switch (config.type) {
case "base":
if (config.daysPerYear === undefined || config.hoursPerDay === undefined)
throw new Error("Missing daysPerYear or hoursPerDay in time config");
return new BaseKSPTime(date, config);
return new BaseKSPTime(date, config, dateMode);
case "real":
return new RealKSPTime(date, config);
}

View File

@@ -1,6 +1,6 @@
import { KSPTime } from "../time/time.js";
import { joinStrings } from "./array.js";
export function trajectoryToText(traj, seq) {
export function trajectoryToText(traj, seq, dateMode) {
const { steps, system, config } = traj;
const pairs = [];
const add = (label, data, indent) => {
@@ -8,10 +8,10 @@ export function trajectoryToText(traj, seq) {
};
const space = () => add("", "", 0);
add("Sequence", seq.seqStringFullNames, 0);
const depDate = KSPTime(steps[0].dateOfStart, config.time);
const arrDate = KSPTime(steps[steps.length - 1].dateOfStart, config.time);
add("Departure", depDate.stringYDHMS("hms", "ut"), 0);
add("Arrival", arrDate.stringYDHMS("hms", "ut"), 0);
const depDate = KSPTime(steps[0].dateOfStart, config.time, dateMode);
const arrDate = KSPTime(steps[steps.length - 1].dateOfStart, config.time, dateMode);
add("Departure", depDate.stringYDHMS("hms", "ut") + " UT", 0);
add("Arrival", arrDate.stringYDHMS("hms", "ut") + " UT", 0);
add("Total ΔV", `${traj.totalDeltaV.toFixed(1)} m/s`, 0);
space();
add("Steps", "", 0);
@@ -39,7 +39,7 @@ export function trajectoryToText(traj, seq) {
label = `${arrivalBodyName} circularization`;
}
add(label, "", 1);
const dateMET = KSPTime(details.dateMET, config.time);
const dateMET = KSPTime(details.dateMET, config.time, dateMode);
add("Date", dateMET.toUT(depDate).stringYDHMS("hms", "ut") + " UT", 2);
add("", dateMET.stringYDHMS("hms", "emt") + " MET", 2);
if (details.ejectAngle !== undefined) {
@@ -55,8 +55,8 @@ export function trajectoryToText(traj, seq) {
space();
const details = traj.flybys[flybyIdx];
const bodyName = system.bodyFromId(details.bodyId).name;
const enterMET = KSPTime(details.soiEnterDateMET, config.time);
const exitMET = KSPTime(details.soiExitDateMET, config.time);
const enterMET = KSPTime(details.soiEnterDateMET, config.time, dateMode);
const exitMET = KSPTime(details.soiExitDateMET, config.time, dateMode);
add(`Flyby around ${bodyName}`, "", 1);
add("SOI enter date", enterMET.toUT(depDate).stringYDHMS("hms", "ut") + " UT", 2);
add("", enterMET.stringYDHMS("hms", "emt") + " MET", 2);
@@ -91,7 +91,7 @@ function pairsToString(pairs) {
}
return joinStrings(lines, "\n");
}
export function trajectoryToCSVData(traj) {
export function trajectoryToCSVData(traj, dateMode) {
const { config, steps, orbits } = traj;
const n = steps.length;
const entries = [];
@@ -105,7 +105,7 @@ export function trajectoryToCSVData(traj) {
entries.push({
type: "dsm",
bodyId: step.attractorId,
timeUT: KSPTime(dateOfStart, config.time).dateSeconds,
timeUT: KSPTime(dateOfStart, config.time, dateMode).dateSeconds,
pos: startState.pos,
vel: startState.vel
});
@@ -115,7 +115,7 @@ export function trajectoryToCSVData(traj) {
entries.push({
type: "flyby",
bodyId: steps[i - 1].attractorId,
timeUT: KSPTime(dateOfStart, config.time).dateSeconds,
timeUT: KSPTime(dateOfStart, config.time, dateMode).dateSeconds,
pos: startState.pos,
vel: startState.vel
});
@@ -127,7 +127,7 @@ export function trajectoryToCSVData(traj) {
entries.push({
type: "arrival",
bodyId: steps[n - 1].attractorId,
timeUT: KSPTime(arrivalDate, config.time).dateSeconds,
timeUT: KSPTime(arrivalDate, config.time, dateMode).dateSeconds,
pos: arrivalState.pos,
vel: arrivalState.vel
});

View File

@@ -240,6 +240,9 @@
<div id="soi-toggle-box">
<input type="checkbox" id="soi-checkbox" name="soi-checkbox">
<label for="soi-checkbox">Show SOIs</label>
<input type="checkbox" id="date-as-elapsed-checkbox" name="date-as-elapsed-checkbox">
<label for="date-as-elapsed-checkbox">Show dates as elapsed time</label>
</div>
</div>
</div>

View File

@@ -57,8 +57,12 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
}
requestAnimationFrame(loop);
// Date display mode toggle:
const datesAsElapsedCheckbox = document.getElementById("date-as-elapsed-checkbox") as HTMLInputElement;
const initialDateDisplayMode = datesAsElapsedCheckbox.checked ? "elapsed" : "offset";
// Setting up solar system time control
const systemTime = new TimeSelector("system", config);
const systemTime = new TimeSelector("system", config, initialDateDisplayMode);
const updateSystemTime = () => {
if(systemTime.validate()){
system.date = systemTime.dateSeconds;
@@ -175,11 +179,26 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
{
// Time inputs
const timeRangeStart = new TimeSelector("start", config);
const timeRangeEnd = new TimeSelector("end", config);
const timeRangeStart = new TimeSelector("start", config, initialDateDisplayMode);
const timeRangeEnd = new TimeSelector("end", config, initialDateDisplayMode);
timeRangeStart.setToDefault();
timeRangeEnd.setToDefault();
// configure time selectors format updates
const updateTimeSelectorsUTMode = (mode: "elapsed" | "offset") => {
systemTime.time.utDisplayMode = mode;
systemTime.update();
timeRangeStart.time.utDisplayMode = mode;
timeRangeStart.update()
timeRangeEnd.time.utDisplayMode = mode;
timeRangeEnd.update();
}
datesAsElapsedCheckbox.onchange = () => {
const mode = datesAsElapsedCheckbox.checked ? "elapsed" : "offset";
updateTimeSelectorsUTMode(mode);
}
// Numerical inputs
const depAltitude = new IntegerInput("start-altitude");
const destAltitude = new IntegerInput("end-altitude");
@@ -271,7 +290,17 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
const displayFoundTrajectory = (sequence: FlybySequence) => {
trajectory = new Trajectory(solver, system, config);
trajectory.draw(canvas);
trajectory.fillResultControls(resultItems, systemTime, controls);
const {depDate, arrDate} = trajectory.fillResultControls(resultItems, systemTime, controls);
// Change the displayed arrival and departure dates as well
datesAsElapsedCheckbox.onchange = () => {
const mode = datesAsElapsedCheckbox.checked ? "elapsed" : "offset";
updateTimeSelectorsUTMode(mode);
depDate.utDisplayMode = mode;
arrDate.utDisplayMode = mode;
resultItems.depDateSpan.innerHTML = depDate.stringYDHMS("hms", "ut");
resultItems.arrDateSpan.innerHTML = arrDate.stringYDHMS("hms", "ut");
}
systemTime.input(() => {
updateSystemTime();
@@ -284,8 +313,9 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
trajectory.updatePodPosition(systemTime);
console.log(solver.bestDeltaV);
const trajText = trajectoryToText(trajectory, sequence);
const currentDateDisplayMode = datesAsElapsedCheckbox.checked ? "elapsed" : "offset";
const trajText = trajectoryToText(trajectory, sequence, currentDateDisplayMode);
console.log(trajText);
trajectoryCounter++;
@@ -294,7 +324,7 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
});
showTrajDetailsBtn.enable();
const trajCSV = trajectoryToCSVData(trajectory);
const trajCSV = trajectoryToCSVData(trajectory, currentDateDisplayMode);
downloadTrajDataBtn.click(() => {
let element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(trajCSV));
@@ -424,6 +454,8 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
scene.remove();
renderer.dispose();
controls.dispose();
datesAsElapsedCheckbox.onchange = null;
initEditorWithSystem(systems, index);
});

View File

@@ -9,7 +9,7 @@ export class TimeSelector {
readonly hourInput!: HTMLInputElement;
readonly selector!: HTMLDivElement;
constructor(namePrefix: string, public readonly config: Config) {
constructor(namePrefix: string, public readonly config: Config, dateMode: "elapsed" | "offset") {
this.yearInput = document.getElementById(`${namePrefix}-year`) as HTMLInputElement;
this.dayInput = document.getElementById(`${namePrefix}-day`) as HTMLInputElement;
this.hourInput = document.getElementById(`${namePrefix}-hour`) as HTMLInputElement;
@@ -17,7 +17,7 @@ export class TimeSelector {
this.selector = document.getElementById(`${namePrefix}-time`) as HTMLDivElement;
this.selector.oninput = () => this.validate();
this.time = KSPTime(0, this.config.time);
this.time = KSPTime(0, this.config.time, dateMode);
this.validate();
}

View File

@@ -273,8 +273,8 @@ export class Trajectory {
* @param controls The camera controller
*/
public fillResultControls(resultItems: ResultPannelItems, systemTime: TimeSelector, controls: CameraController){
const depDate = KSPTime(this.steps[0].dateOfStart, this.config.time);
const arrDate = KSPTime(this.steps[this.steps.length-1].dateOfStart, this.config.time);
const depDate = KSPTime(this.steps[0].dateOfStart, this.config.time, systemTime.time.utDisplayMode);
const arrDate = KSPTime(this.steps[this.steps.length-1].dateOfStart, this.config.time, systemTime.time.utDisplayMode);
// total delta-V
resultItems.totalDVSpan.innerHTML = this.totalDeltaV.toFixed(1);
@@ -364,7 +364,7 @@ export class Trajectory {
if(option.type == "maneuver"){
const details = this.maneuvres[option.origin];
const dateEMT = KSPTime(details.dateMET, this.config.time);
const dateEMT = KSPTime(details.dateMET, this.config.time, systemTime.time.utDisplayMode);
resultItems.dateSpan.innerHTML = dateEMT.stringYDHMS("hm", "emt");
resultItems.progradeDVSpan.innerHTML = details.progradeDV.toFixed(1);
@@ -387,8 +387,8 @@ export class Trajectory {
} else if(option.type == "flyby"){
const details = this.flybys[option.origin];
const startDateEMT = KSPTime(details.soiEnterDateMET, this.config.time);
const endDateEMT = KSPTime(details.soiExitDateMET, this.config.time);
const startDateEMT = KSPTime(details.soiEnterDateMET, this.config.time, systemTime.time.utDisplayMode);
const endDateEMT = KSPTime(details.soiExitDateMET, this.config.time, systemTime.time.utDisplayMode);
resultItems.startDateSpan.innerHTML = startDateEMT.stringYDHMS("hm", "emt");
resultItems.endDateSpan.innerHTML = endDateEMT.stringYDHMS("hm", "emt");
@@ -407,6 +407,8 @@ export class Trajectory {
/*for(const step of this.steps){
console.log(step);
}*/
return {depDate, arrDate};
}
/**

View File

@@ -1,12 +1,15 @@
export class BaseKSPTime implements IKSPTime {
private _exactDate: number = 0;
constructor(date: number | DateYDHMS, public readonly config: BaseTimeSettings){
public utDisplayMode: "elapsed" | "offset" = "offset";
constructor(date: number | DateYDHMS, public readonly config: BaseTimeSettings, dateMode: "elapsed" | "offset"){
if(typeof date == "number") {
this.dateSeconds = date;
} else {
this.displayYDHMS = date;
}
this.utDisplayMode = dateMode;
}
public stringYDHMS(precision: "h" | "hm" | "hms", display: "emt" | "ut"): string {
@@ -23,17 +26,25 @@ export class BaseKSPTime implements IKSPTime {
}
if(display == "ut"){
return `Year ${year} - Day ${day} - ${hmsStr}`;
if(this.utDisplayMode == "offset"){
return `Year ${year} - Day ${day} - ${hmsStr}`;
} else {
return `T+ ${year}y - ${day}d - ${hmsStr}`;
}
} else {
return `T+ ${year-1}y - ${day-1}d - ${hmsStr}`;
if(this.utDisplayMode == "offset"){
return `T+ ${year-1}y - ${day-1}d - ${hmsStr}`;
} else {
return `T+ ${year}y - ${day}d - ${hmsStr}`;
}
}
}
public toUT(from: number | IKSPTime): IKSPTime {
if(typeof from == "number")
return new BaseKSPTime(from + this._exactDate, this.config);
return new BaseKSPTime(from + this._exactDate, this.config, this.utDisplayMode);
else
return new BaseKSPTime(from.dateSeconds + this._exactDate, this.config);
return new BaseKSPTime(from.dateSeconds + this._exactDate, this.config, this.utDisplayMode);
}
public get dateSeconds(){
@@ -51,14 +62,23 @@ export class BaseKSPTime implements IKSPTime {
const hour = Math.floor((t % this._secondsPerDay) / 3600);
const minute = Math.floor((t % 3600) / 60);
const second = (t % 60);
return {year:years+1, day:days+1, hour, minute, second};
if(this.utDisplayMode == "offset"){
return {year:years+1, day:days+1, hour, minute, second};
} else {
return {year:years, day:days, hour, minute, second};
}
}
public set displayYDHMS(date: DateYDHMS) {
let {year, day, hour, minute, second} = date;
let t = this._secondsPerYear * (year-1);
t += this._secondsPerDay * (day-1);
if(this.utDisplayMode == "offset"){
year -= 1;
day -= 1;
}
let t = this._secondsPerYear * year;
t += this._secondsPerDay * day;
t += 3600 * hour;
t += 60 * minute;
t += second;

View File

@@ -1,6 +1,8 @@
export class RealKSPTime implements IKSPTime {
private _exactDate: number = 0; // time elapsed since Jan 1st 1970 (positive or negative), in seconds
public readonly utDisplayMode = "offset";
constructor(date: number | DateYDHMS, public readonly config: RealTimeSettings){
if(typeof date == "number") {
this.dateSeconds = date;

View File

@@ -1,12 +1,12 @@
import { RealKSPTime } from "./realtime.js";
import { BaseKSPTime } from "./basetime.js";
export function KSPTime(date: number | DateYDHMS, config: BaseTimeSettings | RealTimeSettings): IKSPTime {
export function KSPTime(date: number | DateYDHMS, config: BaseTimeSettings | RealTimeSettings, dateMode: "elapsed" | "offset"): IKSPTime {
switch(config.type) {
case "base":
if(config.daysPerYear === undefined || config.hoursPerDay === undefined)
throw new Error("Missing daysPerYear or hoursPerDay in time config");
return new BaseKSPTime(date, config);
return new BaseKSPTime(date, config, dateMode);
case "real":
return new RealKSPTime(date, config);
}

View File

@@ -5,7 +5,7 @@ import { joinStrings } from "./array.js";
type pair = {label: string, data: string, indent: number};
export function trajectoryToText(traj: Trajectory, seq: FlybySequence) {
export function trajectoryToText(traj: Trajectory, seq: FlybySequence, dateMode: "elapsed" | "offset") {
const {steps, system, config} = traj;
const pairs: pair[] = [];
@@ -17,10 +17,10 @@ export function trajectoryToText(traj: Trajectory, seq: FlybySequence) {
add("Sequence", seq.seqStringFullNames, 0);
const depDate = KSPTime(steps[0].dateOfStart, config.time);
const arrDate = KSPTime(steps[steps.length-1].dateOfStart, config.time);
add("Departure", depDate.stringYDHMS("hms", "ut"), 0);
add("Arrival", arrDate.stringYDHMS("hms", "ut"), 0);
const depDate = KSPTime(steps[0].dateOfStart, config.time, dateMode);
const arrDate = KSPTime(steps[steps.length-1].dateOfStart, config.time, dateMode);
add("Departure", depDate.stringYDHMS("hms", "ut") + " UT", 0);
add("Arrival", arrDate.stringYDHMS("hms", "ut") + " UT", 0);
add("Total ΔV", `${traj.totalDeltaV.toFixed(1)} m/s`, 0);
space();
add("Steps", "", 0);
@@ -49,7 +49,7 @@ export function trajectoryToText(traj: Trajectory, seq: FlybySequence) {
label = `${arrivalBodyName} circularization`;
}
add(label, "", 1);
const dateMET = KSPTime(details.dateMET, config.time);
const dateMET = KSPTime(details.dateMET, config.time, dateMode);
add("Date", dateMET.toUT(depDate).stringYDHMS("hms", "ut") + " UT", 2);
add("", dateMET.stringYDHMS("hms", "emt") + " MET", 2);
if(details.ejectAngle !== undefined){
@@ -66,8 +66,8 @@ export function trajectoryToText(traj: Trajectory, seq: FlybySequence) {
space();
const details = traj.flybys[flybyIdx];
const bodyName = system.bodyFromId(details.bodyId).name;
const enterMET = KSPTime(details.soiEnterDateMET, config.time);
const exitMET = KSPTime(details.soiExitDateMET, config.time);
const enterMET = KSPTime(details.soiEnterDateMET, config.time, dateMode);
const exitMET = KSPTime(details.soiExitDateMET, config.time, dateMode);
add(`Flyby around ${bodyName}`, "", 1);
add("SOI enter date", enterMET.toUT(depDate).stringYDHMS("hms", "ut") + " UT", 2);
add("", enterMET.stringYDHMS("hms", "emt") + " MET", 2);
@@ -115,7 +115,7 @@ type CSVEntry = {
vel: {x: number, y: number, z: number},
};
export function trajectoryToCSVData(traj: Trajectory){
export function trajectoryToCSVData(traj: Trajectory, dateMode: "elapsed" | "offset"){
const {config, steps, orbits} = traj;
const n = steps.length;
const entries: CSVEntry[] = [];
@@ -130,7 +130,7 @@ export function trajectoryToCSVData(traj: Trajectory){
entries.push({
type: "dsm",
bodyId: step.attractorId,
timeUT: KSPTime(dateOfStart, config.time).dateSeconds,
timeUT: KSPTime(dateOfStart, config.time, dateMode).dateSeconds,
pos: startState.pos,
vel: startState.vel
});
@@ -139,7 +139,7 @@ export function trajectoryToCSVData(traj: Trajectory){
entries.push({
type: "flyby",
bodyId: steps[i-1].attractorId,
timeUT: KSPTime(dateOfStart, config.time).dateSeconds,
timeUT: KSPTime(dateOfStart, config.time, dateMode).dateSeconds,
pos: startState.pos,
vel: startState.vel
});
@@ -153,7 +153,7 @@ export function trajectoryToCSVData(traj: Trajectory){
entries.push({
type: "arrival",
bodyId: steps[n-1].attractorId,
timeUT: KSPTime(arrivalDate, config.time).dateSeconds,
timeUT: KSPTime(arrivalDate, config.time, dateMode).dateSeconds,
pos: arrivalState.pos,
vel: arrivalState.vel
});

5
src/types.d.ts vendored
View File

@@ -140,8 +140,9 @@ interface SequenceParameters {
type DateYDHMS = {year: number, day: number, hour: number, minute: number, second: number};
interface IKSPTime {
public dateSeconds: number;
public displayYDHMS: DateYDH;
public dateSeconds: number;
public displayYDHMS: DateYDH;
public utDisplayMode: "elapsed" | "offset";
public readonly defaultDate: number;
public stringYDHMS(precision: "h" | "hm" | "hms", display: "emt" | "ut"): string;
public toUT(from: IKSPTime | number): IKSPTime;