abstract-math 0.0.0.27__tar.gz → 0.0.0.47__tar.gz
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.
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/PKG-INFO +1 -1
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/setup.py +1 -1
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/flask_scripts/flask_utils.py +1 -1
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/safe_math.py +1 -1
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/solar_math/flask_utils.py +1 -1
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/solar_math/main.py +38 -37
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/solar_math/src/constants/__init__.py +13 -3
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/solar_math/src/constants/distance_constants.py +20 -15
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/solar_math/src/constants/planet_constants.py +35 -34
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/solar_math/src/constants/time_constants.py +17 -13
- abstract_math-0.0.0.47/src/abstract_math/solar_math/src/imports.py +5 -0
- abstract_math-0.0.0.47/src/abstract_math/solar_math/src/utils/escape_velocity.py +145 -0
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/solar_math/src/utils/geometry_utils.py +9 -9
- abstract_math-0.0.0.47/src/abstract_math/solar_math/src/utils/velocity_utils.py +74 -0
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math.egg-info/PKG-INFO +1 -1
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math.egg-info/SOURCES.txt +2 -1
- abstract_math-0.0.0.47/tests/test.py +5 -0
- abstract_math-0.0.0.27/src/abstract_math/solar_math/src/imports.py +0 -5
- abstract_math-0.0.0.27/src/abstract_math/solar_math/src/utils/escape_velocity.py +0 -111
- abstract_math-0.0.0.27/src/abstract_math/solar_math/src/utils/velocity_utils.py +0 -52
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/README.md +0 -0
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/pyproject.toml +0 -0
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/setup.cfg +0 -0
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/__init__.py +0 -0
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/createflask.py +0 -0
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/derive_tokens.py +0 -0
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/flask_scripts/__init__.py +0 -0
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/solar_math/__init__.py +0 -0
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/solar_math/src/__init__.py +0 -0
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/solar_math/src/utils/__init__.py +0 -0
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math.egg-info/dependency_links.txt +0 -0
- {abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math.egg-info/top_level.txt +0 -0
{abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/flask_scripts/flask_utils.py
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from abstract_flask import
|
|
1
|
+
from abstract_flask import offer_help,Blueprint,get_logFile,get_request_data,jsonify # must provide Blueprint, request, jsonify, get_request_data, get_logFile, offer_help
|
|
2
2
|
from ..solar_math import *
|
|
3
3
|
# Auto-generated routes
|
|
4
4
|
math_data_bp = Blueprint('math_data_bp', __name__, url_prefix='/utils/')
|
{abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/solar_math/flask_utils.py
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from abstract_flask import
|
|
1
|
+
from abstract_flask import generate_from_files
|
|
2
2
|
from abstract_utilities import write_to_file
|
|
3
3
|
directory='/home/computron/Documents/pythonTools/modules/abstract_math/src/abstract_math/solar_math'
|
|
4
4
|
output_file='/home/computron/Documents/pythonTools/modules/abstract_math/src/abstract_math/flask_scripts/flask_utils.py'
|
|
@@ -5,31 +5,32 @@ from .src.constants.time_constants import seconds_per
|
|
|
5
5
|
from .src.constants.planet_constants import planet_radius, get_body, g_at_radius
|
|
6
6
|
from .src.utils.geometry_utils import visible_area_flat, visible_surface_angle
|
|
7
7
|
from .src.utils import get_R_mu,get_normalized_distance,get_normalized_starting_velocity
|
|
8
|
-
from .src.imports import math, mul, div, add # your abstract_math ops
|
|
8
|
+
from .src.imports import math, mul, div, add, exp # your abstract_math ops
|
|
9
9
|
from .src.constants import (
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
DEFAULT_DIST_UNIT,
|
|
11
|
+
DEFAULT_TIME_UNIT,
|
|
12
12
|
DEFAULT_PLANET,
|
|
13
13
|
DEFAULT_START_ALTITUDE,
|
|
14
14
|
DEFAULT_AS_RADIUS
|
|
15
15
|
)
|
|
16
|
+
|
|
16
17
|
def normalize_inputs(
|
|
17
18
|
planet: str,
|
|
18
19
|
start_altitude: float,
|
|
19
20
|
starting_velocity: float,
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
input_dist_unit: str,
|
|
22
|
+
input_time_unit: str,
|
|
22
23
|
target_distance: float = None,
|
|
23
24
|
) -> dict:
|
|
24
25
|
"""Normalize input altitudes and velocities into SI (meters, seconds)."""
|
|
25
|
-
start_alt_m = get_normalized_distance(start_altitude,
|
|
26
|
-
target_alt_m = get_normalized_distance(target_distance,
|
|
26
|
+
start_alt_m = get_normalized_distance(start_altitude, input_dist_unit)
|
|
27
|
+
target_alt_m = get_normalized_distance(target_distance, input_dist_unit)
|
|
27
28
|
|
|
28
29
|
v0_mps = get_normalized_starting_velocity(
|
|
29
30
|
start_altitude=start_alt_m,
|
|
30
31
|
starting_velocity=starting_velocity,
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
input_dist_unit=input_dist_unit,
|
|
33
|
+
input_time_unit=input_time_unit,
|
|
33
34
|
planet=planet,
|
|
34
35
|
)
|
|
35
36
|
|
|
@@ -44,43 +45,43 @@ def analyze_visible_surface(
|
|
|
44
45
|
max_steps: int = 20,
|
|
45
46
|
fov_range: tuple[int, int] = (20, 160),
|
|
46
47
|
fov_interval: int = 10,
|
|
47
|
-
|
|
48
|
-
display_units: str =
|
|
48
|
+
input_dist_unit: str = DEFAULT_DIST_UNIT, # how to interpret altitude numbers
|
|
49
|
+
display_units: str = DEFAULT_DIST_UNIT, # how to print areas/radii
|
|
49
50
|
planet: str = DEFAULT_PLANET,
|
|
50
51
|
printit: bool = False
|
|
51
52
|
):
|
|
52
53
|
"""
|
|
53
|
-
Scan altitudes/FOVs. Altitudes are interpreted in `
|
|
54
|
+
Scan altitudes/FOVs. Altitudes are interpreted in `input_dist_unit`.
|
|
54
55
|
Results are printed in `display_units`.
|
|
55
56
|
"""
|
|
56
57
|
# Planet radius and full area (compute in meters, convert for display)
|
|
57
|
-
r_m = planet_radius(planet,
|
|
58
|
+
r_m = planet_radius(planet, DEFAULT_DIST_UNIT)
|
|
58
59
|
full_area_m2 = 4.0 * math.pi * (r_m ** 2)
|
|
59
|
-
k_disp = dfactor(
|
|
60
|
+
k_disp = dfactor(DEFAULT_DIST_UNIT, display_units) # linear meter->display factor
|
|
60
61
|
full_area_disp = full_area_m2 * (k_disp ** 2) # convert area to display units^2
|
|
61
62
|
|
|
62
|
-
all_stats = {"output": "", "
|
|
63
|
+
all_stats = {"output": "", "input_dist_unit": input_dist_unit,
|
|
63
64
|
"display_units": display_units, "vars": []}
|
|
64
65
|
|
|
65
66
|
for i in range(1, max_steps + 1):
|
|
66
67
|
all_stats["vars"].append({})
|
|
67
|
-
altitude_in = altitude_step * i #
|
|
68
|
-
altitude_m = dconvert(altitude_in,
|
|
68
|
+
altitude_in = altitude_step * i # input_dist_unit
|
|
69
|
+
altitude_m = dconvert(altitude_in, input_dist_unit, DEFAULT_DIST_UNIT)
|
|
69
70
|
|
|
70
71
|
all_stats["vars"][-1]['altitude_input'] = altitude_in
|
|
71
|
-
all_stats["vars"][-1]['
|
|
72
|
+
all_stats["vars"][-1]['input_dist_unit'] = input_dist_unit
|
|
72
73
|
all_stats["vars"][-1]['fov'] = []
|
|
73
74
|
|
|
74
|
-
alt_pretty = dconvert(altitude_in,
|
|
75
|
+
alt_pretty = dconvert(altitude_in, input_dist_unit, display_units)
|
|
75
76
|
all_stats["output"] += (
|
|
76
|
-
f"\n=== Altitude: {altitude_in} {
|
|
77
|
+
f"\n=== Altitude: {altitude_in} {input_dist_unit} (≈ {alt_pretty:.3f} {display_units}) ===\n"
|
|
77
78
|
)
|
|
78
79
|
|
|
79
80
|
for fov in range(fov_range[0], fov_range[1] + 1, fov_interval):
|
|
80
81
|
# Compute visible area/radius in meters, convert to display units
|
|
81
|
-
area_m2, vis_radius_m = visible_area_flat(fov, altitude_m,
|
|
82
|
+
area_m2, vis_radius_m = visible_area_flat(fov, altitude_m, DEFAULT_DIST_UNIT)
|
|
82
83
|
area_disp = area_m2 * (k_disp ** 2)
|
|
83
|
-
vis_radius_disp = dconvert(vis_radius_m,
|
|
84
|
+
vis_radius_disp = dconvert(vis_radius_m, DEFAULT_DIST_UNIT, display_units)
|
|
84
85
|
|
|
85
86
|
# Span uses geometry only; r_m is in meters
|
|
86
87
|
_, angle_deg = visible_surface_angle(vis_radius_m, r_m)
|
|
@@ -198,7 +199,7 @@ def simulate_radial_flight_si(
|
|
|
198
199
|
"hit_target": hit_target,
|
|
199
200
|
"turned_back": turned_back,
|
|
200
201
|
"traveled_m": traveled_m,
|
|
201
|
-
"vesc_end_mps":
|
|
202
|
+
"vesc_end_mps": exp(mul(2.0, div(mu, r)),-2),
|
|
202
203
|
|
|
203
204
|
# extended stats
|
|
204
205
|
"furthest_r": tracker["furthest_r"],
|
|
@@ -212,10 +213,10 @@ def simulate_radial_flight_si(
|
|
|
212
213
|
def radial_travel(
|
|
213
214
|
starting_velocity: float = None,
|
|
214
215
|
start_altitude: float = None,
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
216
|
+
input_dist_unit: str = DEFAULT_DIST_UNIT,
|
|
217
|
+
input_time_unit: str = DEFAULT_TIME_UNIT,
|
|
218
|
+
output_dist_unit: str = DEFAULT_DIST_UNIT,
|
|
219
|
+
output_time_unit: str = DEFAULT_TIME_UNIT,
|
|
219
220
|
*,
|
|
220
221
|
planet: str = DEFAULT_PLANET,
|
|
221
222
|
dt_s: float = 1.0,
|
|
@@ -225,7 +226,7 @@ def radial_travel(
|
|
|
225
226
|
"""Wrapper: handles units, runs SI integrator, converts outputs."""
|
|
226
227
|
norm = normalize_inputs(
|
|
227
228
|
planet=planet, start_altitude=start_altitude, starting_velocity=starting_velocity,
|
|
228
|
-
|
|
229
|
+
input_dist_unit=input_dist_unit, input_time_unit=input_time_unit, target_distance=target_distance
|
|
229
230
|
)
|
|
230
231
|
|
|
231
232
|
sim = simulate_radial_flight_si(
|
|
@@ -240,8 +241,8 @@ def radial_travel(
|
|
|
240
241
|
return sim
|
|
241
242
|
|
|
242
243
|
# Output conversions
|
|
243
|
-
sec_per_out = seconds_per(
|
|
244
|
-
conv = lambda m: dconvert(m,
|
|
244
|
+
sec_per_out = seconds_per(output_time_unit)
|
|
245
|
+
conv = lambda m: dconvert(m, DEFAULT_DIST_UNIT, output_dist_unit)
|
|
245
246
|
|
|
246
247
|
return {
|
|
247
248
|
"ok": True,
|
|
@@ -249,20 +250,20 @@ def radial_travel(
|
|
|
249
250
|
"inputs": {
|
|
250
251
|
"start_altitude": start_altitude,
|
|
251
252
|
"starting_velocity": starting_velocity,
|
|
252
|
-
"
|
|
253
|
-
"
|
|
254
|
-
"
|
|
255
|
-
"
|
|
253
|
+
"input_dist_unit": input_dist_unit,
|
|
254
|
+
"input_time_unit": input_time_unit,
|
|
255
|
+
"output_dist_unit": output_dist_unit,
|
|
256
|
+
"output_time_unit": output_time_unit,
|
|
256
257
|
"target_distance": target_distance,
|
|
257
258
|
},
|
|
258
259
|
# final state
|
|
259
260
|
"altitude": conv(sim["altitude_m"]),
|
|
260
261
|
"radius_from_center": conv(sim["r_m"]),
|
|
261
262
|
"distance_traveled": conv(sim["traveled_m"]),
|
|
262
|
-
"velocity": mul(dconvert(sim["vEnd_mps"],
|
|
263
|
-
"velocity_escape_end": mul(dconvert(sim["vesc_end_mps"],
|
|
263
|
+
"velocity": mul(dconvert(sim["vEnd_mps"], DEFAULT_DIST_UNIT, output_dist_unit), sec_per_out),
|
|
264
|
+
"velocity_escape_end": mul(dconvert(sim["vesc_end_mps"], DEFAULT_DIST_UNIT, output_dist_unit), sec_per_out),
|
|
264
265
|
"time": div(sim["time_s"], sec_per_out),
|
|
265
|
-
"time_unit":
|
|
266
|
+
"time_unit": output_time_unit,
|
|
266
267
|
"g_end_mps2": sim["g_end_mps2"],
|
|
267
268
|
"g_ratio_surface": sim["g_ratio_surface"],
|
|
268
269
|
"steps": sim["steps"],
|
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
from .distance_constants import (
|
|
3
3
|
DISTANCE_CONVERSIONS, ALL_DISTANCE_UNITS,
|
|
4
4
|
normalize_distance_unit, get_distance_unit_conversions,
|
|
5
|
-
_factor, dconvert,
|
|
5
|
+
_factor, dconvert,DEFAULT_DIST_UNIT,DEFAULT_START_ALTITUDE,
|
|
6
|
+
get_smallest_dist_unit_string
|
|
6
7
|
)
|
|
7
8
|
from .time_constants import (
|
|
8
9
|
TIME_CONVERSIONS, ALL_TIME_UNITS,
|
|
9
|
-
normalize_time_unit, get_time_unit_conversions,
|
|
10
|
-
time_factor, convert_time, seconds_per,
|
|
10
|
+
normalize_time_unit, get_time_unit_conversions,tconvert,
|
|
11
|
+
time_factor, convert_time, seconds_per,DEFAULT_TIME_UNIT,
|
|
12
|
+
get_smallest_time_unit_string
|
|
11
13
|
)
|
|
12
14
|
from .planet_constants import (
|
|
13
15
|
PLANETS, G, g0, MU_MOON,
|
|
@@ -18,3 +20,11 @@ from .planet_constants import (
|
|
|
18
20
|
earth_volume, earth_circumference,DEFAULT_PLANET,DEFAULT_AS_RADIUS,
|
|
19
21
|
distance_per_sec_to_mps
|
|
20
22
|
)
|
|
23
|
+
def get_smallest_unit_string(unit):
|
|
24
|
+
for key,values in DISTANCE_CONVERSIONS.items():
|
|
25
|
+
if unit in values["strings"]:
|
|
26
|
+
return values["strings"][0]
|
|
27
|
+
for key,values in TIME_CONVERSIONS.items():
|
|
28
|
+
if unit in values["strings"]:
|
|
29
|
+
return values["strings"][0]
|
|
30
|
+
return unit
|
|
@@ -19,8 +19,13 @@ DISTANCE_CONVERSIONS: Dict[str, Dict[str, Dict[str, float]]] = {
|
|
|
19
19
|
"feet": FEET
|
|
20
20
|
}
|
|
21
21
|
ALL_DISTANCE_UNITS = ("meters", "kilometers", "miles", "feet")
|
|
22
|
-
|
|
22
|
+
DEFAULT_DIST_UNIT="m"
|
|
23
23
|
DEFAULT_START_ALTITUDE=0.0
|
|
24
|
+
def get_smallest_dist_unit_string(unit):
|
|
25
|
+
for key,values in DISTANCE_CONVERSIONS.items():
|
|
26
|
+
if unit in values["strings"]:
|
|
27
|
+
return values["strings"][0]
|
|
28
|
+
return unit
|
|
24
29
|
# -------------------------
|
|
25
30
|
# Unit helpers
|
|
26
31
|
# -------------------------
|
|
@@ -34,36 +39,36 @@ def normalize_distance_unit(unit: str) -> str:
|
|
|
34
39
|
# was: CONVERSIONS
|
|
35
40
|
raise ValueError(f"Unknown unit '{unit}'. Supported: {list(DISTANCE_CONVERSIONS.keys())}")
|
|
36
41
|
|
|
37
|
-
def get_distance_unit_conversions(
|
|
38
|
-
return DISTANCE_CONVERSIONS[normalize_distance_unit(
|
|
42
|
+
def get_distance_unit_conversions(dist_unit: str) -> Dict[str, Dict[str, float]]:
|
|
43
|
+
return DISTANCE_CONVERSIONS[normalize_distance_unit(dist_unit)]
|
|
39
44
|
|
|
40
|
-
def _factor(
|
|
45
|
+
def _factor(dist_unit_from: str, dist_unit_to: str) -> float:
|
|
41
46
|
"""Multiplicative factor s.t. value_in_to = value_in_from * factor."""
|
|
42
|
-
uf = get_distance_unit_conversions(
|
|
43
|
-
ut = get_distance_unit_conversions(
|
|
47
|
+
uf = get_distance_unit_conversions(dist_unit_from)["conv"]["meters"] # meters per 1 from-unit
|
|
48
|
+
ut = get_distance_unit_conversions(dist_unit_to)["conv"]["meters"] # meters per 1 to-unit
|
|
44
49
|
return div(uf, ut)
|
|
45
50
|
|
|
46
|
-
def dconvert(value: float,
|
|
47
|
-
return mul(value, _factor(
|
|
51
|
+
def dconvert(value: float, dist_unit_from: str, dist_unit_to: str) -> float:
|
|
52
|
+
return mul(value, _factor(dist_unit_from, dist_unit_to))
|
|
48
53
|
def get_normalized_distance(
|
|
49
54
|
distance: Optional[float] = None,
|
|
50
|
-
|
|
55
|
+
input_dist_units: str = DEFAULT_DIST_UNIT
|
|
51
56
|
):
|
|
52
57
|
distance = target_alt_m = distance or 0
|
|
53
58
|
if distance is not None:
|
|
54
59
|
target_alt_m = dconvert(value=distance,
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
dist_unit_from=input_dist_units,
|
|
61
|
+
dist_unit_to=DEFAULT_DIST_UNIT
|
|
57
62
|
)
|
|
58
63
|
return target_alt_m
|
|
59
64
|
def get_target_distance(
|
|
60
65
|
distance: Optional[float] = None,
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
input_dist_units: str = DEFAULT_DIST_UNIT,
|
|
67
|
+
output_dist_units: str = DEFAULT_DIST_UNIT,
|
|
63
68
|
):
|
|
64
69
|
distance = target_distance = distance or 0
|
|
65
70
|
if distance is not None:
|
|
66
71
|
target_distance = dconvert(value=distance,
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
dist_unit_from=input_dist_units,
|
|
73
|
+
dist_unit_to=output_dist_units)
|
|
69
74
|
return target_distance
|
|
@@ -47,8 +47,9 @@ def _enrich_body(b: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
47
47
|
|
|
48
48
|
_NAME_ALIASES = {"sol": "sun", "terra": "earth", "luna": "moon"}
|
|
49
49
|
def _normalize_name(name: str) -> str:
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
if isinstance(name,str):
|
|
51
|
+
n = name.lower()
|
|
52
|
+
return _NAME_ALIASES.get(n, n)
|
|
52
53
|
|
|
53
54
|
_BODY_BY_NAME: Dict[str, Dict[str, Any]] = {}
|
|
54
55
|
for entry in PLANETS:
|
|
@@ -57,7 +58,7 @@ for entry in PLANETS:
|
|
|
57
58
|
# -------------------------
|
|
58
59
|
# Public API
|
|
59
60
|
# -------------------------
|
|
60
|
-
def get_planet_vars(name: str,
|
|
61
|
+
def get_planet_vars(name: str, dist_unit: str = "meters") -> Dict[str, Any]:
|
|
61
62
|
"""
|
|
62
63
|
Return body properties with radius/diameter in `units`.
|
|
63
64
|
Mass in kg; mu in m^3/s^2; surface_g in m/s^2.
|
|
@@ -67,49 +68,49 @@ def get_planet_vars(name: str, units: str = "meters") -> Dict[str, Any]:
|
|
|
67
68
|
if body is None:
|
|
68
69
|
raise KeyError(f"Unknown body '{name}'. Available: {sorted(_BODY_BY_NAME.keys())}")
|
|
69
70
|
|
|
70
|
-
|
|
71
|
+
dist_unit_norm = normalize_distance_unit(dist_unit)
|
|
71
72
|
r_m = body["radius"]
|
|
72
73
|
d_m = body["diameter"]
|
|
73
74
|
|
|
74
75
|
out = dict(body)
|
|
75
|
-
out["radius"] = dconvert(r_m, "meters",
|
|
76
|
-
out["diameter"] = dconvert(d_m, "meters",
|
|
77
|
-
out["
|
|
78
|
-
out["
|
|
76
|
+
out["radius"] = dconvert(r_m, "meters", dist_unit_norm)
|
|
77
|
+
out["diameter"] = dconvert(d_m, "meters", dist_unit_norm)
|
|
78
|
+
out["radius_unit"] = dist_unit_norm
|
|
79
|
+
out["diameter_unit"] = dist_unit_norm
|
|
79
80
|
return out
|
|
80
81
|
|
|
81
|
-
def planet_radius(name: str = "earth",
|
|
82
|
-
return get_planet_vars(name,
|
|
82
|
+
def planet_radius(name: str = "earth", dist_unit: str = "meters") -> float:
|
|
83
|
+
return get_planet_vars(name, dist_unit)["radius"]
|
|
83
84
|
|
|
84
|
-
def planet_diameter(name: str = "earth",
|
|
85
|
-
return get_planet_vars(name,
|
|
85
|
+
def planet_diameter(name: str = "earth", dist_unit: str = "meters") -> float:
|
|
86
|
+
return get_planet_vars(name, dist_unit)["diameter"]
|
|
86
87
|
|
|
87
|
-
def full_planet_surface_area(name: str = "earth",
|
|
88
|
-
r = planet_radius(name,
|
|
88
|
+
def full_planet_surface_area(name: str = "earth", dist_unit: str = 'meters') -> float:
|
|
89
|
+
r = planet_radius(name,dist_unit)
|
|
89
90
|
return mul(4 * pi(), exp(r, 2))
|
|
90
91
|
|
|
91
|
-
def planet_volume(name: str = "earth",
|
|
92
|
-
r = planet_radius(name,
|
|
92
|
+
def planet_volume(name: str = "earth", dist_unit: str = 'meters') -> float:
|
|
93
|
+
r = planet_radius(name,dist_unit)
|
|
93
94
|
return mul((4.0/3.0) * pi(), exp(r, 3))
|
|
94
95
|
|
|
95
|
-
def planet_circumference(name: str = "earth",
|
|
96
|
-
r = planet_radius(name,
|
|
96
|
+
def planet_circumference(name: str = "earth", dist_unit: str = 'meters') -> float:
|
|
97
|
+
r = planet_radius(name,dist_unit)
|
|
97
98
|
return mul(2 * pi(), r)
|
|
98
99
|
|
|
99
100
|
def planet_mass(name: str = "earth") -> float:
|
|
100
101
|
return get_planet_vars(name)["mass"]
|
|
101
102
|
|
|
102
|
-
def planet_surface_g(name: str = "earth", as_g0: bool = False) -> float:
|
|
103
|
-
v = get_planet_vars(name)["surface_g"]
|
|
103
|
+
def planet_surface_g(name: str = "earth", as_g0: bool = False, dist_unit: str = "meters") -> float:
|
|
104
|
+
v = get_planet_vars(name, dist_unit)["surface_g"]
|
|
104
105
|
return div(v, g0) if as_g0 else v
|
|
105
106
|
|
|
106
|
-
def escape_velocity(name: str = "earth", altitude: float = 0.0,
|
|
107
|
+
def escape_velocity(name: str = "earth", altitude: float = 0.0, dist_unit: str = "meters") -> float:
|
|
107
108
|
"""
|
|
108
109
|
Escape velocity (m/s) from altitude above surface.
|
|
109
110
|
"""
|
|
110
111
|
mu = _BODY_BY_NAME[_normalize_name(name)]["mu"]
|
|
111
112
|
r = _BODY_BY_NAME[_normalize_name(name)]["radius"] # meters
|
|
112
|
-
h_m = dconvert(altitude,
|
|
113
|
+
h_m = dconvert(altitude, dist_unit, "meters")
|
|
113
114
|
R = add(r, h_m)
|
|
114
115
|
return math.sqrt(mul(2.0, div(mu, R)))
|
|
115
116
|
|
|
@@ -119,31 +120,31 @@ def escape_velocity(name: str = "earth", altitude: float = 0.0, units: str = "me
|
|
|
119
120
|
def pi() -> float:
|
|
120
121
|
return math.pi
|
|
121
122
|
|
|
122
|
-
def earth_radius(
|
|
123
|
-
return planet_radius('earth',
|
|
123
|
+
def earth_radius(dist_unit: str = 'meters') -> float:
|
|
124
|
+
return planet_radius('earth', dist_unit)
|
|
124
125
|
|
|
125
|
-
def earth_diameter(
|
|
126
|
-
return planet_diameter('earth',
|
|
126
|
+
def earth_diameter(dist_unit: str = 'meters') -> float:
|
|
127
|
+
return planet_diameter('earth', dist_unit)
|
|
127
128
|
|
|
128
|
-
def full_earth_surface_area(
|
|
129
|
-
r = earth_radius(
|
|
129
|
+
def full_earth_surface_area(dist_unit: str = 'meters') -> float:
|
|
130
|
+
r = earth_radius(dist_unit)
|
|
130
131
|
return mul(4 * pi(), exp(r, 2))
|
|
131
132
|
|
|
132
|
-
def earth_volume(
|
|
133
|
-
r = earth_radius(
|
|
133
|
+
def earth_volume(dist_unit: str = 'meters') -> float:
|
|
134
|
+
r = earth_radius(dist_unit)
|
|
134
135
|
return mul((4.0/3.0) * pi(), exp(r, 3))
|
|
135
136
|
|
|
136
|
-
def earth_circumference(
|
|
137
|
-
r = earth_radius(
|
|
137
|
+
def earth_circumference(dist_unit: str = 'meters') -> float:
|
|
138
|
+
r = earth_radius(dist_unit)
|
|
138
139
|
return mul(2 * pi(), r)
|
|
139
140
|
|
|
140
141
|
# =========================
|
|
141
142
|
# Radial toy + single-call wrapper
|
|
142
143
|
# =========================
|
|
143
|
-
def distance_per_sec_to_mps(v_per_sec: float,
|
|
144
|
+
def distance_per_sec_to_mps(v_per_sec: float, dist_unit: str) -> float:
|
|
144
145
|
"""Convert a speed given in `units`/s into m/s using your convert()."""
|
|
145
146
|
# v [units/s] * (meters per 1 units) => [m/s]
|
|
146
|
-
return mul(v_per_sec, get_distance_unit_conversions(_normalize_unit(
|
|
147
|
+
return mul(v_per_sec, get_distance_unit_conversions(_normalize_unit(dist_unit))["conv"]["meters"])
|
|
147
148
|
|
|
148
149
|
|
|
149
150
|
def get_body(planet: str) -> Dict[str, Any]:
|
|
@@ -21,36 +21,40 @@ TIME_CONVERSIONS = {
|
|
|
21
21
|
"days": DAYS,
|
|
22
22
|
}
|
|
23
23
|
ALL_TIME_UNITS = ("seconds", "minutes", "hours", "days")
|
|
24
|
-
|
|
25
|
-
def
|
|
26
|
-
|
|
24
|
+
DEFAULT_TIME_UNIT="s"
|
|
25
|
+
def get_smallest_time_unit_string(unit):
|
|
26
|
+
for key,values in TIME_CONVERSIONS.items():
|
|
27
|
+
if unit in values["strings"]:
|
|
28
|
+
return values["strings"][0]
|
|
29
|
+
return unit
|
|
30
|
+
def normalize_time_unit(time_unit: str) -> str:
|
|
31
|
+
u = time_unit.strip().lower()
|
|
27
32
|
if u in TIME_CONVERSIONS:
|
|
28
33
|
return u
|
|
29
34
|
for key, values in TIME_CONVERSIONS.items():
|
|
30
35
|
if u in values.get("strings", []):
|
|
31
36
|
return key
|
|
32
|
-
raise ValueError(f"Unknown time unit '{
|
|
37
|
+
raise ValueError(f"Unknown time unit '{time_unit}'. Supported: {list(TIME_CONVERSIONS.keys())}")
|
|
33
38
|
|
|
34
|
-
def get_time_unit_conversions(
|
|
35
|
-
return TIME_CONVERSIONS[normalize_time_unit(
|
|
39
|
+
def get_time_unit_conversions(time_unit: str) -> dict:
|
|
40
|
+
return TIME_CONVERSIONS[normalize_time_unit(time_unit)]
|
|
36
41
|
|
|
37
|
-
def time_factor(
|
|
42
|
+
def time_factor(time_unit_from: str, time_unit_to: str) -> float:
|
|
38
43
|
"""
|
|
39
44
|
multiplicative factor s.t.
|
|
40
45
|
value_in_to = value_in_from * _time_factor(unit_from, unit_to)
|
|
41
46
|
|
|
42
47
|
seconds per 1 unit_from / seconds per 1 unit_to
|
|
43
48
|
"""
|
|
44
|
-
sf = get_time_unit_conversions(
|
|
45
|
-
st = get_time_unit_conversions(
|
|
49
|
+
sf = get_time_unit_conversions(time_unit_from)["conv"]["seconds"] # sec / unit_from
|
|
50
|
+
st = get_time_unit_conversions(time_unit_to)["conv"]["seconds"] # sec / unit_to
|
|
46
51
|
return sf / st
|
|
47
52
|
|
|
48
|
-
def
|
|
49
|
-
return value * time_factor(
|
|
53
|
+
def tconvert(value: float, time_unit_from: str, time_unit_to: str) -> float:
|
|
54
|
+
return value * time_factor(time_unit_from, time_unit_to)
|
|
50
55
|
|
|
51
56
|
def seconds_per(unit: str) -> float:
|
|
52
57
|
"""Return seconds in one <unit> (unit aliases supported)."""
|
|
53
58
|
return get_time_unit_conversions(normalize_time_unit(unit))["conv"]["seconds"]
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
convert_time = tconvert
|
|
56
60
|
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# src/utils/escape_velocity.py
|
|
2
|
+
from ..imports import math, mul, div, add
|
|
3
|
+
from ..constants import (
|
|
4
|
+
DEFAULT_DIST_UNIT,
|
|
5
|
+
DEFAULT_TIME_UNIT,
|
|
6
|
+
DEFAULT_PLANET,
|
|
7
|
+
DEFAULT_START_ALTITUDE,
|
|
8
|
+
DEFAULT_AS_RADIUS,
|
|
9
|
+
get_smallest_unit_string
|
|
10
|
+
)
|
|
11
|
+
from ..constants.planet_constants import get_body,get_R_mu,g_at_radius
|
|
12
|
+
from ..constants.distance_constants import dconvert,get_target_distance,get_normalized_distance
|
|
13
|
+
from ..constants.time_constants import get_time_unit_conversions, normalize_time_unit, seconds_per,tconvert
|
|
14
|
+
from .velocity_utils import normalized_velocity_conversion,get_velocity_conversion
|
|
15
|
+
def get_r_m(planet: str = DEFAULT_PLANET,start_altitude: float = DEFAULT_START_ALTITUDE,input_dist_unit: str = DEFAULT_DIST_UNIT,as_radius:bool = DEFAULT_AS_RADIUS):
|
|
16
|
+
R,mu = get_R_mu(planet=planet)
|
|
17
|
+
r_m = dconvert(start_altitude, input_dist_unit, DEFAULT_DIST_UNIT)
|
|
18
|
+
# Determine radius from center in meters
|
|
19
|
+
if not as_radius:
|
|
20
|
+
r_m = add(R, r_m)
|
|
21
|
+
if r_m <= 0:
|
|
22
|
+
return {"ok": False, "error": "computed radius is non-positive"}
|
|
23
|
+
return r_m
|
|
24
|
+
def get_vesc_mps(
|
|
25
|
+
planet: str = DEFAULT_PLANET,
|
|
26
|
+
start_altitude: float = DEFAULT_START_ALTITUDE,
|
|
27
|
+
input_dist_unit: str = DEFAULT_DIST_UNIT,
|
|
28
|
+
as_radius:bool = DEFAULT_AS_RADIUS
|
|
29
|
+
):
|
|
30
|
+
R,mu = get_R_mu(planet=planet)
|
|
31
|
+
r_m = get_r_m(planet=planet,start_altitude=start_altitude,input_dist_unit=input_dist_unit,as_radius=as_radius)
|
|
32
|
+
vesc_mps = math.sqrt(mul(2.0, div(mu, r_m)))
|
|
33
|
+
return vesc_mps
|
|
34
|
+
|
|
35
|
+
def get_normalized_starting_velocity(
|
|
36
|
+
start_altitude: float = None,
|
|
37
|
+
starting_velocity: float = None,
|
|
38
|
+
input_dist_unit: str = DEFAULT_DIST_UNIT, # distance part of starting_velocity & start_distance
|
|
39
|
+
input_time_unit: str = DEFAULT_TIME_UNIT, # time part of starting_velocity
|
|
40
|
+
output_dist_unit: str = DEFAULT_DIST_UNIT,
|
|
41
|
+
output_time_unit: str = DEFAULT_TIME_UNIT,
|
|
42
|
+
planet: str = DEFAULT_PLANET
|
|
43
|
+
):
|
|
44
|
+
start_altitude = start_altitude or 0
|
|
45
|
+
if starting_velocity == None:
|
|
46
|
+
starting_velocity = escape_velocity_at(planet=planet,
|
|
47
|
+
start_altitude=start_altitude,
|
|
48
|
+
input_time_unit=input_time_unit,
|
|
49
|
+
input_dist_unit=input_dist_unit,
|
|
50
|
+
output_time_unit=output_time_unit,
|
|
51
|
+
output_dist_unit=output_dist_unit
|
|
52
|
+
)
|
|
53
|
+
return normalized_velocity_conversion(
|
|
54
|
+
velocity=starting_velocity,
|
|
55
|
+
input_time_unit=input_time_unit,
|
|
56
|
+
input_dist_unit=input_dist_unit
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def escape_velocity_at(
|
|
60
|
+
planet: str = DEFAULT_PLANET,
|
|
61
|
+
start_altitude: float = DEFAULT_START_ALTITUDE,
|
|
62
|
+
*,
|
|
63
|
+
input_time_unit: str = DEFAULT_TIME_UNIT, # how to interpret `distance`
|
|
64
|
+
input_dist_unit: str = DEFAULT_DIST_UNIT, # how to interpret `distance`
|
|
65
|
+
output_dist_unit: str = DEFAULT_DIST_UNIT, # distance unit for the *speed*
|
|
66
|
+
output_time_unit: str = DEFAULT_TIME_UNIT, # time unit for the *speed*
|
|
67
|
+
as_radius: bool = DEFAULT_AS_RADIUS # False => `distance` is altitude above surface; True => radius from center
|
|
68
|
+
) -> dict:
|
|
69
|
+
"""
|
|
70
|
+
Compute v_escape at a given location around `planet`.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
planet: body name (must exist in PLANETS)
|
|
74
|
+
start_altitude: if as_radius=False => altitude above surface; if as_radius=True => radius from center
|
|
75
|
+
input_units: units of `distance`
|
|
76
|
+
output_units: distance unit of the returned speed
|
|
77
|
+
output_time: time unit of the returned speed ('s'|'min'|'h' etc.)
|
|
78
|
+
as_radius: interpret `distance` as radius-from-center when True
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
{
|
|
82
|
+
"ok": True,
|
|
83
|
+
"planet": str,
|
|
84
|
+
"radius_from_center": <float in output_units>,
|
|
85
|
+
"v_escape": <float in output_units/output_time>,
|
|
86
|
+
"v_escape_mps": <float in m/s>,
|
|
87
|
+
"units": {"distance": output_units, "time": output_time}
|
|
88
|
+
}
|
|
89
|
+
"""
|
|
90
|
+
if not (isinstance(start_altitude, (int, float)) and math.isfinite(start_altitude) and start_altitude >= 0):
|
|
91
|
+
return {"ok": False, "error": "distance must be a non-negative number"}
|
|
92
|
+
R,mu = get_R_mu(planet=planet)
|
|
93
|
+
# v_esc (m/s)
|
|
94
|
+
|
|
95
|
+
r_m = get_r_m(planet=planet,
|
|
96
|
+
start_altitude=start_altitude,
|
|
97
|
+
input_dist_unit=input_dist_unit,
|
|
98
|
+
as_radius=as_radius
|
|
99
|
+
)
|
|
100
|
+
r_conv = dconvert(r_m, input_dist_unit, output_dist_unit)
|
|
101
|
+
v_escape_mps = get_vesc_mps(
|
|
102
|
+
planet=planet,
|
|
103
|
+
start_altitude=start_altitude,
|
|
104
|
+
input_dist_unit=input_dist_unit,
|
|
105
|
+
as_radius=as_radius
|
|
106
|
+
)
|
|
107
|
+
v_escape = get_velocity_conversion(velocity=v_escape_mps,
|
|
108
|
+
input_time_unit= DEFAULT_TIME_UNIT,
|
|
109
|
+
input_dist_unit= DEFAULT_DIST_UNIT,
|
|
110
|
+
output_dist_unit= output_dist_unit,
|
|
111
|
+
output_time_unit= output_time_unit)
|
|
112
|
+
# Convert speed to <output_units>/<output_time>
|
|
113
|
+
|
|
114
|
+
# Also return the radius in output_units for convenience
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
g_o_mps = g_at_radius(mu, r_m)
|
|
118
|
+
g_o_conv = get_velocity_conversion(velocity=g_o_mps,
|
|
119
|
+
input_time_unit= DEFAULT_TIME_UNIT,
|
|
120
|
+
input_dist_unit= DEFAULT_DIST_UNIT,
|
|
121
|
+
output_dist_unit= output_dist_unit,
|
|
122
|
+
output_time_unit= output_time_unit)
|
|
123
|
+
|
|
124
|
+
smallest_time_unit = get_smallest_unit_string(output_time_unit)
|
|
125
|
+
smallest_distance_unit = get_smallest_unit_string(output_dist_unit)
|
|
126
|
+
return {
|
|
127
|
+
"ok": True,
|
|
128
|
+
"planet": planet,
|
|
129
|
+
|
|
130
|
+
"v_escape": round(v_escape,6),
|
|
131
|
+
"v_escape_mps": round(v_escape_mps,6),
|
|
132
|
+
"units": {"distance": output_dist_unit, "time": output_time_unit},
|
|
133
|
+
"r_m":round(r_m,6),
|
|
134
|
+
"r": round(r_conv,6),
|
|
135
|
+
"g_o_mps":round(g_o_mps,6),
|
|
136
|
+
"g_o":round(g_o_conv,6),
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
"units": {"distance": output_dist_unit, "time": output_time_unit},
|
|
140
|
+
"radius_from_center": f"{round(r_conv,2)} {smallest_distance_unit}",
|
|
141
|
+
"v_escape": f"{round(v_escape,2)} {smallest_distance_unit}/{smallest_time_unit}^2",
|
|
142
|
+
"g_out": f"{round(g_o_conv,2)} {smallest_distance_unit}/{smallest_time_unit}^2",
|
|
143
|
+
"escape_velocity": f"{round(v_escape,2)} {smallest_distance_unit}/{smallest_time_unit}^2"
|
|
144
|
+
|
|
145
|
+
}
|
|
@@ -14,23 +14,23 @@ def get_h_cap(r_m: float, h_m: float, theta: Optional[float] = None) -> float:
|
|
|
14
14
|
theta = get_central_angle(r_m, h_m)
|
|
15
15
|
return mul(r_m, sub(1.0, math.cos(theta)))
|
|
16
16
|
|
|
17
|
-
def spherical_cap_area(observer_altitude: float,
|
|
17
|
+
def spherical_cap_area(observer_altitude: float, dist_unit: str = 'meters'):
|
|
18
18
|
"""
|
|
19
19
|
Visible spherical cap area from altitude (same units as input returned in unit^2).
|
|
20
20
|
"""
|
|
21
21
|
r_m = earth_radius('meters')
|
|
22
|
-
h_m = convert(observer_altitude,
|
|
22
|
+
h_m = convert(observer_altitude, dist_unit, 'meters')
|
|
23
23
|
|
|
24
24
|
theta = get_central_angle(r_m, h_m)
|
|
25
25
|
h_cap_m = get_h_cap(r_m, h_m, theta)
|
|
26
26
|
area_m2 = mul(2 * pi() * r_m, h_cap_m) # 2π R h
|
|
27
27
|
# return in requested units^2
|
|
28
|
-
area_u2 = mul(area_m2, exp(_factor('meters',
|
|
29
|
-
return area_u2, convert(h_cap_m, 'meters',
|
|
28
|
+
area_u2 = mul(area_m2, exp(_factor('meters', dist_unit), 2))
|
|
29
|
+
return area_u2, convert(h_cap_m, 'meters', dist_unit), theta
|
|
30
30
|
|
|
31
|
-
def percent_visible(observer_altitude: float,
|
|
32
|
-
cap_area_u2, _, _ = spherical_cap_area(observer_altitude,
|
|
33
|
-
full_area_u2 = full_earth_surface_area(
|
|
31
|
+
def percent_visible(observer_altitude: float, dist_unit: str = 'meters') -> float:
|
|
32
|
+
cap_area_u2, _, _ = spherical_cap_area(observer_altitude, dist_unit)
|
|
33
|
+
full_area_u2 = full_earth_surface_area(dist_unit)
|
|
34
34
|
return mul(div(cap_area_u2, full_area_u2), 100.0)
|
|
35
35
|
|
|
36
36
|
# --- Camera/FOV flat-projection helper (approximate) ---
|
|
@@ -70,9 +70,9 @@ def get_triangle_heights(a: float, b: float, c: float, area: float):
|
|
|
70
70
|
hc = mul(2.0, div(area, c))
|
|
71
71
|
return {"ha": ha, "hb": hb, "hc": hc}
|
|
72
72
|
|
|
73
|
-
def compute_fov_triangle(altitude: float, fov_angle_deg: float,
|
|
73
|
+
def compute_fov_triangle(altitude: float, fov_angle_deg: float, dist_unit: str = 'meters'):
|
|
74
74
|
"""Simple isosceles triangle model for a camera at altitude."""
|
|
75
|
-
a =
|
|
75
|
+
a = dconvert(altitude, dist_unit, 'meters')
|
|
76
76
|
fov_angle_rad = math.radians(fov_angle_deg)
|
|
77
77
|
base = 2.0 * a * math.tan(fov_angle_rad / 2.0)
|
|
78
78
|
b = c = a
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#src/utils/velocity_utils.py
|
|
2
|
+
from ..imports import *
|
|
3
|
+
from ..constants import *
|
|
4
|
+
|
|
5
|
+
def distance_per_time_to_mps(v: float, dist_unit: str, time_unit: str) -> float:
|
|
6
|
+
"""
|
|
7
|
+
Convert <v> in (<dist_unit>/<time_unit>) to m/s.
|
|
8
|
+
"""
|
|
9
|
+
# distance: unit -> meters
|
|
10
|
+
norm_dist_unit = normalize_distance_unit(
|
|
11
|
+
dist_unit
|
|
12
|
+
) # <-- was normalize_time_unit
|
|
13
|
+
meters_per_unit = get_distance_unit_conversions(
|
|
14
|
+
norm_dist_unit
|
|
15
|
+
)["conv"]["meters"]
|
|
16
|
+
v_meters_per_timeunit = mul(
|
|
17
|
+
v,
|
|
18
|
+
meters_per_unit
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
# time: timeunit -> seconds
|
|
22
|
+
sec_per_time = seconds_per(
|
|
23
|
+
time_unit
|
|
24
|
+
) # from time_constants.py
|
|
25
|
+
return div(
|
|
26
|
+
v_meters_per_timeunit,
|
|
27
|
+
sec_per_time
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
def mps_to_distance_per_time(v_mps: float, dist_unit: str, time_unit: str) -> float:
|
|
31
|
+
"""
|
|
32
|
+
Convert m/s to <dist_unit>/<time_unit>.
|
|
33
|
+
"""
|
|
34
|
+
norm_dist_unit = normalize_distance_unit(
|
|
35
|
+
dist_unit
|
|
36
|
+
)
|
|
37
|
+
meters_per_unit = get_distance_unit_conversions(
|
|
38
|
+
norm_dist_unit
|
|
39
|
+
)["conv"]["meters"]
|
|
40
|
+
v_unit_per_sec = div(v_mps, meters_per_unit) # [dist_unit / s]
|
|
41
|
+
sec_per_time = seconds_per(
|
|
42
|
+
time_unit
|
|
43
|
+
)
|
|
44
|
+
return mul(
|
|
45
|
+
v_unit_per_sec,
|
|
46
|
+
sec_per_time
|
|
47
|
+
) # [dist_unit / time_unit]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def get_velocity_conversion(
|
|
53
|
+
velocity,
|
|
54
|
+
input_time_unit: str = DEFAULT_TIME_UNIT,
|
|
55
|
+
input_dist_unit: str = DEFAULT_DIST_UNIT,
|
|
56
|
+
output_dist_unit: str = DEFAULT_DIST_UNIT,
|
|
57
|
+
output_time_unit: str = DEFAULT_TIME_UNIT,
|
|
58
|
+
):
|
|
59
|
+
v0_mps = distance_per_time_to_mps(v=velocity, dist_unit=input_dist_unit, time_unit=input_time_unit)
|
|
60
|
+
v0_unit_p_time = mps_to_distance_per_time(v_mps=v0_mps, dist_unit=output_dist_unit, time_unit=output_time_unit)
|
|
61
|
+
return v0_unit_p_time
|
|
62
|
+
|
|
63
|
+
def normalized_velocity_conversion(
|
|
64
|
+
velocity,
|
|
65
|
+
input_time_unit: str = DEFAULT_TIME_UNIT,
|
|
66
|
+
input_dist_unit: str = DEFAULT_DIST_UNIT,
|
|
67
|
+
):
|
|
68
|
+
v0_mps = get_velocity_conversion(
|
|
69
|
+
velocity=velocity,
|
|
70
|
+
input_time_unit=input_time_unit,
|
|
71
|
+
input_dist_unit=input_dist_unit
|
|
72
|
+
)
|
|
73
|
+
return v0_mps
|
|
74
|
+
|
|
@@ -23,4 +23,5 @@ src/abstract_math/solar_math/src/constants/time_constants.py
|
|
|
23
23
|
src/abstract_math/solar_math/src/utils/__init__.py
|
|
24
24
|
src/abstract_math/solar_math/src/utils/escape_velocity.py
|
|
25
25
|
src/abstract_math/solar_math/src/utils/geometry_utils.py
|
|
26
|
-
src/abstract_math/solar_math/src/utils/velocity_utils.py
|
|
26
|
+
src/abstract_math/solar_math/src/utils/velocity_utils.py
|
|
27
|
+
tests/test.py
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
# src/utils/escape_velocity.py
|
|
2
|
-
from ..imports import math, mul, div, add
|
|
3
|
-
from ..constants import (
|
|
4
|
-
DEFAULT_UNITS,
|
|
5
|
-
DEFAULT_TIME,
|
|
6
|
-
DEFAULT_PLANET,
|
|
7
|
-
DEFAULT_START_ALTITUDE,
|
|
8
|
-
DEFAULT_AS_RADIUS
|
|
9
|
-
)
|
|
10
|
-
from ..constants.planet_constants import get_body,get_R_mu
|
|
11
|
-
from ..constants.distance_constants import dconvert,get_target_distance,get_normalized_distance
|
|
12
|
-
from ..constants.time_constants import get_time_unit_conversions, normalize_time_unit, seconds_per
|
|
13
|
-
from .velocity_utils import normalized_velocity_conversioin
|
|
14
|
-
def get_r_m(planet: str = DEFAULT_PLANET,start_altitude: float = DEFAULT_START_ALTITUDE,input_units: str = DEFAULT_UNITS,as_radius:bool = DEFAULT_AS_RADIUS):
|
|
15
|
-
R,mu = get_R_mu(planet=planet)
|
|
16
|
-
r_m = dconvert(start_altitude, input_units, DEFAULT_UNITS)
|
|
17
|
-
# Determine radius from center in meters
|
|
18
|
-
if not as_radius:
|
|
19
|
-
r_m = add(R, r_m)
|
|
20
|
-
if r_m <= 0:
|
|
21
|
-
return {"ok": False, "error": "computed radius is non-positive"}
|
|
22
|
-
return r_m
|
|
23
|
-
def get_vesc_mps(
|
|
24
|
-
planet: str = DEFAULT_PLANET,
|
|
25
|
-
start_altitude: float = DEFAULT_START_ALTITUDE,
|
|
26
|
-
input_units: str = DEFAULT_UNITS,
|
|
27
|
-
as_radius:bool = DEFAULT_AS_RADIUS
|
|
28
|
-
):
|
|
29
|
-
R,mu = get_R_mu(planet=planet)
|
|
30
|
-
r_m = get_r_m(planet=planet,start_altitude=start_altitude,input_units=input_units,as_radius=as_radius)
|
|
31
|
-
vesc_mps = math.sqrt(mul(2.0, div(mu, r_m)))
|
|
32
|
-
return vesc_mps
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def get_normalized_starting_velocity(
|
|
37
|
-
start_altitude: float = None,
|
|
38
|
-
starting_velocity: float = None,
|
|
39
|
-
input_units: str = DEFAULT_UNITS, # distance part of starting_velocity & start_distance
|
|
40
|
-
input_time: str = DEFAULT_TIME, # time part of starting_velocity
|
|
41
|
-
output_units: str = DEFAULT_UNITS,
|
|
42
|
-
output_time: str = DEFAULT_TIME,
|
|
43
|
-
planet: str = DEFAULT_PLANET
|
|
44
|
-
):
|
|
45
|
-
start_altitude = start_altitude or 0
|
|
46
|
-
if starting_velocity == None:
|
|
47
|
-
starting_velocity = escape_velocity_at(planet=planet,
|
|
48
|
-
start_altitude=start_altitude,
|
|
49
|
-
input_time=input_time,
|
|
50
|
-
input_units=input_units,
|
|
51
|
-
output_time=input_time,
|
|
52
|
-
output_units=input_units
|
|
53
|
-
)
|
|
54
|
-
return normalized_velocity_conversioin(
|
|
55
|
-
velocity=starting_velocity,
|
|
56
|
-
input_time=input_time,
|
|
57
|
-
input_units=input_units
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
def escape_velocity_at(
|
|
61
|
-
planet: str = DEFAULT_PLANET,
|
|
62
|
-
start_altitude: float = DEFAULT_START_ALTITUDE,
|
|
63
|
-
*,
|
|
64
|
-
input_time: str = DEFAULT_TIME, # how to interpret `distance`
|
|
65
|
-
input_units: str = DEFAULT_UNITS, # how to interpret `distance`
|
|
66
|
-
output_units: str = DEFAULT_UNITS, # distance unit for the *speed*
|
|
67
|
-
output_time: str = DEFAULT_TIME, # time unit for the *speed*
|
|
68
|
-
as_radius: bool = DEFAULT_AS_RADIUS # False => `distance` is altitude above surface; True => radius from center
|
|
69
|
-
) -> dict:
|
|
70
|
-
"""
|
|
71
|
-
Compute v_escape at a given location around `planet`.
|
|
72
|
-
|
|
73
|
-
Args:
|
|
74
|
-
planet: body name (must exist in PLANETS)
|
|
75
|
-
start_altitude: if as_radius=False => altitude above surface; if as_radius=True => radius from center
|
|
76
|
-
input_units: units of `distance`
|
|
77
|
-
output_units: distance unit of the returned speed
|
|
78
|
-
output_time: time unit of the returned speed ('s'|'min'|'h' etc.)
|
|
79
|
-
as_radius: interpret `distance` as radius-from-center when True
|
|
80
|
-
|
|
81
|
-
Returns:
|
|
82
|
-
{
|
|
83
|
-
"ok": True,
|
|
84
|
-
"planet": str,
|
|
85
|
-
"radius_from_center": <float in output_units>,
|
|
86
|
-
"v_escape": <float in output_units/output_time>,
|
|
87
|
-
"v_escape_mps": <float in m/s>,
|
|
88
|
-
"units": {"distance": output_units, "time": output_time}
|
|
89
|
-
}
|
|
90
|
-
"""
|
|
91
|
-
if not (isinstance(start_altitude, (int, float)) and math.isfinite(start_altitude) and start_altitude >= 0):
|
|
92
|
-
return {"ok": False, "error": "distance must be a non-negative number"}
|
|
93
|
-
R,mu = get_R_mu(planet=planet)
|
|
94
|
-
# v_esc (m/s)
|
|
95
|
-
r_m = get_r_m(planet=planet,start_altitude=start_altitude,input_units=input_units,as_radius=as_radius)
|
|
96
|
-
vesc_mps = get_vesc_mps(planet=planet,start_altitude=start_altitude,input_units=input_units,as_radius=as_radius)
|
|
97
|
-
# Convert speed to <output_units>/<output_time>
|
|
98
|
-
vesc_units_per_time = dconvert(vesc_mps, DEFAULT_UNITS, output_units)
|
|
99
|
-
time_per = seconds_per(output_time) # seconds per 1 output_time
|
|
100
|
-
vesc_out = mul(vesc_units_per_time, time_per) # <output_units>/<output_time>
|
|
101
|
-
# Also return the radius in output_units for convenience
|
|
102
|
-
r_out = dconvert(r_m, DEFAULT_UNITS, output_units)
|
|
103
|
-
|
|
104
|
-
return {
|
|
105
|
-
"ok": True,
|
|
106
|
-
"planet": planet,
|
|
107
|
-
"radius_from_center": r_out,
|
|
108
|
-
"v_escape": vesc_out,
|
|
109
|
-
"v_escape_mps": vesc_mps,
|
|
110
|
-
"units": {"distance": output_units, "time": output_time}
|
|
111
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
#src/utils/velocity_utils.py
|
|
2
|
-
from ..imports import *
|
|
3
|
-
from ..constants import *
|
|
4
|
-
|
|
5
|
-
def distance_per_time_to_mps(v: float, dist_units: str, time_units: str) -> float:
|
|
6
|
-
"""
|
|
7
|
-
Convert <v> in (<dist_units>/<time_units>) to m/s.
|
|
8
|
-
"""
|
|
9
|
-
# distance: unit -> meters
|
|
10
|
-
norm_dist_unit = normalize_distance_unit(dist_units) # <-- was normalize_time_unit
|
|
11
|
-
meters_per_unit = get_distance_unit_conversions(norm_dist_unit)["conv"]["meters"]
|
|
12
|
-
v_meters_per_timeunit = mul(v, meters_per_unit)
|
|
13
|
-
|
|
14
|
-
# time: timeunit -> seconds
|
|
15
|
-
sec_per_time = seconds_per(time_units) # from time_constants.py
|
|
16
|
-
return div(v_meters_per_timeunit, sec_per_time)
|
|
17
|
-
|
|
18
|
-
def mps_to_distance_per_time(v_mps: float, dist_units: str, time_units: str) -> float:
|
|
19
|
-
"""
|
|
20
|
-
Convert m/s to <dist_units>/<time_units>.
|
|
21
|
-
"""
|
|
22
|
-
norm_dist_unit = normalize_distance_unit(dist_units)
|
|
23
|
-
meters_per_unit = get_distance_unit_conversions(norm_dist_unit)["conv"]["meters"]
|
|
24
|
-
v_units_per_sec = div(v_mps, meters_per_unit) # [dist_units / s]
|
|
25
|
-
sec_per_time = seconds_per(time_units)
|
|
26
|
-
return mul(v_units_per_sec, sec_per_time) # [dist_units / time_units]
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def get_velocity_conversioin(
|
|
32
|
-
velocity,
|
|
33
|
-
input_time: str = DEFAULT_TIME,
|
|
34
|
-
input_units: str = DEFAULT_UNITS,
|
|
35
|
-
output_units: str = DEFAULT_UNITS,
|
|
36
|
-
output_time: str = DEFAULT_TIME,
|
|
37
|
-
):
|
|
38
|
-
v0_mps = distance_per_time_to_mps(v=velocity, dist_units=input_units, time_units=input_time)
|
|
39
|
-
v0_unit_p_time = mps_to_distance_per_time(v_mps=v0_mps, dist_units=output_units, time_units=output_time)
|
|
40
|
-
return v0_unit_p_time
|
|
41
|
-
|
|
42
|
-
def normalized_velocity_conversioin(
|
|
43
|
-
velocity,
|
|
44
|
-
input_time: str = DEFAULT_TIME,
|
|
45
|
-
input_units: str = DEFAULT_UNITS
|
|
46
|
-
):
|
|
47
|
-
v0_mps = get_velocity_conversioin(
|
|
48
|
-
velocity=velocity,
|
|
49
|
-
input_time=input_time,
|
|
50
|
-
input_units=input_units
|
|
51
|
-
)
|
|
52
|
-
return v0_mps
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/flask_scripts/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/solar_math/src/__init__.py
RENAMED
|
File without changes
|
{abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math/solar_math/src/utils/__init__.py
RENAMED
|
File without changes
|
{abstract_math-0.0.0.27 → abstract_math-0.0.0.47}/src/abstract_math.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|