@interstellar-tools/equations 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/categories/anomalies/asymptote-true-anomaly.d.ts +50 -0
- package/dist/categories/anomalies/asymptote-true-anomaly.d.ts.map +1 -0
- package/dist/categories/anomalies/asymptote-true-anomaly.js +55 -0
- package/dist/categories/anomalies/asymptote-true-anomaly.js.map +1 -0
- package/dist/categories/anomalies/hyperbolic-to-true-anomaly.d.ts +38 -0
- package/dist/categories/anomalies/hyperbolic-to-true-anomaly.d.ts.map +1 -0
- package/dist/categories/anomalies/hyperbolic-to-true-anomaly.js +49 -0
- package/dist/categories/anomalies/hyperbolic-to-true-anomaly.js.map +1 -0
- package/dist/categories/anomalies/true-to-hyperbolic-anomaly.d.ts +40 -0
- package/dist/categories/anomalies/true-to-hyperbolic-anomaly.d.ts.map +1 -0
- package/dist/categories/anomalies/true-to-hyperbolic-anomaly.js +54 -0
- package/dist/categories/anomalies/true-to-hyperbolic-anomaly.js.map +1 -0
- package/dist/categories/kepler/solve-kepler-hyperbolic.d.ts +49 -0
- package/dist/categories/kepler/solve-kepler-hyperbolic.d.ts.map +1 -0
- package/dist/categories/kepler/solve-kepler-hyperbolic.js +90 -0
- package/dist/categories/kepler/solve-kepler-hyperbolic.js.map +1 -0
- package/dist/categories/manoeuvres/cw-two-impulse-transfer.d.ts +58 -0
- package/dist/categories/manoeuvres/cw-two-impulse-transfer.d.ts.map +1 -0
- package/dist/categories/manoeuvres/cw-two-impulse-transfer.js +104 -0
- package/dist/categories/manoeuvres/cw-two-impulse-transfer.js.map +1 -0
- package/dist/categories/manoeuvres/phasing-wait-time.d.ts +55 -0
- package/dist/categories/manoeuvres/phasing-wait-time.d.ts.map +1 -0
- package/dist/categories/manoeuvres/phasing-wait-time.js +77 -0
- package/dist/categories/manoeuvres/phasing-wait-time.js.map +1 -0
- package/dist/categories/orbits/cw-propagate.d.ts +48 -0
- package/dist/categories/orbits/cw-propagate.d.ts.map +1 -0
- package/dist/categories/orbits/cw-propagate.js +68 -0
- package/dist/categories/orbits/cw-propagate.js.map +1 -0
- package/dist/categories/orbits/cw-state-transition.d.ts +65 -0
- package/dist/categories/orbits/cw-state-transition.d.ts.map +1 -0
- package/dist/categories/orbits/cw-state-transition.js +83 -0
- package/dist/categories/orbits/cw-state-transition.js.map +1 -0
- package/dist/categories/orbits/hyperbolic-eccentricity.d.ts +56 -0
- package/dist/categories/orbits/hyperbolic-eccentricity.d.ts.map +1 -0
- package/dist/categories/orbits/hyperbolic-eccentricity.js +72 -0
- package/dist/categories/orbits/hyperbolic-eccentricity.js.map +1 -0
- package/dist/categories/orbits/hyperbolic-semi-major-axis.d.ts +53 -0
- package/dist/categories/orbits/hyperbolic-semi-major-axis.d.ts.map +1 -0
- package/dist/categories/orbits/hyperbolic-semi-major-axis.js +66 -0
- package/dist/categories/orbits/hyperbolic-semi-major-axis.js.map +1 -0
- package/dist/categories/orbits/hyperbolic-time-of-flight.d.ts +64 -0
- package/dist/categories/orbits/hyperbolic-time-of-flight.d.ts.map +1 -0
- package/dist/categories/orbits/hyperbolic-time-of-flight.js +86 -0
- package/dist/categories/orbits/hyperbolic-time-of-flight.js.map +1 -0
- package/dist/categories/orbits/synodic-period.d.ts +59 -0
- package/dist/categories/orbits/synodic-period.d.ts.map +1 -0
- package/dist/categories/orbits/synodic-period.js +72 -0
- package/dist/categories/orbits/synodic-period.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Radians } from '@interstellar-tools/types';
|
|
2
|
+
/**
|
|
3
|
+
* Compute how long to **wait for a phase angle**: when a target, leading a chaser on another circular orbit, will be at the angle a manoeuvre needs.
|
|
4
|
+
*
|
|
5
|
+
* The phase angle $ \theta $ is how far the target is ahead of the chaser, and it changes at the difference in mean motions:
|
|
6
|
+
*
|
|
7
|
+
* $$
|
|
8
|
+
* \dot\theta = n_\text{target} - n_\text{chaser}, \qquad
|
|
9
|
+
* t_\text{wait} = \frac{\theta_\text{required} - \theta_\text{now}}{n_\text{target} - n_\text{chaser}} \pmod{T_\text{syn}}
|
|
10
|
+
* $$
|
|
11
|
+
*
|
|
12
|
+
* returning the first time that's not negative.
|
|
13
|
+
*
|
|
14
|
+
* **Units**
|
|
15
|
+
* - Inputs: angles in **radians**, mean motions in **rad/s**.
|
|
16
|
+
* - Output: $ t_\text{wait} $ in **s**, in $ [0, T_\text{syn}) $.
|
|
17
|
+
*
|
|
18
|
+
* ::: info Notes
|
|
19
|
+
*
|
|
20
|
+
* - A chaser in a lower, faster orbit closes the gap: the phase angle shrinks.
|
|
21
|
+
* - For a Hohmann transfer to a target on a circular orbit, the required angle is $ \theta = \pi - n_\text{target}\, t_\text{transfer} $.
|
|
22
|
+
* - If the required angle is just behind, the wait is almost a whole synodic period; see {@link synodicPeriod}.
|
|
23
|
+
*
|
|
24
|
+
* :::
|
|
25
|
+
*
|
|
26
|
+
* @param thetaNow - Current phase angle, target ahead of chaser, in **radians** (finite).
|
|
27
|
+
* @param thetaRequired - Phase angle wanted, in **radians** (finite).
|
|
28
|
+
* @param nChaser - Chaser's mean motion in **rad/s** (finite, > 0).
|
|
29
|
+
* @param nTarget - Target's mean motion in **rad/s** (finite, > 0, not equal to `nChaser`).
|
|
30
|
+
* @returns Waiting time in **s**, in [0, synodic period).
|
|
31
|
+
* @throws {TypeError} If any input is not a finite number.
|
|
32
|
+
* @throws {RangeError} If a mean motion is `<= 0`, or both are equal (the phase never changes).
|
|
33
|
+
* @group Manoeuvres
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* import type { Radians } from '@interstellar-tools/types';
|
|
38
|
+
*
|
|
39
|
+
* // Chaser 1° per orbit faster, target 10° ahead, burn when it's 4° ahead
|
|
40
|
+
* const nTarget = 0.00113;
|
|
41
|
+
* const nChaser = nTarget * (1 + 1 / 360);
|
|
42
|
+
* const t = phasingWaitTime(
|
|
43
|
+
* ((10 * Math.PI) / 180) as Radians,
|
|
44
|
+
* ((4 * Math.PI) / 180) as Radians,
|
|
45
|
+
* nChaser,
|
|
46
|
+
* nTarget
|
|
47
|
+
* );
|
|
48
|
+
* // t ≈ 6 orbits of the target
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @see {@link synodicPeriod}
|
|
52
|
+
* @see {@link hohmannTransferTime}
|
|
53
|
+
*/
|
|
54
|
+
export declare const phasingWaitTime: (thetaNow: Radians, thetaRequired: Radians, nChaser: number, nTarget: number) => number;
|
|
55
|
+
//# sourceMappingURL=phasing-wait-time.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phasing-wait-time.d.ts","sourceRoot":"","sources":["../../../src/categories/manoeuvres/phasing-wait-time.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAU,OAAO,EACjB,eAAe,OAAO,EACtB,SAAS,MAAM,EACf,SAAS,MAAM,KACd,MA4BF,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute how long to **wait for a phase angle**: when a target, leading a chaser on another circular orbit, will be at the angle a manoeuvre needs.
|
|
3
|
+
*
|
|
4
|
+
* The phase angle $ \theta $ is how far the target is ahead of the chaser, and it changes at the difference in mean motions:
|
|
5
|
+
*
|
|
6
|
+
* $$
|
|
7
|
+
* \dot\theta = n_\text{target} - n_\text{chaser}, \qquad
|
|
8
|
+
* t_\text{wait} = \frac{\theta_\text{required} - \theta_\text{now}}{n_\text{target} - n_\text{chaser}} \pmod{T_\text{syn}}
|
|
9
|
+
* $$
|
|
10
|
+
*
|
|
11
|
+
* returning the first time that's not negative.
|
|
12
|
+
*
|
|
13
|
+
* **Units**
|
|
14
|
+
* - Inputs: angles in **radians**, mean motions in **rad/s**.
|
|
15
|
+
* - Output: $ t_\text{wait} $ in **s**, in $ [0, T_\text{syn}) $.
|
|
16
|
+
*
|
|
17
|
+
* ::: info Notes
|
|
18
|
+
*
|
|
19
|
+
* - A chaser in a lower, faster orbit closes the gap: the phase angle shrinks.
|
|
20
|
+
* - For a Hohmann transfer to a target on a circular orbit, the required angle is $ \theta = \pi - n_\text{target}\, t_\text{transfer} $.
|
|
21
|
+
* - If the required angle is just behind, the wait is almost a whole synodic period; see {@link synodicPeriod}.
|
|
22
|
+
*
|
|
23
|
+
* :::
|
|
24
|
+
*
|
|
25
|
+
* @param thetaNow - Current phase angle, target ahead of chaser, in **radians** (finite).
|
|
26
|
+
* @param thetaRequired - Phase angle wanted, in **radians** (finite).
|
|
27
|
+
* @param nChaser - Chaser's mean motion in **rad/s** (finite, > 0).
|
|
28
|
+
* @param nTarget - Target's mean motion in **rad/s** (finite, > 0, not equal to `nChaser`).
|
|
29
|
+
* @returns Waiting time in **s**, in [0, synodic period).
|
|
30
|
+
* @throws {TypeError} If any input is not a finite number.
|
|
31
|
+
* @throws {RangeError} If a mean motion is `<= 0`, or both are equal (the phase never changes).
|
|
32
|
+
* @group Manoeuvres
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* import type { Radians } from '@interstellar-tools/types';
|
|
37
|
+
*
|
|
38
|
+
* // Chaser 1° per orbit faster, target 10° ahead, burn when it's 4° ahead
|
|
39
|
+
* const nTarget = 0.00113;
|
|
40
|
+
* const nChaser = nTarget * (1 + 1 / 360);
|
|
41
|
+
* const t = phasingWaitTime(
|
|
42
|
+
* ((10 * Math.PI) / 180) as Radians,
|
|
43
|
+
* ((4 * Math.PI) / 180) as Radians,
|
|
44
|
+
* nChaser,
|
|
45
|
+
* nTarget
|
|
46
|
+
* );
|
|
47
|
+
* // t ≈ 6 orbits of the target
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @see {@link synodicPeriod}
|
|
51
|
+
* @see {@link hohmannTransferTime}
|
|
52
|
+
*/
|
|
53
|
+
export const phasingWaitTime = (thetaNow, thetaRequired, nChaser, nTarget) => {
|
|
54
|
+
for (const [name, x] of [
|
|
55
|
+
['thetaNow', thetaNow],
|
|
56
|
+
['thetaRequired', thetaRequired],
|
|
57
|
+
['nChaser', nChaser],
|
|
58
|
+
['nTarget', nTarget]
|
|
59
|
+
]) {
|
|
60
|
+
if (!Number.isFinite(x))
|
|
61
|
+
throw new TypeError(`${name} must be a finite number. Received: ${x}`);
|
|
62
|
+
}
|
|
63
|
+
for (const [name, x] of [
|
|
64
|
+
['nChaser', nChaser],
|
|
65
|
+
['nTarget', nTarget]
|
|
66
|
+
]) {
|
|
67
|
+
if (x <= 0)
|
|
68
|
+
throw new RangeError(`${name} must be > 0. Received: ${x}`);
|
|
69
|
+
}
|
|
70
|
+
if (nChaser === nTarget)
|
|
71
|
+
throw new RangeError(`nChaser and nTarget must differ: the phase angle never changes. Received: ${nChaser}`);
|
|
72
|
+
const rate = nTarget - nChaser;
|
|
73
|
+
const synodic = (2 * Math.PI) / Math.abs(rate);
|
|
74
|
+
const t = (thetaRequired - thetaNow) / rate;
|
|
75
|
+
return ((t % synodic) + synodic) % synodic;
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=phasing-wait-time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phasing-wait-time.js","sourceRoot":"","sources":["../../../src/categories/manoeuvres/phasing-wait-time.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,QAAiB,EACjB,aAAsB,EACtB,OAAe,EACf,OAAe,EACP,EAAE;IACV,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI;QACtB,CAAC,UAAU,EAAE,QAAQ,CAAC;QACtB,CAAC,eAAe,EAAE,aAAa,CAAC;QAChC,CAAC,SAAS,EAAE,OAAO,CAAC;QACpB,CAAC,SAAS,EAAE,OAAO,CAAC;KACZ,EAAE,CAAC;QACX,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YACrB,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,uCAAuC,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI;QACtB,CAAC,SAAS,EAAE,OAAO,CAAC;QACpB,CAAC,SAAS,EAAE,OAAO,CAAC;KACZ,EAAE,CAAC;QACX,IAAI,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,UAAU,CAAC,GAAG,IAAI,2BAA2B,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,OAAO,KAAK,OAAO;QACrB,MAAM,IAAI,UAAU,CAClB,6EAA6E,OAAO,EAAE,CACvF,CAAC;IAEJ,MAAM,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC;IAC/B,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,CAAC,GAAG,CAAC,aAAa,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC;IAE5C,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC;AAC7C,CAAC,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { CwState } from '@interstellar-tools/types';
|
|
2
|
+
/**
|
|
3
|
+
* **Propagate** a Clohessy–Wiltshire / Hill relative state in closed form.
|
|
4
|
+
*
|
|
5
|
+
* $$
|
|
6
|
+
* \begin{pmatrix}\mathbf r \\ \mathbf v\end{pmatrix}(t) =
|
|
7
|
+
* \begin{bmatrix}\Phi_{rr} & \Phi_{rv} \\ \Phi_{vr} & \Phi_{vv}\end{bmatrix}
|
|
8
|
+
* \begin{pmatrix}\mathbf r_0 \\ \mathbf v_0\end{pmatrix}
|
|
9
|
+
* $$
|
|
10
|
+
*
|
|
11
|
+
* with $ \Phi(t) $ from {@link cwStateTransition}.
|
|
12
|
+
*
|
|
13
|
+
* **Units**
|
|
14
|
+
* - Inputs: `state` positions in **m** and velocities in **m/s**, `n` in **rad/s**, `t` in **s**.
|
|
15
|
+
* - Output: the state at `t`, in the same units.
|
|
16
|
+
*
|
|
17
|
+
* ::: info Notes
|
|
18
|
+
*
|
|
19
|
+
* - The exact solution of the equations {@link cwHillDerivatives} gives to a numerical integrator: no step size, no accumulated error.
|
|
20
|
+
* - Same LVLH frame and `CwState` layout as `cwHillDerivatives`: `[x, y, z, xDot, yDot, zDot]`, with $ x $ radial, $ y $ along-track, $ z $ cross-track.
|
|
21
|
+
* - A state with $ \dot y_0 = -2n x_0 $ has no along-track drift: it traces a closed ellipse around the chief.
|
|
22
|
+
*
|
|
23
|
+
* :::
|
|
24
|
+
*
|
|
25
|
+
* @param state - Relative state `[x, y, z, xDot, yDot, zDot]` (finite).
|
|
26
|
+
* @param n - Mean motion of the circular reference orbit in **rad/s** (finite, > 0).
|
|
27
|
+
* @param t - Time to propagate in **s** (finite; negative goes backwards).
|
|
28
|
+
* @returns The relative state at `t`.
|
|
29
|
+
* @throws {TypeError} If any input is not a finite number.
|
|
30
|
+
* @throws {RangeError} If `n <= 0`.
|
|
31
|
+
* @group Orbits
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* import type { CwState } from '@interstellar-tools/types';
|
|
36
|
+
*
|
|
37
|
+
* // 100 m below the chief with no drift: back where it started after one orbit
|
|
38
|
+
* const n = 0.00113;
|
|
39
|
+
* const start: CwState = [-100, 0, 0, 0, 2 * n * 100, 0];
|
|
40
|
+
* const later = cwPropagate(start, n, (2 * Math.PI) / n);
|
|
41
|
+
* // later ≈ start
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @see {@link cwStateTransition}
|
|
45
|
+
* @see {@link cwTwoImpulseTransfer}
|
|
46
|
+
*/
|
|
47
|
+
export declare const cwPropagate: (state: CwState, n: number, t: number) => CwState;
|
|
48
|
+
//# sourceMappingURL=cw-propagate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cw-propagate.d.ts","sourceRoot":"","sources":["../../../src/categories/orbits/cw-propagate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAqB,MAAM,2BAA2B,CAAC;AAM5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,eAAO,MAAM,WAAW,GAAI,OAAO,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,KAAG,OAqBlE,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { applyMatrix3 } from '../helpers/apply-matrix-3.js';
|
|
2
|
+
import { cwStateTransition } from './cw-state-transition.js';
|
|
3
|
+
/**
|
|
4
|
+
* **Propagate** a Clohessy–Wiltshire / Hill relative state in closed form.
|
|
5
|
+
*
|
|
6
|
+
* $$
|
|
7
|
+
* \begin{pmatrix}\mathbf r \\ \mathbf v\end{pmatrix}(t) =
|
|
8
|
+
* \begin{bmatrix}\Phi_{rr} & \Phi_{rv} \\ \Phi_{vr} & \Phi_{vv}\end{bmatrix}
|
|
9
|
+
* \begin{pmatrix}\mathbf r_0 \\ \mathbf v_0\end{pmatrix}
|
|
10
|
+
* $$
|
|
11
|
+
*
|
|
12
|
+
* with $ \Phi(t) $ from {@link cwStateTransition}.
|
|
13
|
+
*
|
|
14
|
+
* **Units**
|
|
15
|
+
* - Inputs: `state` positions in **m** and velocities in **m/s**, `n` in **rad/s**, `t` in **s**.
|
|
16
|
+
* - Output: the state at `t`, in the same units.
|
|
17
|
+
*
|
|
18
|
+
* ::: info Notes
|
|
19
|
+
*
|
|
20
|
+
* - The exact solution of the equations {@link cwHillDerivatives} gives to a numerical integrator: no step size, no accumulated error.
|
|
21
|
+
* - Same LVLH frame and `CwState` layout as `cwHillDerivatives`: `[x, y, z, xDot, yDot, zDot]`, with $ x $ radial, $ y $ along-track, $ z $ cross-track.
|
|
22
|
+
* - A state with $ \dot y_0 = -2n x_0 $ has no along-track drift: it traces a closed ellipse around the chief.
|
|
23
|
+
*
|
|
24
|
+
* :::
|
|
25
|
+
*
|
|
26
|
+
* @param state - Relative state `[x, y, z, xDot, yDot, zDot]` (finite).
|
|
27
|
+
* @param n - Mean motion of the circular reference orbit in **rad/s** (finite, > 0).
|
|
28
|
+
* @param t - Time to propagate in **s** (finite; negative goes backwards).
|
|
29
|
+
* @returns The relative state at `t`.
|
|
30
|
+
* @throws {TypeError} If any input is not a finite number.
|
|
31
|
+
* @throws {RangeError} If `n <= 0`.
|
|
32
|
+
* @group Orbits
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* import type { CwState } from '@interstellar-tools/types';
|
|
37
|
+
*
|
|
38
|
+
* // 100 m below the chief with no drift: back where it started after one orbit
|
|
39
|
+
* const n = 0.00113;
|
|
40
|
+
* const start: CwState = [-100, 0, 0, 0, 2 * n * 100, 0];
|
|
41
|
+
* const later = cwPropagate(start, n, (2 * Math.PI) / n);
|
|
42
|
+
* // later ≈ start
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @see {@link cwStateTransition}
|
|
46
|
+
* @see {@link cwTwoImpulseTransfer}
|
|
47
|
+
*/
|
|
48
|
+
export const cwPropagate = (state, n, t) => {
|
|
49
|
+
for (const x of state)
|
|
50
|
+
if (!Number.isFinite(x))
|
|
51
|
+
throw new TypeError(`state must have finite components. Received: ${x}`);
|
|
52
|
+
const { rr, rv, vr, vv } = cwStateTransition(n, t);
|
|
53
|
+
const r0 = [state[0], state[1], state[2]];
|
|
54
|
+
const v0 = [state[3], state[4], state[5]];
|
|
55
|
+
const rA = applyMatrix3(rr, r0);
|
|
56
|
+
const rB = applyMatrix3(rv, v0);
|
|
57
|
+
const vA = applyMatrix3(vr, r0);
|
|
58
|
+
const vB = applyMatrix3(vv, v0);
|
|
59
|
+
return [
|
|
60
|
+
rA[0] + rB[0],
|
|
61
|
+
rA[1] + rB[1],
|
|
62
|
+
rA[2] + rB[2],
|
|
63
|
+
vA[0] + vB[0],
|
|
64
|
+
vA[1] + vB[1],
|
|
65
|
+
vA[2] + vB[2]
|
|
66
|
+
];
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=cw-propagate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cw-propagate.js","sourceRoot":"","sources":["../../../src/categories/orbits/cw-propagate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAc,EAAE,CAAS,EAAE,CAAS,EAAW,EAAE;IAC3E,KAAK,MAAM,CAAC,IAAI,KAAK;QACnB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YACrB,MAAM,IAAI,SAAS,CAAC,gDAAgD,CAAC,EAAE,CAAC,CAAC;IAE7E,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnD,MAAM,EAAE,GAAsB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,MAAM,EAAE,GAAsB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,MAAM,EAAE,GAAG,YAAY,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,YAAY,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,YAAY,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,YAAY,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAEhC,OAAO;QACL,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACb,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACb,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACb,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACb,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACb,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;KACL,CAAC;AACb,CAAC,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Matrix3x3Type } from '@interstellar-tools/types';
|
|
2
|
+
/**
|
|
3
|
+
* The Clohessy–Wiltshire state transition matrix $ \Phi(t) $, split into its four 3×3 blocks:
|
|
4
|
+
* $ \mathbf r(t) = \Phi_{rr}\mathbf r_0 + \Phi_{rv}\mathbf v_0 $ and $ \mathbf v(t) = \Phi_{vr}\mathbf r_0 + \Phi_{vv}\mathbf v_0 $.
|
|
5
|
+
*
|
|
6
|
+
* @group Orbits
|
|
7
|
+
*/
|
|
8
|
+
export interface CwStateTransitionInterface {
|
|
9
|
+
/** Position from initial position. */
|
|
10
|
+
rr: Matrix3x3Type;
|
|
11
|
+
/** Position from initial velocity (s). */
|
|
12
|
+
rv: Matrix3x3Type;
|
|
13
|
+
/** Velocity from initial position (1/s). */
|
|
14
|
+
vr: Matrix3x3Type;
|
|
15
|
+
/** Velocity from initial velocity. */
|
|
16
|
+
vv: Matrix3x3Type;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Compute the **Clohessy–Wiltshire state transition matrix**: the closed-form solution of the CW / Hill equations.
|
|
20
|
+
*
|
|
21
|
+
* With $ s = \sin nt $ and $ c = \cos nt $, in the LVLH frame of {@link cwHillDerivatives}
|
|
22
|
+
* ($ x $ radial, $ y $ along-track, $ z $ cross-track):
|
|
23
|
+
*
|
|
24
|
+
* $$
|
|
25
|
+
* \Phi_{rr} = \begin{bmatrix} 4 - 3c & 0 & 0 \\ 6(s - nt) & 1 & 0 \\ 0 & 0 & c \end{bmatrix}, \quad
|
|
26
|
+
* \Phi_{rv} = \frac{1}{n}\begin{bmatrix} s & 2(1 - c) & 0 \\ -2(1 - c) & 4s - 3nt & 0 \\ 0 & 0 & s \end{bmatrix}
|
|
27
|
+
* $$
|
|
28
|
+
*
|
|
29
|
+
* $$
|
|
30
|
+
* \Phi_{vr} = \begin{bmatrix} 3ns & 0 & 0 \\ 6n(c - 1) & 0 & 0 \\ 0 & 0 & -ns \end{bmatrix}, \quad
|
|
31
|
+
* \Phi_{vv} = \begin{bmatrix} c & 2s & 0 \\ -2s & 4c - 3 & 0 \\ 0 & 0 & c \end{bmatrix}
|
|
32
|
+
* $$
|
|
33
|
+
*
|
|
34
|
+
* **Units**
|
|
35
|
+
* - Inputs: `n` in **rad/s**, `t` in **s**.
|
|
36
|
+
* - Output: dimensionless blocks, except $ \Phi_{rv} $ in **s** and $ \Phi_{vr} $ in **1/s**.
|
|
37
|
+
*
|
|
38
|
+
* ::: info Notes
|
|
39
|
+
*
|
|
40
|
+
* - Valid near a **circular** reference orbit, for separations small compared with its radius. Elliptic reference orbits need other solutions (e.g. Yamanaka–Ankersen).
|
|
41
|
+
* - The $ -3nt $ terms grow without bound: a deputy slightly lower than the chief drifts ahead every orbit.
|
|
42
|
+
* - $ \Phi(0) $ is the identity, and $ \Phi(t_1 + t_2) = \Phi(t_2)\,\Phi(t_1) $.
|
|
43
|
+
* - Negative `t` propagates backwards.
|
|
44
|
+
*
|
|
45
|
+
* :::
|
|
46
|
+
*
|
|
47
|
+
* @param n - Mean motion of the circular reference orbit $ n $ in **rad/s** (finite, > 0).
|
|
48
|
+
* @param t - Time since the initial state $ t $ in **s** (finite).
|
|
49
|
+
* @returns The four 3×3 blocks of $ \Phi(t) $.
|
|
50
|
+
* @throws {TypeError} If any input is not a finite number.
|
|
51
|
+
* @throws {RangeError} If `n <= 0`.
|
|
52
|
+
* @group Orbits
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* // ISS-like orbit: n ≈ 0.00113 rad/s, a quarter of an orbit later
|
|
57
|
+
* const { rr, rv } = cwStateTransition(0.00113, (Math.PI / 2) / 0.00113);
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @see {@link cwPropagate}
|
|
61
|
+
* @see {@link cwTwoImpulseTransfer}
|
|
62
|
+
* @see https://en.wikipedia.org/wiki/Clohessy%E2%80%93Wiltshire_equations Clohessy–Wiltshire equations
|
|
63
|
+
*/
|
|
64
|
+
export declare const cwStateTransition: (n: number, t: number) => CwStateTransitionInterface;
|
|
65
|
+
//# sourceMappingURL=cw-state-transition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cw-state-transition.d.ts","sourceRoot":"","sources":["../../../src/categories/orbits/cw-state-transition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACzC,sCAAsC;IACtC,EAAE,EAAE,aAAa,CAAC;IAClB,0CAA0C;IAC1C,EAAE,EAAE,aAAa,CAAC;IAClB,4CAA4C;IAC5C,EAAE,EAAE,aAAa,CAAC;IAClB,sCAAsC;IACtC,EAAE,EAAE,aAAa,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,eAAO,MAAM,iBAAiB,GAC5B,GAAG,MAAM,EACT,GAAG,MAAM,KACR,0BAqCF,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute the **Clohessy–Wiltshire state transition matrix**: the closed-form solution of the CW / Hill equations.
|
|
3
|
+
*
|
|
4
|
+
* With $ s = \sin nt $ and $ c = \cos nt $, in the LVLH frame of {@link cwHillDerivatives}
|
|
5
|
+
* ($ x $ radial, $ y $ along-track, $ z $ cross-track):
|
|
6
|
+
*
|
|
7
|
+
* $$
|
|
8
|
+
* \Phi_{rr} = \begin{bmatrix} 4 - 3c & 0 & 0 \\ 6(s - nt) & 1 & 0 \\ 0 & 0 & c \end{bmatrix}, \quad
|
|
9
|
+
* \Phi_{rv} = \frac{1}{n}\begin{bmatrix} s & 2(1 - c) & 0 \\ -2(1 - c) & 4s - 3nt & 0 \\ 0 & 0 & s \end{bmatrix}
|
|
10
|
+
* $$
|
|
11
|
+
*
|
|
12
|
+
* $$
|
|
13
|
+
* \Phi_{vr} = \begin{bmatrix} 3ns & 0 & 0 \\ 6n(c - 1) & 0 & 0 \\ 0 & 0 & -ns \end{bmatrix}, \quad
|
|
14
|
+
* \Phi_{vv} = \begin{bmatrix} c & 2s & 0 \\ -2s & 4c - 3 & 0 \\ 0 & 0 & c \end{bmatrix}
|
|
15
|
+
* $$
|
|
16
|
+
*
|
|
17
|
+
* **Units**
|
|
18
|
+
* - Inputs: `n` in **rad/s**, `t` in **s**.
|
|
19
|
+
* - Output: dimensionless blocks, except $ \Phi_{rv} $ in **s** and $ \Phi_{vr} $ in **1/s**.
|
|
20
|
+
*
|
|
21
|
+
* ::: info Notes
|
|
22
|
+
*
|
|
23
|
+
* - Valid near a **circular** reference orbit, for separations small compared with its radius. Elliptic reference orbits need other solutions (e.g. Yamanaka–Ankersen).
|
|
24
|
+
* - The $ -3nt $ terms grow without bound: a deputy slightly lower than the chief drifts ahead every orbit.
|
|
25
|
+
* - $ \Phi(0) $ is the identity, and $ \Phi(t_1 + t_2) = \Phi(t_2)\,\Phi(t_1) $.
|
|
26
|
+
* - Negative `t` propagates backwards.
|
|
27
|
+
*
|
|
28
|
+
* :::
|
|
29
|
+
*
|
|
30
|
+
* @param n - Mean motion of the circular reference orbit $ n $ in **rad/s** (finite, > 0).
|
|
31
|
+
* @param t - Time since the initial state $ t $ in **s** (finite).
|
|
32
|
+
* @returns The four 3×3 blocks of $ \Phi(t) $.
|
|
33
|
+
* @throws {TypeError} If any input is not a finite number.
|
|
34
|
+
* @throws {RangeError} If `n <= 0`.
|
|
35
|
+
* @group Orbits
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* // ISS-like orbit: n ≈ 0.00113 rad/s, a quarter of an orbit later
|
|
40
|
+
* const { rr, rv } = cwStateTransition(0.00113, (Math.PI / 2) / 0.00113);
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @see {@link cwPropagate}
|
|
44
|
+
* @see {@link cwTwoImpulseTransfer}
|
|
45
|
+
* @see https://en.wikipedia.org/wiki/Clohessy%E2%80%93Wiltshire_equations Clohessy–Wiltshire equations
|
|
46
|
+
*/
|
|
47
|
+
export const cwStateTransition = (n, t) => {
|
|
48
|
+
for (const [name, x] of [
|
|
49
|
+
['n', n],
|
|
50
|
+
['t', t]
|
|
51
|
+
]) {
|
|
52
|
+
if (!Number.isFinite(x))
|
|
53
|
+
throw new TypeError(`${name} must be a finite number. Received: ${x}`);
|
|
54
|
+
}
|
|
55
|
+
if (n <= 0)
|
|
56
|
+
throw new RangeError(`n must be > 0. Received: ${n}`);
|
|
57
|
+
const nt = n * t;
|
|
58
|
+
const s = Math.sin(nt);
|
|
59
|
+
const c = Math.cos(nt);
|
|
60
|
+
return {
|
|
61
|
+
rr: [
|
|
62
|
+
[4 - 3 * c, 0, 0],
|
|
63
|
+
[6 * (s - nt), 1, 0],
|
|
64
|
+
[0, 0, c]
|
|
65
|
+
],
|
|
66
|
+
rv: [
|
|
67
|
+
[s / n, (2 * (1 - c)) / n, 0],
|
|
68
|
+
[(-2 * (1 - c)) / n, (4 * s - 3 * nt) / n, 0],
|
|
69
|
+
[0, 0, s / n]
|
|
70
|
+
],
|
|
71
|
+
vr: [
|
|
72
|
+
[3 * n * s, 0, 0],
|
|
73
|
+
[6 * n * (c - 1), 0, 0],
|
|
74
|
+
[0, 0, -n * s]
|
|
75
|
+
],
|
|
76
|
+
vv: [
|
|
77
|
+
[c, 2 * s, 0],
|
|
78
|
+
[-2 * s, 4 * c - 3, 0],
|
|
79
|
+
[0, 0, c]
|
|
80
|
+
]
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=cw-state-transition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cw-state-transition.js","sourceRoot":"","sources":["../../../src/categories/orbits/cw-state-transition.ts"],"names":[],"mappings":"AAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,CAAS,EACT,CAAS,EACmB,EAAE;IAC9B,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI;QACtB,CAAC,GAAG,EAAE,CAAC,CAAC;QACR,CAAC,GAAG,EAAE,CAAC,CAAC;KACA,EAAE,CAAC;QACX,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YACrB,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,uCAAuC,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,4BAA4B,CAAC,EAAE,CAAC,CAAC;IAElE,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACvB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEvB,OAAO;QACL,EAAE,EAAE;YACF,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACjB,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACpB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;SACV;QACD,EAAE,EAAE;YACF,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7B,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7C,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;SACd;QACD,EAAE,EAAE;YACF,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACjB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACvB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;SACf;QACD,EAAE,EAAE;YACF,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACtB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;SACV;KACF,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute the **eccentricity of a hyperbola** from the excess speed and the periapsis distance.
|
|
3
|
+
*
|
|
4
|
+
* $$
|
|
5
|
+
* e = 1 + \frac{r_p\, v_\infty^2}{\mu}
|
|
6
|
+
* $$
|
|
7
|
+
*
|
|
8
|
+
* Where:
|
|
9
|
+
* - $ r_p $ is the periapsis distance from the body's centre (m)
|
|
10
|
+
* - $ v_\infty $ is the hyperbolic excess speed (m/s)
|
|
11
|
+
* - $ \mu $ is the body's gravitational parameter (m³/s²)
|
|
12
|
+
*
|
|
13
|
+
* **Units**
|
|
14
|
+
* - Inputs: `vInfinity` in **m/s**, `rp` in **m**, `mu` in **m³/s²**.
|
|
15
|
+
* - Output: $ e $ dimensionless, > 1.
|
|
16
|
+
*
|
|
17
|
+
* ::: info Notes
|
|
18
|
+
*
|
|
19
|
+
* - From $ r_p = a(1 - e) $ with $ a = -\mu / v_\infty^2 $.
|
|
20
|
+
* - A slow, close pass gives $ e $ just above 1, a nearly parabolic swing; a fast, distant one gives a large $ e $ and a nearly straight path.
|
|
21
|
+
* - The trajectory turns through $ 2\arcsin(1/e) $; see `gravityAssistTurningAngle`.
|
|
22
|
+
*
|
|
23
|
+
* :::
|
|
24
|
+
*
|
|
25
|
+
* ::: practice Apollo 11, arriving at the Moon
|
|
26
|
+
*
|
|
27
|
+
* **1.44**
|
|
28
|
+
*
|
|
29
|
+
* _Approach hyperbola: 1.08 km/s excess speed, closest approach 113.9 km above the surface_
|
|
30
|
+
*
|
|
31
|
+
* ```ts
|
|
32
|
+
* hyperbolicEccentricity(1080, 1_737_400 + 113_900, 4.902800118e12); // ≈ 1.440
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* :::
|
|
36
|
+
*
|
|
37
|
+
* @param vInfinity - Hyperbolic excess speed $ v_\infty $ in **m/s** (finite, > 0).
|
|
38
|
+
* @param rp - Periapsis distance $ r_p $ in **m** (finite, > 0).
|
|
39
|
+
* @param mu - Gravitational parameter $ \mu $ in **m³/s²** (finite, > 0).
|
|
40
|
+
* @returns Eccentricity $ e $ (> 1).
|
|
41
|
+
* @throws {TypeError} If any input is not a finite number.
|
|
42
|
+
* @throws {RangeError} If `vInfinity <= 0`, `rp <= 0` or `mu <= 0`.
|
|
43
|
+
* @group Orbits
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* // A Jupiter flyby: v∞ = 6 km/s, periapsis at 5 Jupiter radii
|
|
48
|
+
* const e = hyperbolicEccentricity(6000, 5 * 71_492e3, 1.26686534e17);
|
|
49
|
+
* // e ≈ 1.102
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @see {@link hyperbolicSemiMajorAxis}
|
|
53
|
+
* @see {@link asymptoteTrueAnomaly}
|
|
54
|
+
*/
|
|
55
|
+
export declare const hyperbolicEccentricity: (vInfinity: number, rp: number, mu: number) => number;
|
|
56
|
+
//# sourceMappingURL=hyperbolic-eccentricity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyperbolic-eccentricity.d.ts","sourceRoot":"","sources":["../../../src/categories/orbits/hyperbolic-eccentricity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,eAAO,MAAM,sBAAsB,GACjC,WAAW,MAAM,EACjB,IAAI,MAAM,EACV,IAAI,MAAM,KACT,MAkBF,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute the **eccentricity of a hyperbola** from the excess speed and the periapsis distance.
|
|
3
|
+
*
|
|
4
|
+
* $$
|
|
5
|
+
* e = 1 + \frac{r_p\, v_\infty^2}{\mu}
|
|
6
|
+
* $$
|
|
7
|
+
*
|
|
8
|
+
* Where:
|
|
9
|
+
* - $ r_p $ is the periapsis distance from the body's centre (m)
|
|
10
|
+
* - $ v_\infty $ is the hyperbolic excess speed (m/s)
|
|
11
|
+
* - $ \mu $ is the body's gravitational parameter (m³/s²)
|
|
12
|
+
*
|
|
13
|
+
* **Units**
|
|
14
|
+
* - Inputs: `vInfinity` in **m/s**, `rp` in **m**, `mu` in **m³/s²**.
|
|
15
|
+
* - Output: $ e $ dimensionless, > 1.
|
|
16
|
+
*
|
|
17
|
+
* ::: info Notes
|
|
18
|
+
*
|
|
19
|
+
* - From $ r_p = a(1 - e) $ with $ a = -\mu / v_\infty^2 $.
|
|
20
|
+
* - A slow, close pass gives $ e $ just above 1, a nearly parabolic swing; a fast, distant one gives a large $ e $ and a nearly straight path.
|
|
21
|
+
* - The trajectory turns through $ 2\arcsin(1/e) $; see `gravityAssistTurningAngle`.
|
|
22
|
+
*
|
|
23
|
+
* :::
|
|
24
|
+
*
|
|
25
|
+
* ::: practice Apollo 11, arriving at the Moon
|
|
26
|
+
*
|
|
27
|
+
* **1.44**
|
|
28
|
+
*
|
|
29
|
+
* _Approach hyperbola: 1.08 km/s excess speed, closest approach 113.9 km above the surface_
|
|
30
|
+
*
|
|
31
|
+
* ```ts
|
|
32
|
+
* hyperbolicEccentricity(1080, 1_737_400 + 113_900, 4.902800118e12); // ≈ 1.440
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* :::
|
|
36
|
+
*
|
|
37
|
+
* @param vInfinity - Hyperbolic excess speed $ v_\infty $ in **m/s** (finite, > 0).
|
|
38
|
+
* @param rp - Periapsis distance $ r_p $ in **m** (finite, > 0).
|
|
39
|
+
* @param mu - Gravitational parameter $ \mu $ in **m³/s²** (finite, > 0).
|
|
40
|
+
* @returns Eccentricity $ e $ (> 1).
|
|
41
|
+
* @throws {TypeError} If any input is not a finite number.
|
|
42
|
+
* @throws {RangeError} If `vInfinity <= 0`, `rp <= 0` or `mu <= 0`.
|
|
43
|
+
* @group Orbits
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* // A Jupiter flyby: v∞ = 6 km/s, periapsis at 5 Jupiter radii
|
|
48
|
+
* const e = hyperbolicEccentricity(6000, 5 * 71_492e3, 1.26686534e17);
|
|
49
|
+
* // e ≈ 1.102
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @see {@link hyperbolicSemiMajorAxis}
|
|
53
|
+
* @see {@link asymptoteTrueAnomaly}
|
|
54
|
+
*/
|
|
55
|
+
export const hyperbolicEccentricity = (vInfinity, rp, mu) => {
|
|
56
|
+
for (const [name, x] of [
|
|
57
|
+
['vInfinity', vInfinity],
|
|
58
|
+
['rp', rp],
|
|
59
|
+
['mu', mu]
|
|
60
|
+
]) {
|
|
61
|
+
if (!Number.isFinite(x))
|
|
62
|
+
throw new TypeError(`${name} must be a finite number. Received: ${x}`);
|
|
63
|
+
}
|
|
64
|
+
if (vInfinity <= 0)
|
|
65
|
+
throw new RangeError(`vInfinity must be > 0. Received: ${vInfinity}`);
|
|
66
|
+
if (rp <= 0)
|
|
67
|
+
throw new RangeError(`rp must be > 0. Received: ${rp}`);
|
|
68
|
+
if (mu <= 0)
|
|
69
|
+
throw new RangeError(`mu must be > 0. Received: ${mu}`);
|
|
70
|
+
return 1 + (rp * vInfinity * vInfinity) / mu;
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=hyperbolic-eccentricity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyperbolic-eccentricity.js","sourceRoot":"","sources":["../../../src/categories/orbits/hyperbolic-eccentricity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,SAAiB,EACjB,EAAU,EACV,EAAU,EACF,EAAE;IACV,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI;QACtB,CAAC,WAAW,EAAE,SAAS,CAAC;QACxB,CAAC,IAAI,EAAE,EAAE,CAAC;QACV,CAAC,IAAI,EAAE,EAAE,CAAC;KACF,EAAE,CAAC;QACX,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YACrB,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,uCAAuC,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,SAAS,IAAI,CAAC;QAChB,MAAM,IAAI,UAAU,CAAC,oCAAoC,SAAS,EAAE,CAAC,CAAC;IAExE,IAAI,EAAE,IAAI,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,6BAA6B,EAAE,EAAE,CAAC,CAAC;IAErE,IAAI,EAAE,IAAI,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,6BAA6B,EAAE,EAAE,CAAC,CAAC;IAErE,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,GAAG,SAAS,CAAC,GAAG,EAAE,CAAC;AAC/C,CAAC,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute the **semi-major axis of a hyperbola** from the hyperbolic excess speed.
|
|
3
|
+
*
|
|
4
|
+
* $$
|
|
5
|
+
* a = -\frac{\mu}{v_\infty^2}
|
|
6
|
+
* $$
|
|
7
|
+
*
|
|
8
|
+
* Where:
|
|
9
|
+
* - $ v_\infty $ is the hyperbolic excess speed: the speed left over far from the body (m/s)
|
|
10
|
+
* - $ \mu $ is the body's gravitational parameter (m³/s²)
|
|
11
|
+
*
|
|
12
|
+
* **Units**
|
|
13
|
+
* - Inputs: `vInfinity` in **m/s**, `mu` in **m³/s²**.
|
|
14
|
+
* - Output: $ a $ in **m**, negative.
|
|
15
|
+
*
|
|
16
|
+
* ::: info Notes
|
|
17
|
+
*
|
|
18
|
+
* - Negative by convention, so that vis-viva $ v^2 = \mu(2/r - 1/a) $ holds for hyperbolas too.
|
|
19
|
+
* - $ v_\infty $ comes from a speed $ v $ at distance $ r $ by energy: $ v_\infty^2 = v^2 - 2\mu/r $, or from {@link characteristicEnergyC3} as $ \sqrt{C_3} $.
|
|
20
|
+
*
|
|
21
|
+
* :::
|
|
22
|
+
*
|
|
23
|
+
* ::: practice Apollo 11, arriving at the Moon
|
|
24
|
+
*
|
|
25
|
+
* **−4 203 km**
|
|
26
|
+
*
|
|
27
|
+
* _Approach hyperbola, with 1.08 km/s left over far from the Moon_
|
|
28
|
+
*
|
|
29
|
+
* ```ts
|
|
30
|
+
* hyperbolicSemiMajorAxis(1080, 4.902800118e12); // ≈ -4 203 361 m
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* :::
|
|
34
|
+
*
|
|
35
|
+
* @param vInfinity - Hyperbolic excess speed $ v_\infty $ in **m/s** (finite, > 0).
|
|
36
|
+
* @param mu - Gravitational parameter $ \mu $ in **m³/s²** (finite, > 0).
|
|
37
|
+
* @returns Semi-major axis $ a $ in **m** (negative).
|
|
38
|
+
* @throws {TypeError} If any input is not a finite number.
|
|
39
|
+
* @throws {RangeError} If `vInfinity <= 0` or `mu <= 0`.
|
|
40
|
+
* @group Orbits
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* // Leaving Earth for Mars with v∞ ≈ 2.95 km/s
|
|
45
|
+
* const a = hyperbolicSemiMajorAxis(2950, 3.986004418e14);
|
|
46
|
+
* // a ≈ -45 803 km
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @see {@link hyperbolicEccentricity}
|
|
50
|
+
* @see {@link hyperbolicPeriapsisSpeed}
|
|
51
|
+
*/
|
|
52
|
+
export declare const hyperbolicSemiMajorAxis: (vInfinity: number, mu: number) => number;
|
|
53
|
+
//# sourceMappingURL=hyperbolic-semi-major-axis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyperbolic-semi-major-axis.d.ts","sourceRoot":"","sources":["../../../src/categories/orbits/hyperbolic-semi-major-axis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,eAAO,MAAM,uBAAuB,GAClC,WAAW,MAAM,EACjB,IAAI,MAAM,KACT,MAeF,CAAC"}
|