-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSatellite.py
119 lines (108 loc) · 4.04 KB
/
Satellite.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
from Orbit import mk_Orbit
class Satellite:
def __init__(self, body_dict, parent=None):
"""
A generic object in space with an orbit.
:param body_dict: parameters
keys: name, color, orbit (dict, see Orbit.py)
:param parent: the parent Body object
"""
self.name = body_dict['name']
if parent is None:
self.orbit = None
else:
body_dict['orbit']['mu'] = parent.mu
self.orbit = mk_Orbit(body_dict['orbit'])
self.color = body_dict['color']
# Double-link with parent
self.parent = parent
if (self.parent is not None and
isinstance(self.parent, Body)):
if isinstance(self, Body):
self.parent.bodies[self.name] = self
elif isinstance(self, Craft):
self.parent.crafts[self.name] = self
def __repr__(self):
return '<{}>'.format(self.name)
class Body(Satellite):
"""
A Satellite with its own gravity and satellites.
surface gravity > .01g i.e.
density[g/cm^2] * radius[m] > 3.5e5
If density is not known, assume 1.0
plus Gilly as an exception?
"""
def __init__(self, body_dict, parent=None):
"""
load a Body object
:param body_dict:
keys: name, color, size, mu, orbit (dict, see Orbit.py)
:param parent: a loaded
"""
Satellite.__init__(self, body_dict, parent)
self.bodies = {} # populated when a satellite is initialized
self.satellites = {}
self.size = body_dict['size']
self.mu = body_dict['mu']
if parent is None:
self.soi = self.size * 2.
else:
self.soi = self.orbit.semi() * (self.mu / self.parent.mu) ** (2 / 5)
if self.parent.parent is None: # adjust relevant range of the system
# update parent soi
if self.orbit.is_hyp:
parent.soi = max(parent.soi, 1.5 * self.orbit.peri)
else:
parent.soi = max(parent.soi, 1.5 * self.orbit.apo())
class Craft(Satellite):
"""
A man-made satellite (space craft) that can change orbit
"""
res_types = ['delta-v', ]
def __init__(self, body_dict, parent=None):
Satellite.__init__(self, body_dict, parent)
self.resources = {}
for r in self.res_types:
self.resources[r] = (0, 0)
def adjust_res(self, name, quant_adj, cap_adj=0):
"""
Change a resource quantity
:param name: name of the resource
:param quant_adj: change in quantity
(value, 'full' or 'empty')
:param cap_adj: change in max quantity
:return: The resulting change in quantity
"""
# adjust capacity
if name in self.res_types:
curr, cap = self.resources[name]
cap += cap_adj
else:
self.res_types.append(name)
curr, cap = 0.0, cap_adj
self.resources[name] = (curr, cap)
# adjust current quantity
prev = curr
if quant_adj == 'full':
self.resources[name] = (cap, cap)
elif quant_adj == 'empty':
self.resources[name] = (0.0, cap)
else:
new = min(max(curr + quant_adj, 0.0), cap)
self.resources[name] = (new, cap)
curr = self.resources[name][0]
return curr - prev # true change in the resource
def burn(self, dv_vect, t):
"""
Apply a burn to reach a new orbit.
:param dv_vect: vector representing the burn (2-value list)
:param t: time of burn [days]
"""
# manage resources
dv_vect = list(dv_vect) # make non-mutable
dv_available = self.adjust_res('delta-v', -dv_vect[0])
dv_vect[0] = -dv_available
# change the orbit
state = self.orbit.get_state(t)
state.boost(dv_vect)
self.orbit = state.get_orbit()