Skip to content

Commit

Permalink
fixed bug in half-angle matching algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
david-rc-dayton committed Feb 10, 2018
1 parent 39cf040 commit 3bc8e52
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 13 deletions.
3 changes: 1 addition & 2 deletions src/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,5 @@ export function matchHalfPlane(angle: number, match: number): number {
const [a1, a2] = [angle, TWO_PI - angle];
const d1 = Math.atan2(Math.sin(a1 - match), Math.cos(a1 - match));
const d2 = Math.atan2(Math.sin(a2 - match), Math.cos(a2 - match));
if (d1 < d2) { return a1; }
return a2;
return (Math.abs(d1) < Math.abs(d2)) ? a1 : a2;
}
2 changes: 1 addition & 1 deletion src/propagators/kepler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export class Kepler implements IPropagator {
let EInit = Math.acos((e + Math.cos(v)) / (1 + e * Math.cos(v)));
EInit = matchHalfPlane(EInit, v);
let MInit = EInit - e * Math.sin(EInit);
MInit = matchHalfPlane(MInit, v);
MInit = matchHalfPlane(MInit, EInit);
let MFinal = (MInit / TWO_PI)
+ n * delta
+ (nDot / 2) * Math.pow(delta, 2)
Expand Down
30 changes: 20 additions & 10 deletions src/propagators/runge-kutta-4.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,32 @@ const DEFAULT_MODEL: INumericalModel = {
stepSize: 60,
};

/** Default propagator model for two-body acceleration. */
const DEFAULT_MODEL_TWOBODY: INumericalModel = {
area: 0,
atmosphericDrag: false,
drag: 0,
gravityMoon: false,
gravitySun: false,
j2Effect: false,
j3Effect: false,
j4Effect: false,
mass: 0,
reflect: 0,
solarRadiation: false,
stepSize: 0,
};

/** 4th order Runge-Kutta numerical integrator for satellite propagation. */
export class RungeKutta4 implements IPropagator {
/**
* Create a new RungeKutta4 propagator object, using onlt two-body
* perturbation options.
*/
public static twoBody(state: J2000): RungeKutta4 {
return new RungeKutta4(state, {
atmosphericDrag: false,
gravityMoon: false,
gravitySun: false,
j2Effect: false,
j3Effect: false,
j4Effect: false,
solarRadiation: false,
});
public static twoBody(state: J2000, model?: INumericalModel): RungeKutta4 {
model = model || {};
const mergeModel = { ...DEFAULT_MODEL_TWOBODY, ...model };
return new RungeKutta4(state, mergeModel);
}

/** Propagator identifier string. */
Expand Down
26 changes: 26 additions & 0 deletions src/test/test-propagators.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as assert from "assert";
import { J2000 } from "../coordinates/j2000";
import { Kepler } from "../propagators/kepler";
import { RungeKutta4 } from "../propagators/runge-kutta-4";

const GEO_STATE_1 = [
Expand Down Expand Up @@ -38,3 +39,28 @@ describe("RungeKutta4", () => {
});
});
});

describe("Kepler", () => {
describe("#.step()", () => {
it("should match numerical two-body results", () => {
const state = new J2000(
Date.UTC(2017, 10, 16, 0, 11, 30, 195),
-3.86234943730e4, 1.68697633760e4, 1.00434444900e3,
-1.231249e0, -2.810612e0, -2.01294e-1,
);
const propRk = RungeKutta4.twoBody(state, { stepSize: 60 });
const resultRk = propRk.step(
Date.UTC(2017, 10, 16, 0, 11, 30, 195), 21600, 6,
);
const propKep = new Kepler(state.toKeplerian());
const resultKep = propKep.step(
Date.UTC(2017, 10, 16, 0, 11, 30, 195), 21600, 6,
);
for (let i = 0; i < resultRk.length; i++) {
const dist = resultRk[i].position
.distance(resultKep[i].position) * 1000;
assert.ok(dist < 1, `Distance: ${dist.toFixed(3)} meters`);
}
});
});
});

0 comments on commit 3bc8e52

Please sign in to comment.