Some bug fixes
This commit is contained in:
parent
9d435fb255
commit
b176a4a412
@ -192,13 +192,8 @@ export class LambertSolutions {
|
||||
transferGoalTrueAnomaly -= 2 * Math.PI;
|
||||
}
|
||||
|
||||
if (transferStartTrueAnomaly < 2 * Math.PI && transferGoalTrueAnomaly > 2 * Math.PI) {
|
||||
transferStartTrueAnomaly -= 2 * Math.PI;
|
||||
transferGoalTrueAnomaly -= 2 * Math.PI;
|
||||
}
|
||||
|
||||
let closestPoint;
|
||||
if (transferStartTrueAnomaly < 0 && transferGoalTrueAnomaly >= 0) {
|
||||
if ((transferStartTrueAnomaly < 0 && transferGoalTrueAnomaly >= 0) || (transferStartTrueAnomaly < 2 * Math.PI && transferGoalTrueAnomaly >= 2 * Math.PI)) {
|
||||
closestPoint = semiLatusRectum / (1 + eccentricity);
|
||||
} else {
|
||||
closestPoint = Math.min(this.positionOneMagnitude, this.positionTwoMagnitude);
|
||||
@ -570,7 +565,7 @@ export function getOrbitalPeriod(semiMajor: number, body: Body) {
|
||||
return Math.sqrt(semiMajor**3 / body.gravitationalParameter);
|
||||
}
|
||||
|
||||
export function perform2dGradientDescent(functionToMinimize: ((variableOne: number, variableTwo: number) => number | null), initialGuessVariableOne: number, initialGuessVaribaleTwo: number, maxDifference?: number, maxTries?: number): [number, number] | null {
|
||||
export function perform2dGradientDescent(functionToMinimize: ((variableOne: number, variableTwo: number) => number | null), initialGuessVariableOne: number, initialGuessVaribaleTwo: number, maxDifference?: number, maxTries?: number, variableOneBounds?: [number, number], variableTwoBounds?: [number, number]): [number, number] | null {
|
||||
let variableOne = initialGuessVariableOne;
|
||||
let variableTwo = initialGuessVaribaleTwo;
|
||||
let bestValue = functionToMinimize(variableOne, variableTwo);
|
||||
@ -649,6 +644,18 @@ export function perform2dGradientDescent(functionToMinimize: ((variableOne: numb
|
||||
break;
|
||||
}
|
||||
|
||||
if (variableOneBounds) {
|
||||
if (variableOneUpdate < variableOneBounds[0] || variableOneUpdate > variableOneBounds[1]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (variableTwoBounds) {
|
||||
if (variableTwoUpdate < variableTwoBounds[0] || variableTwoUpdate > variableTwoBounds[1]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
variableOne = variableOneUpdate;
|
||||
variableTwo = variableTwoUpdate;
|
||||
bestValue = bestValueImprovement;
|
||||
@ -992,17 +999,26 @@ export function findCheapestIntercept(startingSituation: OrbitalCoordinates, tar
|
||||
|
||||
}
|
||||
|
||||
let extraStartOrbits = Math.floor(startOrbitMeanAnomaly / (2 * Math.PI));
|
||||
let extraEndOrbits = Math.floor(endOrbitMeanAnomaly / (2 * Math.PI));
|
||||
let startTrueAnomaly: number = 0;
|
||||
let endTrueAnomaly: number = 0;
|
||||
|
||||
startOrbitMeanAnomaly = startOrbitMeanAnomaly % (2 * Math.PI);
|
||||
endOrbitMeanAnomaly = endOrbitMeanAnomaly % (2 * Math.PI);
|
||||
["start", "end"].forEach(orbit => {
|
||||
let meanAnomaly = orbit == "start" ? startOrbitMeanAnomaly : endOrbitMeanAnomaly;
|
||||
let eccentricity = orbit == "start" ? startingSituation.orbit.eccentricity : targetSituation.orbit.eccentricity;
|
||||
let extraOrbits = 0;
|
||||
if (eccentricity < 1) {
|
||||
extraOrbits = Math.floor(meanAnomaly / (2 * Math.PI));
|
||||
meanAnomaly = meanAnomaly % (2 * Math.PI);
|
||||
}
|
||||
let [_, trueAnomaly] = getEccentricAndTrueAnomalyFromMeanAnomaly(meanAnomaly, eccentricity);
|
||||
trueAnomaly += extraOrbits * 2 * Math.PI;
|
||||
|
||||
let [_, startTrueAnomaly] = getEccentricAndTrueAnomalyFromMeanAnomaly(startOrbitMeanAnomaly, startingSituation.orbit.eccentricity);
|
||||
let [__, endTrueAnomaly] = getEccentricAndTrueAnomalyFromMeanAnomaly(endOrbitMeanAnomaly, targetSituation.orbit.eccentricity);
|
||||
|
||||
startTrueAnomaly += extraStartOrbits * 2 * Math.PI;
|
||||
endTrueAnomaly += extraEndOrbits * 2 * Math.PI;
|
||||
if (orbit == "start") {
|
||||
startTrueAnomaly = trueAnomaly;
|
||||
} else if (orbit == "end") {
|
||||
endTrueAnomaly = trueAnomaly;
|
||||
}
|
||||
});
|
||||
|
||||
let targetTransferTime = endTime - startTime;
|
||||
let lambertSolutions = new LambertSolutions(startingSituation.orbit, startTrueAnomaly, targetSituation.orbit, endTrueAnomaly + extraTrueAnomaly, body, backwards);
|
||||
@ -1024,7 +1040,12 @@ export function findCheapestIntercept(startingSituation: OrbitalCoordinates, tar
|
||||
return null;
|
||||
}
|
||||
|
||||
if (transfer.farthestPointDistance > body.sphereOfInfluence || transfer.closestPointDistance < body.closestSafeDistance) {
|
||||
if (transfer.farthestPointDistance >= body.sphereOfInfluence || transfer.closestPointDistance <= body.closestSafeDistance) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Sometimes, we get eccentric orbits that are impossible to do
|
||||
if (transfer.transferOrbitTrueAnomalyAtManoeuvreOne < Math.PI && transfer.transferOrbitTrueanomalyAtManoeuvreTwo > Math.PI && transfer.transferOrbit.eccentricity - 1 >= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1066,7 +1087,7 @@ export function findCheapestIntercept(startingSituation: OrbitalCoordinates, tar
|
||||
return;
|
||||
}
|
||||
|
||||
let result = perform2dGradientDescent(interceptFunction, foundStartTime, foundEndTime, 0, 30);
|
||||
let result = perform2dGradientDescent(interceptFunction, foundStartTime, foundEndTime, 0, 30, [0, 1e99]);
|
||||
if (result) {
|
||||
let foundTransfer = getTransfer(result[0], result[1], backwards);
|
||||
if (foundTransfer) {
|
||||
@ -1463,22 +1484,30 @@ export function findOrbitThroughInterpolation(ownCoordinates: OrbitalCoordinates
|
||||
}
|
||||
|
||||
const getAnglesFromPhaseAngles = (firstPhaseAngle: number, secondPhaseAngle: number) => {
|
||||
let angleOne;
|
||||
let angleTwo;
|
||||
let cosAngleOne;
|
||||
let cosAngleTwo;
|
||||
|
||||
if (Math.abs(interpolationParameters.firstPhaseAngle) < Math.PI / 2) {
|
||||
angleOne = Math.acos(Math.tan(firstPhaseAngle) * firstDistanceAlongDirection / firstDistancePerpendicularToDirection);
|
||||
cosAngleOne = Math.tan(firstPhaseAngle) * firstDistanceAlongDirection / firstDistancePerpendicularToDirection;
|
||||
} else {
|
||||
angleOne = Math.acos(Math.tan(Math.PI - firstPhaseAngle) * -firstDistanceAlongDirection / firstDistancePerpendicularToDirection);
|
||||
cosAngleOne = Math.tan(Math.PI - firstPhaseAngle) * -firstDistanceAlongDirection / firstDistancePerpendicularToDirection;
|
||||
}
|
||||
|
||||
if (Math.abs(interpolationParameters.secondPhaseAngle) < Math.PI / 2) {
|
||||
angleTwo = Math.acos(Math.tan(secondPhaseAngle) * secondDistanceAlongDirection / secondDistancePerpendicularToDirection);
|
||||
cosAngleTwo = Math.tan(secondPhaseAngle) * secondDistanceAlongDirection / secondDistancePerpendicularToDirection;
|
||||
} else {
|
||||
angleTwo = Math.acos(Math.tan(Math.PI - secondPhaseAngle) * -secondDistanceAlongDirection / secondDistancePerpendicularToDirection);
|
||||
cosAngleTwo = Math.tan(Math.PI - secondPhaseAngle) * -secondDistanceAlongDirection / secondDistancePerpendicularToDirection;
|
||||
}
|
||||
|
||||
return [angleOne, angleTwo];
|
||||
if (Math.abs(cosAngleOne) > 1) {
|
||||
cosAngleOne = 1 * Math.sign(cosAngleOne);
|
||||
}
|
||||
|
||||
if (Math.abs(cosAngleTwo) > 1) {
|
||||
cosAngleTwo = 1 * Math.sign(cosAngleTwo);
|
||||
}
|
||||
|
||||
return [Math.acos(cosAngleOne), Math.acos(cosAngleTwo)];
|
||||
}
|
||||
|
||||
let bestAngles = [[0], [0]];
|
||||
@ -1519,7 +1548,7 @@ export function findOrbitThroughInterpolation(ownCoordinates: OrbitalCoordinates
|
||||
)
|
||||
);
|
||||
|
||||
let normalVector = normalizeVector(vectorCrossProduct(targetPositionTwo, targetPositionOne));
|
||||
let normalVector = normalizeVector(vectorCrossProduct(targetPositionOne, targetPositionTwo));
|
||||
|
||||
// Rotate the position vector about this normal vector to get the direction of the periapsis
|
||||
let ux = normalVector[0][0];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user