-
Notifications
You must be signed in to change notification settings - Fork 0
/
scmod.py
215 lines (157 loc) · 5.06 KB
/
scmod.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
'''
----------------------------------------------------------------------------------------------------
Python module for sunlit_surface
----------------------------------------------------------------------------------------------------
'''
import numpy as np
import sys
import datetime
import os
def from_orbital_to_cartesian_coordinates(a, e, i, RAAN, om, t, mu):
'''
Converting from orbital parameters to cartesian coordinates
- Inputs:
a semi-major axis (km)
e eccentricity (-)
i inclination (deg)
RAAN right ascension of the ascending node (deg)
om argument of periapsis (deg)
t time spent since passage at periapsis (s)
mu gravitational parameter of the central body (km3/s2)
- Outputs:
pos position vector of the orbiting object (km)
'''
# converting angles from degrees to radians
i = i * np.pi / 180
RAAN = RAAN * np.pi / 180
om = om * np.pi / 180
# computing mean anomaly
n = np.sqrt(mu / np.power(a, 3.0))
M = n * t
# computing eccentric anomaly
E = [M]
for j in range(100):
E.append(E[j] + (M - E[j] + e * np.sin(E[j])) / (1 - e * np.cos(E[j])))
if(abs(E[j+1] - E[j]) < 1e-8):
E = E[j+1]
break
# computing true anomaly
nu = 2 * np.arctan2(
np.sqrt(1 + e) * np.sin(E / 2),
np.sqrt(1 - e) * np.cos(E / 2)
) % (np.pi * 2)
# computing radius
r = a * (1 -np.power(e, 2.0)) / (1 + e * np.cos(nu))
# computing position vector
pos = [
r *
(np.cos(om + nu) * np.cos(RAAN) -
np.sin(om + nu) * np.sin(RAAN) * np.cos(i)),
r *
(np.cos(om + nu) * np.sin(RAAN) +
np.sin(om + nu) * np.cos(RAAN) * np.cos(i)),
r * (np.sin(om + nu) * np.sin(i))
]
return pos
def geographic_to_cartesian_coord(lat, lon, r):
'''
Converts from geographic to cartesian coordinates
- Inputs:
- Outputs:
'''
lat = lat * np.pi / 180
lon = lon * np.pi / 180
position_vector = [
r * np.cos(lon) * np.cos(lat),
r * np.sin(lon) * np.cos(lat),
r * np.sin(lat)
]
return position_vector
def rotate_frame_around_z(input_vector, angle):
'''
Converts coordinates from a reference frame to another with a given rotation angle along the
z-axis
- Inputs:
- Outputs:
'''
angle = angle * np.pi / 180
output_vector = [
np.cos(angle) * input_vector[0] - np.sin(angle) * input_vector[1],
np.sin(angle) * input_vector[0] + np.cos(angle) * input_vector[1],
input_vector[2]
]
return output_vector
def rotate_frame_around_x(input_vector, angle):
'''
Converts coordinates from a reference frame to another with a given rotation angle along the
x-axis
- Inputs:
- Outputs:
'''
angle = angle * np.pi / 180
output_vector = [
input_vector[0],
np.cos(angle) * input_vector[1] - np.sin(angle) * input_vector[1],
np.sin(angle) * input_vector[2] + np.cos(angle) * input_vector[2],
]
return output_vector
def compute_sunlight(surface_vector, sun_vector, delta_t):
'''
Computes sunlight time of a position on the planet.
Based on position on the planet and position of the planet with respect to the sun and duration
delta_t.
Contains a subfunction "twilight_function" which defines a shadowy zone on the edge of the
sunlit half of the planet.
Inputs:
-
Outputs:
-
'''
def twilight_function(x):
'''
Defines a shadow zone on the edge of the sunlit half of the planet.
Inputs:
- x = float
Outputs:
- y = float
'''
asymptote_value = 1
slope = 1e-1
fact = 1e1
if (x <= 0):
y = 0
elif(x > 0):
y = asymptote_value * (1 - slope / ( fact * x + 1 ))
else:
print(error)
return y
surface_vector = surface_vector / np.linalg.norm(surface_vector)
sun_vector = sun_vector / np.linalg.norm(sun_vector)
prdct = - np.dot(surface_vector, sun_vector)
sunlight_time = delta_t * twilight_function(prdct)
return sunlight_time
def normalize_np_array(input_array):
'''
Normalize array
- Inputs:
- Outputs:
'''
max_value = np.amax(input_array)
if (max_value == 0):
return input_array
return input_array / max_value
def normalize_each_time_frame(input_array):
"""
Normalize each time frame
- Input: 3D numpy array
- Output: 3D numpy array
"""
for i in range(input_array.shape[0]):
max_value = np.amax(input_array[i, :, :])
if max_value != 0:
input_array[i, :, :] = input_array[i, :, :] / max_value
return input_array
def prompt_progress(iterations_done, iterations_total):
progress_percent = iterations_done * 100.0 / iterations_total
sys.stdout.write("Progress: {0:.2f} % \r".format(progress_percent))
sys.stdout.flush()