Professional Documents
Culture Documents
Appendices Sergi Gallardo
Appendices Sergi Gallardo
Author:
Director – Co-director:
Juan Jose Alins Delgado - Javier Gago Barrio
Degree:
Bachelor ’s degree in Aerospace Vehicles Engineering
Examination sesion:
Spring, 2022
Contents
Appendices 1
B Python scripts 2
B.1 GUI.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
B.2 Constellation.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
B.3 Linkb.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
B.4 Simulation.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
B.5 City_data.txt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
i
Appendix A
To run the simulation on a new computer you need to have Python 3 installed first. If Python
3 is installed, the following Python libraries are required:
• Numpy
• Networkx
• Scipy
• PyAstronomy
• PyQt5
• vtk
With these libraries installed you only need to have the 4 Python files (gui.py, constellation.py,
simulation.py, linkb.py) saved in the same folder together with the city_data.txt document where
the ground stations are saved. And run the file gui.py from the python console.
1
Appendix B
Python scripts
This appendix shows all the necessary scripts to run the simulation.
• gui.py: The user interface code
• Constellation.py: The code in charge of generating the constellation and performing all
calculations related to satellites, ground stations and links.
• Linkb.py: Code in which the link budget equations have been implemented
• Simulation.py: Code that runs the simulation at each time instant
• City_data.txt: Ground station latitude and longitude
B.1 GUI.py
1
2 # imports
3
4 # normal python l i b s
5 import s y s
6 import math
7
8 import m u l t i p r o c e s s i n g a s mp
9 import t h r e a d i n g a s td
10
11 # engineering
12
13 # qt5 s t u f f
14 from PyQt5 . QtWidgets import QApplication , QLabel , QWidget , QPushButton
15 from PyQt5 . QtWidgets import QLineEdit , QGridLayout , QStyle , QCheckBox
16 from PyQt5 . QtWidgets import QComboBox , Q F i l e D i a l o g
17
18 from s i m u l a t i o n import S i m u l a t i o n
19
20
21 ##################################################################
22 # globals
23
24 # t h e mean r a d i u s o f t h e e a r t h i n m e t e r s a c c o r d i n g t o w i k i p e d i a
25 EARTH_RADIUS = 6371000
2
APPENDIX B. PYTHON SCRIPTS
26
27 # i f t r u e , w i l l e n a b l e c a l c u l a t i n g network l i n k −s t a t e
28 MAKE_LINKS = True
29
30 # i f you add a new network d e s i g n ( l i n k i n g method )
31 # t h i s l i s t w i l l need t o be updated f o r i t t o appear
32 # i n t h e GUI
33 NETWORK_DESIGNS = [ "SPARSE" , "+GRID" , "IDEAL" ]
34
35 # button s t y l e s :
36
37 # red , b l a c k t e x t
38 STYLE_1 = ’ QPushButton { background−c o l o r : rgba ( 2 5 5 , 5 0 , 5 0 , 1 0 ) ; c o l o r :
rgba ( 0 , 0 , 0 , 2 5 5 ) ; } ’
39
40 # green , b l a c k t e x t
41 STYLE_2 = ’ QPushButton { background−c o l o r : rgba ( 5 0 , 2 5 5 , 5 0 , 1 0 ) ; c o l o r :
rgba ( 0 , 0 , 0 , 2 5 5 ) ; } ’
42
43 # gray , b l a c k t e x t
44 STYLE_3 = ’ QPushButton { background−c o l o r : rgba ( 0 , 0 , 0 , 5 0 ) ; c o l o r : rgba
(0 ,0 ,0 ,5) ;} ’
45
46 # gray , b l a c k t e x t
47 STYLE_4 = ’ QLabel { background−c o l o r : rgba ( 2 5 5 , 2 5 5 , 0 , 1 5 0 ) ; c o l o r : rgba
(0 ,0 ,0 ,255) ;} ’
48
49 #################################################################
50
51
52 c l a s s ApplicationWindow ( QWidget ) :
53 d e f __init__ ( s e l f ) :
54 s u p e r ( ) . __init__ ( )
55 s e l f . _main = QWidget ( )
56
57 s e l f . c t x = mp. g e t _ c o n t e x t ( ’ spawn ’ )
58
59 s e l f . topGrid = QGridLayout ( s e l f )
60
61 # create input
62 s e l f . i n p u t = QGridLayout ( s e l f )
63 s e l f . makeInput ( )
64 s e l f . topGrid . addLayout ( s e l f . input , 0 , 0 )
65
66 # c r e a t e c o n t r o l s box
67 s e l f . c o n t r o l s = QGridLayout ( s e l f )
68 s e l f . makeControls ( )
69 s e l f . topGrid . addLayout ( s e l f . c o n t r o l s , 1 , 0 )
70
71 s e l f . makeConstellation ()
72
73 def closeEvent ( s e l f , event ) :
74 print ( " c a l l e d c l o s e func " )
75 try :
76 s e l f . vtkProcess . terminate ()
77 except AttributeError :
134 s e l f . i n p u t . addWidget ( s e l f . n f E d i t , 8 , 1)
135
136 self . r s L a b e l = QLabel ( " R e c e i v e r s e n s i t i v i t y (dBm) : " )
137 self . r s E d i t = QLineEdit ( " −104.0 " )
138 self . rsEdit . setToolTip ( ’ f l o a t ’ )
139 self . i n p u t . addWidget ( s e l f . r s L a b e l , 9 , 0 )
140 self . i n p u t . addWidget ( s e l f . r s E d i t , 9 , 1 )
141
142 self . s n r L a b e l = QLabel ( "Minumum SNR (dB) : " )
143 self . s n r E d i t = QLineEdit ( " 0 . 0 " )
144 self . snrEdit . setToolTip ( ’ f l o a t ’ )
145 self . i n p u t . addWidget ( s e l f . s n r L a b e l , 1 0 , 0 )
146 self . i n p u t . addWidget ( s e l f . s n r E d i t , 1 0 , 1 )
147
148
149
150
151
152 d e f makeControls ( s e l f ) :
153 s e l f . controls . setSpacing (5) # s p a c e between b u t t o n s
154
155 # make spawn s i m u l a t i o n button
156 s e l f . g e n e r a t e B u t t o n = QPushButton ( " g e n e r a t e " )
157 s e l f . g e n e r a t e B u t t o n . s e t T o o l T i p ( " spawn a new s i m u l a t i o n p r o c e s s " )
158 s e l f . g e n e r a t e B u t t o n . s e t S t y l e S h e e t (STYLE_2)
159 s e l f . c o n t r o l s . addWidget ( s e l f . g e n e r a t e B u t t o n , 0 , 0 )
160 s e l f . g e n e r a t e B u t t o n . c l i c k e d . c o n n e c t ( s e l f . makeVTKModel )
161
162 # make k i l l s i m u l a t i o n p r o c e s s button
163 s e l f . k i l l B u t t o n = QPushButton ( " k i l l " )
164 s e l f . k i l l B u t t o n . setToolTip ( " k i l l the l a s t created simulation p r o c e s s " )
165 s e l f . k i l l B u t t o n . s e t S t y l e S h e e t (STYLE_1)
166 s e l f . c o n t r o l s . addWidget ( s e l f . k i l l B u t t o n , 0 , 1 )
167 s e l f . k i l l B u t t o n . c l i c k e d . c o n n e c t ( s e l f . killVTKModel )
168
188 s e l f . t i m e s t e p E d i t = QLineEdit ( s t r ( i n t ( 1 0 ) ) ) # 30 s e c o n d d e f a u l t
timestep
189 s e l f . timestepEdit . setToolTip ( " i n t : simulation process timestep " )
190 s e l f . t i m e s t e p B u t t o n = QPushButton ( " s e t " )
191 s e l f . t i m e s t e p B u t t o n . s e t T o o l T i p ( " must p r e s s t o update s i m u l a t i o n " )
192 s e l f . timestepButton . c l i c k e d . connect ( s e l f . setTimestep )
193 s e l f . c o n t r o l s . addWidget ( s e l f . t i m e s t e p L a b e l , 1 , 0 )
194 s e l f . c o n t r o l s . addWidget ( s e l f . t i m e s t e p E d i t , 1 , 1 )
195 s e l f . c o n t r o l s . addWidget ( s e l f . timestepButton , 1 , 2 )
196
197 # make l a b e l t o show c u r r e n t time
198 s e l f . t i m e L a b e l = QLabel ( " Time : 0 : 0 0 : 0 0 " )
199 s e l f . t i m e L a b e l . s e t T o o l T i p ( " c u r r e n t time o f s i m u l a t i o n , updated l i v e " )
200 s e l f . t i m e L a b e l . s e t S t y l e S h e e t (STYLE_4)
201 s e l f . c o n t r o l s . addWidget ( s e l f . timeLabel , 2 , 0 )
202
203 # make checkbox f o r t o g g l e image c a p t u r e
204 s e l f . s a v e I m a g e s L a b e l = QLabel ( " Save Images : " )
205 s e l f . saveImagesCheckbox = QCheckBox ( )
206 s e l f . saveImagesCheckbox . s e t T o o l T i p ( ’ check t h i s box t o b e g i n s a v i n g
images \ npath : . / p i c s ’ )
207 s e l f . saveImagesCheckbox . stateChanged . c o n n e c t ( s e l f . t o g g l e S a v e I m a g e s )
208 s e l f . c o n t r o l s . addWidget ( s e l f . sa v e I m ag e s L a be l , 3 , 0 )
209 s e l f . c o n t r o l s . addWidget ( s e l f . saveImagesCheckbox , 3 , 1 )
210
211 # make checkbox f o r t o g g l e image c a p t u r e
212 s e l f . saveGMLSLabel = QLabel ( " Save GMLs: " )
213 s e l f . saveGMLSCheckbox = QCheckBox ( )
214 s e l f . saveGMLSCheckbox . s e t T o o l T i p ( ’ check t h i s box t o b e g i n s a v i n g GML
f i l e s \ npath : . / gmls ’ )
215 s e l f . saveGMLSCheckbox . stateChanged . c o n n e c t ( s e l f . toggleSaveGMLS )
216 s e l f . c o n t r o l s . addWidget ( s e l f . saveGMLSLabel , 4 , 0 )
217 s e l f . c o n t r o l s . addWidget ( s e l f . saveGMLSCheckbox , 4 , 1 )
218
219 # add a drop down t o s e l e c t network d e s i g n method
220 s e l f . l i n k s L a b e l = QLabel ( " Network Design : " )
221 s e l f . l i n k s S e l e c t = QComboBox ( )
222 s e l f . l i n k s S e l e c t . addItems (NETWORK_DESIGNS)
223 s e l f . l i n k s S e l e c t . a c t i v a t e d [ s t r ] . c o n n e c t ( s e l f . se tL in ki ng Me th od )
224 s e l f . c o n t r o l s . addWidget ( s e l f . l i n k s L a b e l , 5 , 0 )
225 s e l f . c o n t r o l s . addWidget ( s e l f . l i n k s S e l e c t , 5 , 1 )
226
227 # c o n t r o l s f o r r u n n i n g f o r a s e t time
228 s e l f . r u n f o r L a b e l = QLabel ( " Run For ( s e c o n d s ) : " )
229 s e l f . r u n f o r E d i t = QLineEdit ( s t r ( i n t ( 6 0 ) ) )
230 s e l f . runforEdit . setToolTip ( ’ i n t ’ )
231 s e l f . r u n f o r B u t t o n = QPushButton ( " Run ! " )
232 s e l f . r u n f o r B u t t o n . s e t T o o l T i p ( ’ c l i c k t o run t h e s i m u l a t i o n f o r a s e t
time ’ )
233 s e l f . runforButton . c l i c k e d . connect ( s e l f . setRunfor )
234 s e l f . c o n t r o l s . addWidget ( s e l f . r u n f o r L a b e l , 6 , 0 )
235 s e l f . c o n t r o l s . addWidget ( s e l f . r u n f o r E d i t , 6 , 1 )
236 s e l f . c o n t r o l s . addWidget ( s e l f . r u n f o r B u t t o n , 6 , 2 )
237
238 # s e c t i o n f o r s e t t i n g up a c o n n e c t i o n
239 s e l f . node1Label = QLabel ( " Node 1 : " )
296
297 s e l f . v t k P r o c e s s = s e l f . c t x . P r o c e s s ( t a r g e t=S i m u l a t i o n , kwargs=
kwargsToSend )
298 s e l f . vtkProcess . s t a r t ()
299
300 # s t a r t a t h r e a d t o l i s t e n f o r s t u f f from t h e model
301 s e l f . comsThread = td . Thread ( t a r g e t= s e l f . comsThreadHandler )
302 s e l f . comsThread . s t a r t ( )
303
304 def makeConstellation ( s e l f ) :
305
306 # gen a c o n s t e l l a t i o n o b j e c t
307 p = int ( s e l f . planesEdit . text () )
308 n = i n t ( s e l f . nodesEdit . text ( ) )
309 i = f l o a t ( s e l f . incEdit . text () )
310 f =f l o a t ( s e l f . f r e c E d i t . t e x t ( ) )
311 pw= f l o a t ( s e l f . powEdit . t e x t ( ) )
312 b= f l o a t ( s e l f . bEdit . t e x t ( ) )
313 n f= f l o a t ( s e l f . n f E d i t . t e x t ( ) )
314 rs = f l o a t ( s e l f . rsEdit . text () )
315 s n r= f l o a t ( s e l f . s n r E d i t . t e x t ( ) )
316 a = f l o a t ( s e l f . smaEdit . t e x t ( ) ) ∗1000 + EARTH_RADIUS
317 ts = int ( s e l f . timestepEdit . text () )
318 s e l f . con = {
319 ’ planes ’ : p ,
320 ’ nodesPerPlane ’ : n ,
321 ’ inclination ’ : i ,
322 ’ frequency ’ : f ,
323 ’ t r a n s m i s s i o n P o w e r ’ : pw ,
324 ’ bandwidth ’ : b ,
325 ’ n o i s e F i g u r e ’ : nf ,
326 ’ r e c e i v e r S e n s i t i v i t y ’ : rs ,
327 ’ s n r ’ : snr ,
328 ’ semiMajorAxis ’ : a ,
329 ’ timeStep ’ : t s
330 }
331
332 d e f killVTKModel ( s e l f ) :
333 try :
334 s e l f . vtkProcess . terminate ()
335 e x c e p t EOFError :
336 p r i n t ( "ERROR: t r i e d t o k i l l vtk p r o c e s s , but something went wrong " )
337
338 d e f makeVTKModel ( s e l f ) :
339 # make s u r e any e x i s t i n g models a r e k i l l e d
340 try :
341 s e l f . vtkProcess . terminate ()
342 except AttributeError :
343 print ( " . . . " )
344 e x c e p t EOFError :
345 print ( " . . . " )
346
406 s e l f . n o d e 1 S e l e c t . addItems ( r e c v [ 1 ] )
407 s e l f . n o d e 2 S e l e c t . addItems ( r e c v [ 1 ] )
408
409 e x c e p t EOFError :
410 break
411
488 d e f enableImageCapture ( s e l f ) :
489 try :
490 s e l f . myPipeConn . send ( " enableImageCapture " )
491 e x c e p t EOFError :
492 p r i n t ( ’ e n a b l e c a p t u r e d i d not work ’ )
493
B.2 Constellation.py
1 import l i n k b # import l i n k budget f u n c t i o n s
2 # g o t t a have numpy
3 import numpy a s np
4
5 # used t o c a l c u l a t e k e p l e r 2 body o r b i t s
6 from PyAstronomy import p y a s l
7
8 import math
9
10 import networkx a s nx
11
12
13 # XXX: Plathon −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
14
15 LATITUDE_NORTH_THRESHOLD = 6 5 . 0
16 LATITUDE_SOUTH_THRESHOLD = −65.0
17 RAAN = 1 8 0 . 0
18 K= −228.6 # Boltzmman c o n s t a n t
19
20 SPEED_OF_LIGHT_M_PER_S = 2 9 9 7 9 2 4 5 8 . 0
21 PLATHON_DEBUG = 0
22 PRINT_RTT = 1
23 LATITUDE_DEBUG = 0
24 ANTENNA={
25 0:10.093 ,1:10.0881 ,2:10.0756 ,3:10.0554 ,4:10.0275 ,5:9.992 ,6:9.9488 ,
26 7:9.8979 , 8:9.8393 ,9:9.7731 ,10:9.6992 ,11:9.6176 ,12:9.5284 ,13:9.4315 ,
27 14:9.327 ,15:9.2149 ,16:9.0951 ,17:8.9677 ,18:8.8326 ,19:8.69 , 20:8.5397 ,
28 21:8.3819 ,22:8.2164 ,23:8.0434 ,24:7.8628 ,25:7.6746 ,26:7.4789 ,27:7.2755 ,
29 28:7.0647 ,29:6.8462 ,30:6.6202 ,31:6.3866 ,32:6.1455 ,33:5.8968 ,34:5.6404 ,
30 35:5.3765 ,36:5.105 ,37:4.8258 ,38:4.5389 ,39:4.2444 ,40:3.9421 ,41:3.632 ,
31 42:3.3141 ,43:2.9883 ,44:2.6546 ,45:2.3128 ,46:1.9629 ,47:1.6047 ,48:1.2382 ,
32 49:0.8633 ,50:0.4798 ,51:0.0874 ,52: −0.3139 ,53: −0.7243 ,54: −1.1442 ,
33 55: −1.5738 ,56: −2.0134 ,57: −2.4633 ,58: −2.9239 ,59: −3.3957 ,60: −3.8792 ,
34 61: −4.375 ,62: −4.8836 ,63: −5.4059 ,64: −5.9426 ,65: −6.4948 ,66: −7.0636 ,
35 67: −7.6503 ,68: −8.2564 ,69: −8.8836 ,70: −9.5339 ,71: −10.2098 ,72: −10.9142 ,
36 73: −11.6503 ,74: −12.4223 ,75: −13.235 ,76: −14.0944 ,77: −15.0078 ,78: −15.9842 ,
37 79: −17.035 ,80: −18.1741 ,81: −19.4193 ,82: −20.7917 ,83: −22.3154 ,84: −24.0094 ,
38 85: −25.8627 ,86: −27.7523 ,87: −29.27 ,88: −29.7186 ,89: −28.8856 ,90: −27.3843
39 }
40
41 ANTENNA_GS= {
42 0:12.3862 ,1:12.3654 ,2:12.3159 ,3:12.2375 ,4:12.13 ,5:11.9932 ,6:11.827 ,
43 7:11.6311 ,8: 11.405 ,9:11.1485 ,10:10.861 ,11:10.542 ,12:10.1909 ,
44 13:9.8071 ,14:9.3899 ,15:8.9385 ,16:8.452 ,17:7.9296 ,18:7.3704 ,
45 19:6.7736 ,20:6.1387 ,21:5.4651 ,22:4.7532 ,23:4.0039 ,24:3.2196 ,25:2.405 ,
46 26:1.5678 ,27:0.7203 ,28: −0.1187 ,29: −0.9231 ,30: −1.6594 ,31: −2.2894 ,
47 32: −2.7774 ,33: −3.0997 ,34: −3.253 ,35: −3.2551 ,36: −3.1387 ,37: −2.9413 ,
48 38: −2.6977 ,39: −2.4356 ,40: −2.1747 ,41: −1.9284 ,42: −1.7049 ,43: −1.509 ,
49 44: −1.3428 ,45: −1.207 ,46: −1.1013 ,47: −1.0249 ,48: −0.9765 ,49: −0.9547 ,
50 50: −0.958 ,51: −0.9848 ,52: −1.0338 ,53: −1.1034 ,54: −1.1924 ,55: −1.2995 ,
51 56: −1.4234 ,57: −1.563 ,58: −1.7172 ,59: −1.8851 ,60: −2.0658 ,61: −2.2583 ,
52 62: −2.4618 ,63: −2.6757 ,64: −2.8991 ,65: −3.1315 ,66: −3.3723 ,67: −3.6209 ,
53 68: −3.8767 ,69: −4.1395 ,70: −4.4086 ,71: −4.6838 ,72: −4.9647 ,73: −5.251 ,
54 74: −5.5424 ,75: −5.8387 ,76: −6.1397 ,77: −6.4452 ,78: −6.7552 ,79: −7.0694 ,
55 80: −7.3879 ,81: −7.7106 ,82: −8.0375 ,83: −8.3686 ,84: −8.704 ,85: −9.0437 ,
56 86: −9.3879 ,87: −9.7366 ,88: −10.09 ,89: −10.4483 ,90: −10.8117
57 }
58
59 # XXX: End Plathon −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
60
61
62 # t r y t o import numba f u n c s
63 try :
64 import numba
65 USING_NUMBA = F a l s e
66 e x c e p t ModuleNotFoundError :
67 USING_NUMBA = F a l s e
68 p r i n t ( " you p r o b a b l y do not have numba i n s t a l l e d . . . " )
69 p r i n t ( " r e v e r t i n g t o non−numba mode " )
70
71 PRINT_LEVEL = 0 # t h e h i g h e r t h e number , t h e more s t u f f p r i n t e d
72
73 def print_plathon () :
74 p r i n t ( " Plathon p a r a m e t e r s −−−−−−−−−−−−−−−−−−−−−−−" )
75 p r i n t ( " L a t i t u d e t h r e s h o l d s d e g r e e s ( North / South ) : %.2 f /%.2 f " % (
LATITUDE_NORTH_THRESHOLD, LATITUDE_SOUTH_THRESHOLD) )
76
77
78 d e f s d o u t ( l e v e l =0, ∗ a r g s ) :
79 " " " a p r i n t f u n c t i o n ; c h o o s e s t o p r i n t based on PRINT_LEVEL
80
81 Parameters
82 −−−−−−−−−−
83 level : int
84 p r i n t _ l e v e l , h i g h e r = more p r i n t i n g
85 args :
86 the s t u f f to p r i n t
87
88 Returns
89 −−−−−−−
90 None
91 """
92
93 i f l e v e l <= PRINT_LEVEL:
94 toPrint = ’ ’
95 f o r arg in args :
96 t o P r i n t += s t r ( a r g )
97 print ( toPrint )
98 r e t u r n None
99
100
101 # t h e mean r a d i u s o f t h e e a r t h i n m e t e r s a c c o r d i n g t o w i k i p e d i a
102 EARTH_RADIUS = 6371000
103
104 # e a r t h ’ s z a x i s ( eg a v e c t o r i n t h e p o s i t i v e z d i r e c t i o n )
105 EARTH_ROTATION_AXIS = [ 0 , 0 , 1 ]
106
107 # number o f s e c o n d s p e r e a r t h r o t a t i o n ( day )
108 SECONDS_PER_DAY = 86400
109
110 # according to wikipedia
111 STD_GRAVITATIONAL_PARAMATER_EARTH = 3 . 9 8 6 0 0 4 4 1 8 e14
112
113 # how b i g t o i n i t i a l i z e t h e ground p o i n t a r r a y . . .
114 NUM_GROUND_POINTS = 0
115
134
135 # The numpy data type used t o s t o r e ground p o i n t data
136 # ground p o i n t s have n e g a t i v e unique IDs
137 # p o s i t i o n s a r e always c a l c u l a t e d from t h e i n i t i a l p o s i t i o n
138 # t o keep r o u n d i n g e r r o r from compounding
139 GROUNDPOINT_DTYPE = np . dtype ( [
140 ( ’ ID ’ , np . i n t 1 6 ) , # ID number , unique , = a r r a y i n d e x
141 ( ’ i n i t _ x ’ , np . i n t 3 2 ) , # i n i t i a l x p o s i t i o n i n m e t e r s
142 ( ’ i n i t _ y ’ , np . i n t 3 2 ) , # i n i t i a l y p o s i t i o n i n m e t e r s
143 ( ’ i n i t _ z ’ , np . i n t 3 2 ) , # i n i t i a l z p o s i t i o n i n m e t e r s
144 ( ’ x ’ , np . i n t 3 2 ) , # x p o s i t i o n in meters
145 ( ’ y ’ , np . i n t 3 2 ) , # y p o s i t i o n in meters
146 ( ’ z ’ , np . i n t 3 2 ) ] ) # z p o s i t i o n in meters
147
148
163 # const c l a s s
164
165
166 class Constellation () :
167 """
168 A c l a s s used t o c o n t a i n and manage a s a t e l l i t e c o n s t i l l a t i o n
169
170 ...
171
172 Attributes
173 −−−−−−−−−−
174 number_of_planes : i n t
175 t h e number o f p l a n e s i n t h e c o n s t i l l a t i o n
176 nodes_per_plane : i n t
177 t h e number o f s a t e l l i t e s p e r p l a n e
178 total_sats : int
179 t h e t o t a l number o f nodes ( s a t e l l i t e s ) i n c o n s t i l l a t i o n
180 ground_node_counter : i n t
181 always n e g a t i v e , countdown , used t o keep t r a c k o f ground node IDs
182 inclination : float
183 the i n c l i n a t i o n of a l l planes in c o n s t i l l a t i o n
184 semi_major_axis : f l o a t
185 semi major a x i s o f t h e o r b i t s ( r a d i u s , i f o r b i t s c i r c u l a r )
186 period : int
187 the period of the o r b i t s in seconds
188 eccentricity : float
189 the e c c e n t r i c i t y of the o r b i t s ; range = 0.0 − 1.0
190 s a t e l l i t e s _ a r r a y : SATELLITE_DTYPE
191 numpy a r r a y o f s a t e l l i t e _ d t y p e , c o n t a i n s s a t e l l i t e data
192 raan_offsets : List [ float ]
193 l i s t o f f l o a t s , k e e p s t r a c k o f a l l t h e a s c e n d i n g node o f f s e t s i n
degrees
194 plane_solvers : List [ ke_solver ]
195 c o n t a i n s t h e PyAstronomy K e p l e r E l l i p s e s o l v e r f o r each o r b i t a l p l a n e
196 time_offsets : List [ float ]
197 c o n t a i n s t h e time o f f s e t s f o r s a t e l l t i e s withen a p l a n e
198 current_time : i n t
199 k e e p s t r a c k o f t h e c u r r e n t s i m u l a t i o n time
200
201 Methods
202 −−−−−−−
203 i n i t S a t e l l i t e A r r a y ( s a t _ a r r a y=None )
204 f i l l s t h e s a t a r r a y with i n i t i a l v a l u e s f o r time=0
205 getArrayOfNodePositions ()
206 r e t u r n s a a s l i c e o f t h e c o n s t i l l a t i o n array , c o n t a i n i n g o n l y p o s i t i o n
values
207 s e t C o n s t i l l a t i o n T i m e ( time =0.0)
208 u p d a t e s a l l s a t e l l i t e s and ground s t a t i o n s p o s i t i o n s t o r e f l e c t t h e new
time
209 """
210
211 d e f __init__ (
212 self ,
213 p l a n e s =1,
214 nodes_per_plane =4,
215 i n c l i n a t i o n =0,
216 f r e q u e n c y =1,
217 t r a n s m i s s i o n _ p o w e r =1.0 ,
218 bandwidth =1.0 ,
219 n o i s e _ f i g u r e =1.0 ,
220 r e c e i v e r _ s e n s i t i v i t y =1.0 ,
221 s n r =0.0 ,
222 semi_major_axis =6372000 ,
223 e c c =0.0 ,
224 minCommunicationsAltitude =100000 ,
225 m i n S a t E l e v a t i o n =40 ,
226 l i n k i n g M e t h o d= ’SPARSE ’ ,
227 arcOfAscendingNodes =360.0) :
228 """
229 Parameters
230 −−−−−−−−−−
231 planes : int
232 t h e number o f p l a n e s i n t h e c o n s t i l l a t i o n
233 nodes_per_plane : i n t
234 t h e number o f s a t e l l i t e s p e r p l a n e
235 inclination : float
236 the i n c l i n a t i o n of a l l planes in c o n s t i l l a t i o n
237 semi_major_axis : f l o a t
238 semi major a x i s o f t h e o r b i t s ( r a d i u s , i f o r b i t s c i r c u l a r )
239 ecc : f l o a t
240 the e c c e n t r i c i t y of the o r b i t s ; range = 0.0 − 1.0
241 minCommunicationsAltitude : i n t 3 2
242 The minimum a l t i t u d e t h a t i n t e r s a t e l l i t e l i n k s must p a s s
243 above t h e Earth ’ s s u r f a c e .
244 minSatElevation : i n t
245 The minimum a n g l e o f e l e v a t i o n i n d e g r e e s above t h e h o r i z o n a
satellite
246 n e e d s t o have f o r a ground s t a t i o n t o communicate with i t .
247 linkingMethod : s t r i n g
248 The c u r r e n t l i n k i n g method used by t h e c o n s t i l l a t i o n
249 c u r r e n t l y o n l y used f o r g e n e r a t i n g GML f i l e s .
250 arcOfAscendingNodes : f l o a t
251 The a n g l e o f a r c ( i n d e g r e e s ) t h a t t h e a s c e n d i n g nodes o f a l l t h e
252 o r b i t a l p l a n e s i s e v e n l y s p a c e d a l o n g . Ex , s e t i n g t h i s t o 180 r e s u l t s
253 i n a Pi c o n s t e l l a t i o n l i k e I r i d i u m
254
255 """
256 #s e l f . f d = open ( " f i l e . c s v " , "w" )
257 #s e l f . f d . w r i t e ( " \ " L a t i t u d \ " ; \ " Angulo1 \ " ; \ " Angulo2 \ " ; \ " Pt \ " \ n " )
258 p r i n t ( " ArcOfAscendingNodes=%d " % arcOfAscendingNodes )
259 s e l f . number_of_planes = p l a n e s
260 s e l f . nodes_per_plane = nodes_per_plane
261 s e l f . t o t a l _ s a t s = p l a n e s ∗ nodes_per_plane
262 s e l f . ground_node_counter = 0
263 self . inclination = inclination
264 s e l f . communication_frequency = f r e q u e n c y
265 s e l f . t r a n s m i s s i o n _ p o w e r= t r a n s m i s s i o n _ p o w e r
266 s e l f . bandwidth=bandwidth
267 s e l f . n o i s e _ f i g u r e= n o i s e _ f i g u r e
268 s e l f . r e c e i v e r _ s e n s i t i v i t y= r e c e i v e r _ s e n s i t i v i t y
269 s e l f . snr_minimum=s n r
270 s e l f . semi_major_axis = semi_major_axis
271 s e l f . p e r i o d = s e l f . c a l c u l a t e O r b i t P e r i o d ( semi_major_axis= s e l f .
semi_major_axis )
272 s e l f . e c c e n t r i c i t y = ecc
273 s e l f . current_time = 0
274 s e l f . number_of_isl_links = 0
275 s e l f . number_of_gnd_links = 0
276 s e l f . total_links = 0
277 s e l f . l i n k _ a r r a y _ s i z e = LINK_ARRAY_SIZE
278 s e l f . min_communications_altitude = 100000
279 s e l f . m i n _ s a t _ e l e v a t i o n = 40
280 s e l f . linking_method = ’SPARSE ’
281 s e l f .G = None
282 s e l f . arcOfAscendingNodes = arcOfAscendingNodes
283
284
285
286 if s e l f . snr_minimum==0.0:
287 s e l f . s n r _ t h r e s h o l d =( s e l f . r e c e i v e r _ s e n s i t i v i t y −30)−K−10∗np . l o g 1 0 ( s e l f .
bandwidth ∗ 1 0 ∗ ∗ 3 ) −10∗np . l o g 1 0 ( 2 9 0 )− s e l f . n o i s e _ f i g u r e
288
289 else :
290 s e l f . s n r _ t h r e s h o l d= s e l f . snr_minimum
291
292
293 # t h i s i s not w r i t t e n t o z e r o , b e c a u s e i t has i t ’ s own i n i t
294 # f u n c t i o n a a few l i n e s down : i n i t S a t e l l i t e A r r a y ( )
295 s e l f . s a t e l l i t e s _ a r r a y = np . empty ( s e l f . t o t a l _ s a t s , dtype=SATELLITE_DTYPE
)
296
297 # d e c l a r e an empty ground
298 s e l f . g r o u n d p o i n t s _ a r r a y = np . z e r o s (NUM_GROUND_POINTS,
299 dtype=GROUNDPOINT_DTYPE)
300
301 # d e c l a r e an empty l i n k a r r a y
302 s e l f . l i n k _ a r r a y = np . z e r o s ( s e l f . l i n k _ a r r a y _ s i z e , dtype=LINK_DTYPE)
303
306 r a n g e ( 0 , s e l f . number_of_planes ) ]
307
308 # g e n e r a t e a l i s t with a k e p l e r e l l i p s e s o l v e r o b j e c t f o r each p l a n e
309 s e l f . plane_solvers = [ ]
310 f o r raan i n s e l f . r a a n _ o f f s e t s :
311 s e l f . p l a n e _ s o l v e r s . append ( p y a s l . K e p l e r E l l i p s e (
312 p e r= s e l f . p e r i o d , # how l o n g t h e o r b i t t a k e s i n s e c o n d s
313 a= s e l f . semi_major_axis , # i f c i r c u l a r o r b i t , t h i s i s same a s
radius
314 e= s e l f . e c c e n t r i c i t y , # g e n e r a l l y c l o s e to 0 f o r l e o
constillations
315 Omega=raan , # r i g h t a s c e n t i o n o f t h e a s c e n d i n g node
316 w=0.0 , # i n i t i a l time o f f s e t / mean anamoly
317 i= s e l f . i n c l i n a t i o n ) ) # orbit inclination
318
319 # f i g u r e out t h e time o f f s e t s f o r nodes withen a p l a n e
320 s e l f . t i m e _ o f f s e t s = [ ( s e l f . p e r i o d / nodes_per_plane ) ∗ i f o r i i n
321 r a n g e ( 0 , nodes_per_plane ) ]
322
323
324 # i n i t i a l i z e the s a t e l l i t e array
325 s e l f . initSatelliteArray ()
326
327 def i n i t S a t e l l i t e A r r a y ( s e l f ) :
328 " " " i n i t i a l i z e s t h e s a t e l l i t e a r r a y with p o s i t i o n s a t time z e r o
329
330 Parameters
331 −−−−−−−−−−
332 sat_array :
333 the s a t e l l i t e array object , modified in place
334
335 """
336
337 # we o f f s e t each p l a n e by a s m a l l amount , s o they do not ’ c o l l i d e ’
338 # t h i s l i t t l e a l g o r i t h m comes up with a l i s t o f o f f s e t v a l u e s
339 phase_offset = 0
340 p h a s e _ o f f s e t _ i n c r e m e n t = ( ( s e l f . p e r i o d / s e l f . nodes_per_plane ) /
341 s e l f . number_of_planes )
342 temp = [ ]
343 toggle = False
344
350
351 else :
352 phase_offset = 0
353
354 t o g g l e = not t o g g l e
355 temp . append ( p h a s e _ o f f s e t )
356
357 p h a s e _ o f f s e t s = temp
358
359 # l o o p through a l l s a t e l l i t e s
360 f o r p l a n e i n r a n g e ( 0 , s e l f . number_of_planes ) :
361 f o r node i n r a n g e ( 0 , s e l f . nodes_per_plane ) :
362
363 # c a l c u l a t e t h e KE s o l v e r time o f f s e t
364
365 o f f s e t = ( s e l f . t i m e _ o f f s e t s [ node ] + p h a s e _ o f f s e t s [ p l a n e ] )
366 # c a l c u l a t e t h e unique ID o f t h e node ( same a s a r r a y i n d e x )
367 unique_id = ( p l a n e ∗ s e l f . nodes_per_plane ) + node
368
369 # calculate i n i t i a l position
370 i n i t _ p o s = s e l f . p l a n e _ s o l v e r s [ p l a n e ] . xyzPos ( o f f s e t )
371 # XXX: C a l a c u l a t e i n i t i a l v e l o c i t y
372 i n i t _ v e l = s e l f . p l a n e _ s o l v e r s [ p l a n e ] . xyzVel ( o f f s e t )
373
374 # update s a t e l l t i e s a r r a y
375 s e l f . s a t e l l i t e s _ a r r a y [ unique_id ][ ’ ID ’ ] = np . i n t 1 6 ( unique_id )
376 s e l f . s a t e l l i t e s _ a r r a y [ unique_id ][ ’ plane_number ’ ] = np . i n t 1 6 ( p l a n e )
377 s e l f . s a t e l l i t e s _ a r r a y [ unique_id ][ ’ offset_number ’ ] = np . i n t 1 6 ( node )
378 s e l f . s a t e l l i t e s _ a r r a y [ unique_id ][ ’ t i m e _ o f f s e t ’ ] = np . f l o a t 3 2 ( o f f s e t
)
379 s e l f . s a t e l l i t e s _ a r r a y [ unique_id ][ ’ x ’ ] = np . i n t 3 2 ( i n i t _ p o s [ 0 ] )
380 s e l f . s a t e l l i t e s _ a r r a y [ unique_id ][ ’ y ’ ] = np . i n t 3 2 ( i n i t _ p o s [ 1 ] )
381 s e l f . s a t e l l i t e s _ a r r a y [ unique_id ][ ’ z ’ ] = np . i n t 3 2 ( i n i t _ p o s [ 2 ] )
382 s e l f . s a t e l l i t e s _ a r r a y [ unique_id ][ ’ vx ’ ] = np . i n t 3 2 ( i n i t _ v e l [ 0 ] )
383 s e l f . s a t e l l i t e s _ a r r a y [ unique_id ][ ’ vy ’ ] = np . i n t 3 2 ( i n i t _ v e l [ 1 ] )
384 s e l f . s a t e l l i t e s _ a r r a y [ unique_id ][ ’ vz ’ ] = np . i n t 3 2 ( i n i t _ v e l [ 2 ] )
385
386 def getArrayOfNodePositions ( s e l f ) :
387 " " " c o p i e s a sub a r r a y o f o n l y p o s i t i o n data from
388 s a t e l l i t e AND g r o u n d p o i n t a r r a y s
389
390 Returns
391 −−−−−−−
392 p o s i t i o n s : np a r r a y
393 a c o p i e d sub a r r a y o f t h e s a t e l l i t e array , t h a t o n l y c o n t a i n s
p o s i t i o n s data
394 """
395
396 s a t _ p o s i t i o n s = np . copy ( s e l f . s a t e l l i t e s _ a r r a y [ [ ’ x ’ , ’ y ’ , ’ z ’ ] ] )
397 g r o u n d _ p o s i t i o n s = np . copy ( s e l f . g r o u n d p o i n t s _ a r r a y [ [ ’ x ’ , ’ y ’ , ’ z ’ ] ] )
398
413 s a t _ p o s i t i o n s = np . copy ( s e l f . s a t e l l i t e s _ a r r a y [ [ ’ x ’ , ’ y ’ , ’ z ’ ] ] )
414
415 return sat_positions
416
417 def getArrayOfGndPositions ( s e l f ) :
418 " " " c o p i e s a sub a r r a y o f o n l y p o s i t i o n data from
419 groundpoint array
420
421 Returns
422 −−−−−−−
423 g r o u n d _ p o s i t i o n s : np a r r a y
424 a c o p i e d sub a r r a y o f t h e ground p o i n t array , t h a t o n l y c o n t a i n s
positions
425 """
426
427 g r o u n d _ p o s i t i o n s = np . copy ( s e l f . g r o u n d p o i n t s _ a r r a y [ [ ’ x ’ , ’ y ’ , ’ z ’ ] ] )
428
429 return ground_positions
430
431 def getArrayOfLinks ( s e l f ) :
432 " " " c o p i e s a sub a r r a y o f l i n k data
433
434 Returns
435 −−−−−−−
436 l i n k s : np a r r a y
437 contains a l l links
438 """
439 total_links = s e l f . total_links
440 l i n k s = np . copy ( s e l f . l i n k _ a r r a y [ : t o t a l _ l i n k s −1])
441
442 return links
443
444 d e f s e t C o n s t i l l a t i o n T i m e ( s e l f , time =0.0) :
445 " " " u p d a t e s a l l p o s i t i o n and l i n k data t o s p e c i f i e d time
446
447 Parameters
448 −−−−−−−−−−
449 time : f l o a t
450 s i m u l a t i o n time t o s e t t o i n s e c o n d s
451
452 Returns
453 −−−−−−−
454 None
455 """
456
457 # c a s t time t o an i n t
458 s e l f . c u r r e n t _ t i m e = i n t ( time )
459
460 # update a l l t h e s a t e l l i t e p o s i t i o n s
461 f o r sat_id in range ( s e l f . s a t e l l i t e s _ a r r a y . s i z e ) :
462 p l a n e = s e l f . s a t e l l i t e s _ a r r a y [ s a t _ i d ] [ ’ plane_number ’ ]
463 o f f s e t = s e l f . s a t e l l i t e s _ a r r a y [ sat_id ] [ ’ time_offset ’ ]
464 pos = s e l f . p l a n e _ s o l v e r s [ p l a n e ] . xyzPos ( s e l f . c u r r e n t _ t i m e + o f f s e t )
465 v e l = s e l f . p l a n e _ s o l v e r s [ p l a n e ] . xyzVel ( s e l f . c u r r e n t _ t i m e + o f f s e t )
466 s e l f . s a t e l l i t e s _ a r r a y [ s a t _ i d ] [ ’ x ’ ] = np . i n t 3 2 ( pos [ 0 ] )
467 s e l f . s a t e l l i t e s _ a r r a y [ s a t _ i d ] [ ’ y ’ ] = np . i n t 3 2 ( pos [ 1 ] )
480 r o t a t i o n _ m a t r i x = s e l f . g e t R o t a t i o n M a t r i x (EARTH_ROTATION_AXIS,
481 degrees_to_rotate )
482
483 f o r gnd_pt i n r a n g e ( s e l f . g r o u n d p o i n t s _ a r r a y . s i z e ) :
484 i n i t i a l _ p o s = s e l f . g r o u n d p o i n t s _ a r r a y [ gnd_pt ] [
485 [ ’ init_x ’ , ’ init_y ’ , ’ init_z ’ ] ]
486 initial_pos = [ initial_pos [0] , initial_pos [1] , initial_pos [ 2 ] ]
487 new_pos = np . dot ( r o t a t i o n _ m a t r i x , i n i t i a l _ p o s )
488 s e l f . g r o u n d p o i n t s _ a r r a y [ gnd_pt ] [ ’ x ’ ] = new_pos [ 0 ]
489 s e l f . g r o u n d p o i n t s _ a r r a y [ gnd_pt ] [ ’ y ’ ] = new_pos [ 1 ]
490 s e l f . g r o u n d p o i n t s _ a r r a y [ gnd_pt ] [ ’ z ’ ] = new_pos [ 2 ]
491
492 r e t u r n None
493
494 d e f generateNetworkGraph ( s e l f , city_names ) :
495 " " " Makes a NetworkX graph o f t h e network a t t h e c u r r e n t time .
496
497 """
498 s e l f .G = nx . Graph (
499 numPlanes=s t r ( s e l f . number_of_planes ) ,
500 numNodesPerPlane=s t r ( s e l f . nodes_per_plane ) ,
501 p l a n e I n c l i n a t i o n=s t r ( s e l f . i n c l i n a t i o n ) ,
502 semiMajorAxisMeters=s t r ( s e l f . semi_major_axis ) ,
503 minCommunicationsAltitudeMeters=s t r ( s e l f . min_communications_altitude )
,
504 m i n S a t E l e v a t i o n D e g r e e s=s t r ( s e l f . m i n _ s a t _ e l e v a t i o n ) ,
505 s i m u l a t i o n T i m e=s t r ( s e l f . c u r r e n t _ t i m e ) ,
506 c o n n e c t i o n S t r a t e g y= s e l f . linking_method )
507
522
523 # and f i n a l l y t h e l i n k s ( e d g e s i n nx terms )
524 f o r lnk_idx i n r a n g e ( s e l f . t o t a l _ l i n k s ) :
525 p r i n t ( " s e l f . l i n k _ a r r a y [%d ] [ ’ node_1 ’]=% s " % ( lnk_idx , s e l f . l i n k _ a r r a y [
lnk_idx ] [ ’ node_1 ’ ] ) )
526 s e l f .G. add_edge (
527 s t r ( s e l f . l i n k _ a r r a y [ lnk_idx ] [ ’ node_1 ’ ] ) ,
528 s t r ( s e l f . l i n k _ a r r a y [ lnk_idx ] [ ’ node_2 ’ ] ) ,
529 d i s t a n c e=i n t ( s e l f . l i n k _ a r r a y [ lnk_idx ] [ ’ d i s t a n c e ’ ] ) )
530
531 d e f generateNetworkGraph2 ( s e l f , city_names , id_gnd_1 , id_gnd_2 ) :
532 " " " Makes a NetworkX graph o f t h e network a t t h e c u r r e n t time .
533
534 """
535 #XXX: Plathon −−− Routing o n l y with s a t s :
536 # gnd −− s a t −− s a t −− s a t −− gnd
537 s e l f .G = nx . Graph (
538 numPlanes=s t r ( s e l f . number_of_planes ) ,
539 numNodesPerPlane=s t r ( s e l f . nodes_per_plane ) ,
540 p l a n e I n c l i n a t i o n=s t r ( s e l f . i n c l i n a t i o n ) ,
541 semiMajorAxisMeters=s t r ( s e l f . semi_major_axis ) ,
542 minCommunicationsAltitudeMeters=s t r ( s e l f . min_communications_altitude )
,
543 m i n S a t E l e v a t i o n D e g r e e s=s t r ( s e l f . m i n _ s a t _ e l e v a t i o n ) ,
544 s i m u l a t i o n T i m e=s t r ( s e l f . c u r r e n t _ t i m e ) ,
545 c o n n e c t i o n S t r a t e g y= s e l f . linking_method )
546
547 # now add i n s a t s
548 # remember , f o r s a t s , t h e a r r a y i n d e x = s a t ID
549 f o r sat_idx in range ( s e l f . t o t a l _ s a t s ) :
550 s e l f .G. add_node (
551 s t r ( s e l f . s a t e l l i t e s _ a r r a y [ s a t _ i d x ] [ ’ ID ’ ] ) ,
552 planeNumber=s t r ( s e l f . s a t e l l i t e s _ a r r a y [ s a t _ i d x ] [ ’ plane_number ’ ] ) ,
553 o f f s e t N u m b e r=s t r ( s e l f . s a t e l l i t e s _ a r r a y [ s a t _ i d x ] [ ’ offset_number ’ ] ) )
554
572 if s e l f . l i n k _ a r r a y [ lnk_idx ] [ ’ s t a t u s ’ ] == 0 :
573 continue
574 i f l a t 1 _ d e g r e e > LATITUDE_NORTH_THRESHOLD o r l a t 1 _ d e g r e e <
LATITUDE_SOUTH_THRESHOLD:
575 i f LATITUDE_DEBUG > 1 :
576 p r i n t ( " Avoid l i n k due t o s a t 1 : %d : x1 , y1 , z1 = %f ,% f ,% f , l a t :
%f " % ( ID1 , x1 , y1 , z1 , l a t 1 _ d e g r e e ) )
577 lat_skip = 1
578 i f l a t 2 _ d e g r e e > LATITUDE_NORTH_THRESHOLD o r l a t 2 _ d e g r e e <
LATITUDE_SOUTH_THRESHOLD:
579 i f LATITUDE_DEBUG > 1 :
580 p r i n t ( " Avoid l i n k due t o s a t 2 : %d : x2 , y2 , z2 = %f ,% f ,% f , l a t :
%f " % ( ID2 , x2 , y2 , z2 , l a t 2 _ d e g r e e ) )
581 lat_skip = 1
582
583 i f l a t _ s k i p == 1 :
584 i f LATITUDE_DEBUG > 1 :
585 print ( " " )
586 lat_skip = 0
587 continue
588
589
590 s e l f .G. add_edge (
591 s t r ( s e l f . l i n k _ a r r a y [ lnk_idx ] [ ’ node_1 ’ ] ) ,
592 s t r ( s e l f . l i n k _ a r r a y [ lnk_idx ] [ ’ node_2 ’ ] ) ,
593 d i s t a n c e=i n t ( s e l f . l i n k _ a r r a y [ lnk_idx ] [ ’ d i s t a n c e ’ ] ) )
594 else :
595 i f s e l f . l i n k _ a r r a y [ lnk_idx ] [ ’ node_1 ’ ] == id_gnd_1 o r s e l f .
l i n k _ a r r a y [ lnk_idx ] [ ’ node_1 ’ ] == id_gnd_2 o r \
596 s e l f . l i n k _ a r r a y [ lnk_idx ] [ ’ node_2 ’ ] == id_gnd_1 o r s e l f .
l i n k _ a r r a y [ lnk_idx ] [ ’ node_2 ’ ] == id_gnd_2 :
597 s e l f .G. add_edge (
598 s t r ( s e l f . l i n k _ a r r a y [ lnk_idx ] [ ’ node_1 ’ ] ) ,
599 s t r ( s e l f . l i n k _ a r r a y [ lnk_idx ] [ ’ node_2 ’ ] ) ,
600 d i s t a n c e=i n t ( s e l f . l i n k _ a r r a y [ lnk_idx ] [ ’ d i s t a n c e ’ ] ) )
601
602
603 def s a t e l l i t e _ l a t i t u d e ( s e l f , id_sat ) :
604 x = s e l f . s a t e l l i t e s _ a r r a y [ id_sat ] [ ’ x ’ ]
605 y = s e l f . s a t e l l i t e s _ a r r a y [ id_sat ] [ ’ y ’ ]
606 z = s e l f . s a t e l l i t e s _ a r r a y [ id_sat ] [ ’ z ’ ]
607 R = math . s q r t ( math . pow ( x , 2 ) + math . pow ( y , 2 ) + math . pow ( z , 2 ) )
608 l a t _ r a d = math . a s i n ( z /R)
609 l a t _ d e g r e e = l a t _ r a d ∗ 1 8 0 . 0 / math . p i
610 r e t u r n l a t _ d e g r e e , x , y , z ,R
611
612
613 d e f exportGMLFile ( s e l f , f i l e n a m e ) :
614 " " " Exports a GML f i l e o f t h e c u r r e n t graph ( s e l f .G)
615
616 """
617 nx . write_gml ( s e l f .G, f i l e n a m e )
618
619 d e f c a l c u l a t e O r b i t P e r i o d ( s e l f , semi_major_axis =0.0) :
620 " " " c a l c u l a t e s t h e p e r i o d o f a o r b i t f o r Earth
621
622 Parameters
623 −−−−−−−−−−
624 semi_major_axis : f l o a t
625 semi major a x i s o f t h e o r b i t i n m e t e r s
626
627 Returns
628 −−−−−−−
629 Period : i n t
630 t h e p e r i o d o f t h e o r b i t i n s e c o n d s ( rounded t o whole s e c o n d s )
631 """
632
633 tmp = math . pow ( semi_major_axis , 3 ) / STD_GRAVITATIONAL_PARAMATER_EARTH
634 r e t u r n i n t ( 2 . 0 ∗ math . p i ∗ math . s q r t ( tmp ) )
635
636 d e f addGroundPoint ( s e l f , l a t i t u d e , l o n g i t u d e , a l t i t u d e =100.0) :
637 " " " adds a ground p o i n t a t g i v e n c o o r d i n a t e s , assumes e a r t h i s p e r f e c t
sphere
638
639 Parameters
640 −−−−−−−−−−
641 latitude : float
642 l a t i t u d e o f ground p o i n t ( i n d e g r e e s )
643 longitude : float
644 l o n g i t u d e o f ground p o i n t ( i n d e g r e e s )
645 altitude : float
646 a l t i t u d e o f point in meters (0 = earth s u r f a c e )
647
648 Returns
649 −−−−−−−
650 unique_id : i n t
651 t h e ID v a l u e a s s i g n e d t o ground p o i n t ( w i l l be < 0 )
652 """
653
654 # must c o n v e r t t h e l a t / l o n g / a l t t o c a r t e s i a n c o o r d i n a t e s
655 r a d i u s = EARTH_RADIUS + a l t i t u d e
656 init_pos = [0 , 0 , 0]
657 l a t i t u d e = math . r a d i a n s ( l a t i t u d e )
658 l o n g i t u d e = math . r a d i a n s ( l o n g i t u d e )
659 i n i t _ p o s [ 0 ] = r a d i u s ∗ math . c o s ( l a t i t u d e ) ∗ math . c o s ( l o n g i t u d e )
660 i n i t _ p o s [ 1 ] = r a d i u s ∗ math . c o s ( l a t i t u d e ) ∗ math . s i n ( l o n g i t u d e )
661 i n i t _ p o s [ 2 ] = r a d i u s ∗ math . s i n ( l a t i t u d e )
662
663
664
665 # be s u r e t o decrement t h i s f o r t h e next ground p o i n t
666 s e l f . ground_node_counter = s e l f . ground_node_counter − 1
667 unique_id = s e l f . ground_node_counter
668
669 # i f s i m u l a t i o n time i s not 0 , f i g u r e out c u r r e n t p o s i t i o n
670 i f s e l f . c u r r e n t _ t i m e == 0 o r s e l f . c u r r e n t _ t i m e % SECONDS_PER_DAY == 0 :
671 degrees_to_rotate = 0
672 pos = i n i t _ p o s
673
674 else :
675 d e g r e e s _ t o _ r o t a t e = 3 6 0 . 0 / (SECONDS_PER_DAY /
676 ( s e l f . c u r r e n t _ t i m e % SECONDS_PER_DAY) )
677
678 r o t a t i o n _ m a t r i x = s e l f . g e t R o t a t i o n M a t r i x (EARTH_ROTATION_AXIS,
679 degrees_to_rotate )
680
681 pos = np . dot ( r o t a t i o n _ m a t r i x , i n i t _ p o s )
682
683
684 # add t h e new ground p o i n t t o a r r a y
685 # yes , append means a f u l l a r r a y copy e v e r y time ,
686 # but t h i s s h o u l d be a v e r y s m a l l array ,
687 # and ground p o i n t s a r e p r o b a b l y o n l y added once
688 # at the begining of the simulation
689 temp = np . z e r o s ( 1 , dtype=GROUNDPOINT_DTYPE)
690 temp [ 0 ] [ ’ ID ’ ] = np . i n t 1 6 ( unique_id )
691 temp [ 0 ] [ ’ i n i t _ x ’ ] = np . i n t 3 2 ( i n i t _ p o s [ 0 ] )
692 temp [ 0 ] [ ’ i n i t _ y ’ ] = np . i n t 3 2 ( i n i t _ p o s [ 1 ] )
693 temp [ 0 ] [ ’ i n i t _ z ’ ] = np . i n t 3 2 ( i n i t _ p o s [ 2 ] )
694 temp [ 0 ] [ ’ x ’ ] = np . i n t 3 2 ( pos [ 0 ] )
695 temp [ 0 ] [ ’ y ’ ] = np . i n t 3 2 ( pos [ 1 ] )
696 temp [ 0 ] [ ’ z ’ ] = np . i n t 3 2 ( pos [ 2 ] )
697
698 s e l f . g r o u n d p o i n t s _ a r r a y = np . append ( s e l f . g r o u n d p o i n t s _ a r r a y , temp )
699
700 r e t u r n unique_id
701
702 def getRotationMatrix ( s e l f , axis , degrees ) :
703 """
704 Return t h e r o t a t i o n matrix a s s o c i a t e d with c o u n t e r c l o c k w i s e r o t a t i o n
about
705 t h e g i v e n a x i s by t h e t a r a d i a n s .
706
707 Parameters
708 −−−−−−−−−−
709 axis : l i s t [ x , y , z ]
710 a vector d e f i n i n g the r o t a i o n a x i s
711 degrees : f l o a t
712 The number o f d e g r e e s t o r o t a t e
713
714 """
715
716 t h e t a = math . r a d i a n s ( d e g r e e s )
717 a x i s = np . a s a r r a y ( a x i s )
718 a x i s = a x i s / math . s q r t ( np . dot ( a x i s , a x i s ) )
719 a = math . c o s ( t h e t a / 2 . 0 )
720 b , c , d = −a x i s ∗ math . s i n ( t h e t a / 2 . 0 )
721 aa , bb , cc , dd = a ∗ a , b ∗ b , c ∗ c , d ∗ d
722 bc , ad , ac , ab , bd , cd = b ∗ c , a ∗ d , a ∗ c , a ∗ b , b ∗ d , c ∗ d
723 r e t u r n np . a r r a y ( [
724 [ aa + bb − c c − dd , 2 ∗ ( bc + ad ) , 2 ∗ ( bd − ac ) ] ,
725 [ 2 ∗ ( bc − ad ) , aa + c c − bb − dd , 2 ∗ ( cd + ab ) ] ,
726 [ 2 ∗ ( bd + ac ) , 2 ∗ ( cd − ab ) , aa + dd − bb − c c ] ] )
727
728 d e f c a l c u l a t e M a x I S L D i s t a n c e ( s e l f , min_communication_altitude ) :
729 """
730 u e s some t r i g t o c a l c u l a t e t h e max coms r a n g e between s a t e l l i t e s
731 based on some minium communications a l t i t u d e
732
733 Parameters
734 −−−−−−−−−−
735 min_communication_altitude : i n t
736 min coms a l t i t u d e i n meters , r e f e r e n c e d from Earth ’ s s u r f a c e
737
738 Returns
739 −−−−−−−
740 max d i s t a n c e : i n t
741 max d i s t a n c e i n m e t e r s
742
743 """
744
745 c = EARTH_RADIUS + min_communication_altitude
746 b = s e l f . semi_major_axis
747 B = math . r a d i a n s ( 9 0 )
748 C = math . a s i n ( ( c ∗ math . s i n (B) ) / b )
749 A = math . r a d i a n s ( 1 8 0 ) − B − C
750 a = ( b ∗ math . s i n (A) ) / math . s i n (B)
751 return i n t ( a ∗ 2)
752
753 d e f calculateMaxSpaceToGndDistance ( s e l f , m i n _ e l e v a t i o n ) :
754 """
755 Return max s a t e l l i t e t o ground coms d i s t a n c e
756
757 Uses some t r i g t o c a l c u l a t e t h e max s p a c e t o ground communications
758 d i s t a n c e g i v e n a f i e l d o f view f o r g r o u n d s t a t i o n s d e f i n e d by an
759 minimum e l e v a t i o n a n g l e above t h e h o r i z o n .
760 Uses a c i r c l e & l i n e segment i n t e r c e p t c a l c u l a t i o n .
761
762 Parameters
763 −−−−−−−−−−
764 min_elevation : i n t
765 min e l e v a t i o n i n d e g r e e s , r a n g e : 0<val <90
766
767 Returns
768 −−−−−−−
769 max d i s t a n c e : i n t
770 max coms d i s t a n c e i n m e t e r s
771
772 """
773
774 # TODO
775 # make a drawing e x p l a i n i n g t h i s
776
777 f u l l _ l i n e = False
778 t a n g e n t _ t o l = 1 e−9
779
780 # p o i n t 1 o f l i n e segment , r e p r e s e n t i n g g r o u n d s t a t i o n
781 p1x , p1y = ( 0 , EARTH_RADIUS)
782
783 # p o i n t 2 o f l i n e segment , r e p r e s e n t i n g r e a l l y f a r p o i n t
784 # a t m i n _ e l e v a t i o n s l o p e from p o i n t 1
785 s l o p e = math . tan ( math . r a d i a n s ( m i n _ e l e v a t i o n ) )
786 run = 384748000 # meters , sma o f moon
787 r i s e = s l o p e ∗ run + EARTH_RADIUS
841 f i g u r e out a l l p o s s i b l e i n t e r − s a t e l l i t e l i n k s
842 f o r each s a t e l l i t e , with a d i s t a n c e l e s s than max_coms_range
843
844 Parameters
845 −−−−−−−−−−
846 max_coms_range : i n t
847 t h e max coms r a n g e i n m e t e r s
848
849 """
850
851 i f USING_NUMBA i s True :
852 temp = s e l f . n u m b a _ c a l c u l a t e I d e a l L i n k s (
853 max_isl_range ,
854 max_stg_range ,
855 s e l f . total_sats ,
856 self . satellites_array ,
857 s e l f . link_array ,
858 s e l f . groundpoints_array ,
859 s e l f . ground_node_counter ,
860 s e l f . link_array_size )
861 i f temp i s not None :
862 s e l f . n u m b e r _ o f _ i s l _ l i n k s = temp [ 0 ]
863 s e l f . number_of_gnd_links = temp [ 1 ]
864 s e l f . t o t a l _ l i n k s = temp [ 2 ]
865
866 else :
867
868 link_idx = 0
869
894
895 s e l f . number_of_isl_links = link_idx
896
897 # add t h e StG l i n k s
898 f o r gnd_idx i n r a n g e (− s e l f . ground_node_counter ) :
899 gnd_pos = [
900 s e l f . g r o u n d p o i n t s _ a r r a y [ gnd_idx ] [ ’ x ’ ] ,
901 s e l f . g r o u n d p o i n t s _ a r r a y [ gnd_idx ] [ ’ y ’ ] ,
902 s e l f . g r o u n d p o i n t s _ a r r a y [ gnd_idx ] [ ’ z ’ ]
903 ]
904 f o r sat_idx in range ( s e l f . t o t a l _ s a t s ) :
905 # calculate distance
906 d = i n t ( math . s q r t (
907 math . pow ( s e l f . s a t e l l i t e s _ a r r a y [ s a t _ i d x ] [ ’ x ’ ] − gnd_pos [ 0 ] , 2 ) +
908 math . pow ( s e l f . s a t e l l i t e s _ a r r a y [ s a t _ i d x ] [ ’ y ’ ] − gnd_pos [ 1 ] , 2 ) +
909 math . pow ( s e l f . s a t e l l i t e s _ a r r a y [ s a t _ i d x ] [ ’ z ’ ] − gnd_pos [ 2 ] , 2 ) ) )
910 # d e i c i d e i f l i n k i s v a l i d o r not
911 i f d < max_stg_range :
912 i f link_idx < s e l f . link_array_size − 1:
913 gnd_id = s e l f . g r o u n d p o i n t s _ a r r a y [ gnd_idx ] [ ’ ID ’ ]
914 s a t _ i d = s e l f . s a t e l l i t e s _ a r r a y [ s a t _ i d x ] [ ’ ID ’ ]
915 s e l f . l i n k _ a r r a y [ l i n k _ i d x ] [ ’ node_1 ’ ] = gnd_id
916 s e l f . l i n k _ a r r a y [ l i n k _ i d x ] [ ’ node_2 ’ ] = s a t _ i d
917 s e l f . l i n k _ a r r a y [ l i n k _ i d x ] [ ’ d i s t a n c e ’ ] = np . i n t 3 2 ( d )
918 link_idx = link_idx + 1
919 else :
920 p r i n t ( ’ERROR! ran out o f room i n t h e l i n k a r r a y ’ )
921 return
922
923 s e l f . number_of_gnd_links = l i n k _ i d x − s e l f . n u m b e r _ o f _ i s l _ l i n k s
924 s e l f . total_links = link_idx
925
926 @staticmethod
927 @numba . j i t ( nopython=True )
928 def numba_calculateIdealLinks (
929 max_isl_range ,
930 max_stg_range ,
931 total_sats ,
932 satellites_array ,
933 link_array ,
934 groundpoints_array ,
935 ground_node_counter ,
936 link_array_size ) :
937 """
938 f i g u r e out a l l p o s s i b l e i n t e r − s a t e l l i t e l i n k s
939 f o r each s a t e l l i t e , with a d i s t a n c e l e s s than max_coms_range
940
941 Parameters
942 −−−−−−−−−−
943 max_coms_range : i n t
944 t h e max coms r a n g e i n m e t e r s
945
946 """
947
948 link_idx = 0
949
1006
1007 r e t u r n [ number_of_isl_links , number_of_gnd_links , t o t a l _ l i n k s ]
1008
1009 def calculatePlusGridLinks (
1010 self ,
1011 max_stg_range ,
1012 max_isl_range =(2∗∗31) −1,
1013 i n i t i a l i z e =F a l s e ,
1014 c r o s s l i n k _ i n t e r p o l a t i o n =1) :
1015 """
1016 c o n n e c t s a t e l l i t e s i n a +g r i d network
1017
1018 Parameters
1019 −−−−−−−−−−
1020 max_stg_range : i n t
1021 t h e max space −ground coms r a n g e
1022 i n i t i a l i z e : bool
1023 Because PlusGrid ISL a r e s t a t i c , they o n l y need t o be g e n e r a t e d once ,
1024 I f i n i t i a l i z e =F a l s e , o n l y update l i n k d i s t a n c e s , do not r e g e r e r a t e
1025 crosslink_interpolation : int
1026 This v a l u e i s used t o make o n l y 1 out o f e v e r y
crosslink_interpolation
1027 s a t e l l i t e s a b l e t o have c r o s s l i n k s . For example , with a i n t e r p o l a t i o n
1028 v a l u e o f ’ 2 ’ , o n l y e v e r y o t h e r s a t e l l i t e w i l l have c r o s s l i n k s , t h e
rest
1029 w i l l have o n l y i n t r a −p l a n e l i n k s
1030
1031 """
1032
1060 s e l f . n u m b e r _ o f _ i s l _ l i n k s = temp [ 0 ]
1061 s e l f . number_of_gnd_links = temp [ 1 ]
1062 s e l f . t o t a l _ l i n k s = temp [ 2 ]
1063
1064 else :
1065
1066 if initialize :
1067
1068 link_idx = 0
1069
1070 # add t h e i n t r a −p l a n e l i n k s
1071 f o r p l a n e i n r a n g e ( s e l f . number_of_planes ) :
1072 f o r node i n r a n g e ( s e l f . nodes_per_plane ) :
1073 node_1 = node + ( p l a n e ∗ s e l f . nodes_per_plane )
1074 i f node == s e l f . nodes_per_plane − 1 :
1075 node_2 = p l a n e ∗ s e l f . nodes_per_plane
1076 else :
1077 node_2 = node + ( p l a n e ∗ s e l f . nodes_per_plane ) + 1
1078
1079 i f link_idx < s e l f . link_array_size − 1:
1080 s e l f . l i n k _ a r r a y [ l i n k _ i d x ] [ ’ node_1 ’ ] = np . i n t 1 6 ( node_1 )
1081 s e l f . l i n k _ a r r a y [ l i n k _ i d x ] [ ’ node_2 ’ ] = np . i n t 1 6 ( node_2 )
1082 link_idx = link_idx + 1
1083 else :
1084 p r i n t ( ’ERROR! ran out o f room i n t h e l i n k a r r a y f o r i n t r a −
plane l i n k s ’ )
1085 return
1086 # add t h e c r o s s −p l a n e l i n k s
1087 p r i n t ( "Go t o i n i t i a l i z e c r o s s −p l a n e l i n k s " )
1088 f o r p l a n e i n r a n g e ( s e l f . number_of_planes ) :
1089 i f p l a n e == s e l f . number_of_planes − 1 :
1090 plane2 = 0
1091 # XXX: Plathon −−− Exclude c r o s s −seam l i n k s
1092
1093 if s e l f . arcOfAscendingNodes == 1 8 0 . 0 :
1094 break
1095 #break
1096 else :
1097 plane2 = plane + 1
1098 f o r node i n r a n g e ( s e l f . nodes_per_plane ) :
1099 node_1 = node + ( p l a n e ∗ s e l f . nodes_per_plane )
1100 node_2 = node + ( p l a n e 2 ∗ s e l f . nodes_per_plane )
1101 i f link_idx < s e l f . link_array_size − 1:
1102 i f ( node_1 + 1 ) % c r o s s l i n k _ i n t e r p o l a t i o n == 0 :
1103 s e l f . l i n k _ a r r a y [ l i n k _ i d x ] [ ’ node_1 ’ ] = np . i n t 1 6 ( node_1 )
1104 s e l f . l i n k _ a r r a y [ l i n k _ i d x ] [ ’ node_2 ’ ] = np . i n t 1 6 ( node_2 )
1105 link_idx = link_idx + 1
1106 else :
1107 p r i n t ( ’ERROR! ran out o f room i n t h e l i n k a r r a y f o r c r o s s −
plane l i n k s ’ )
1108 return
1109
1120 d = i n t ( math . s q r t (
1121 math . pow ( s e l f . s a t e l l i t e s _ a r r a y [ sat_1 ] [ ’ x ’ ] −
1122 s e l f . s a t e l l i t e s _ a r r a y [ sat_2 ] [ ’ x ’ ] , 2 ) +
1123 math . pow ( s e l f . s a t e l l i t e s _ a r r a y [ sat_1 ] [ ’ y ’ ] −
1124 s e l f . s a t e l l i t e s _ a r r a y [ sat_2 ] [ ’ y ’ ] , 2 ) +
1125 math . pow ( s e l f . s a t e l l i t e s _ a r r a y [ sat_1 ] [ ’ z ’ ] −
1126 s e l f . s a t e l l i t e s _ a r r a y [ sat_2 ] [ ’ z ’ ] , 2 ) ) )
1127 i f d > max_isl_range :
1128 s e l f . l i n k _ a r r a y [ i s l _ i d x ] [ ’ node_1 ’ ] = np . i n t 1 6 ( 0 )
1129 s e l f . l i n k _ a r r a y [ i s l _ i d x ] [ ’ node_2 ’ ] = np . i n t 1 6 ( 0 )
1130 s e l f . l i n k _ a r r a y [ i s l _ i d x ] [ ’ d i s t a n c e ’ ] = np . i n t 3 2 ( 0 )
1131 s e l f . l i n k _ a r r a y [ i s l _ i d x ] [ ’SNR ’ ] = np . f l o a t 3 2 ( 0 )
1132 else :
1133
1134 s e l f . l i n k _ a r r a y [ i s l _ i d x ] [ ’ d i s t a n c e ’ ] = np . i n t 3 2 ( d )
1135 s e l f . l i n k _ a r r a y [ i s l _ i d x ] [ ’ s t a t u s ’ ]= np . i n t 1 6 ( 0 )
1136
1209 link_array ,
1210 groundpoints_array ,
1211 ground_node_counter ,
1212 link_array_size ,
1213 number_of_planes ,
1214 nodes_per_plane ,
1215 number_of_isl_links ,
1216 arcOfAscendingNodes = 3 6 0 . 0 ,
1217 i n i t i a l i z e =F a l s e ,
1218 c r o s s l i n k _ i n t e r p o l a t i o n =1,
1219 max_isl_range =(2∗∗31) −1) :
1220 """
1221 f i g u r e out a l l p o s s i b l e i n t e r − s a t e l l i t e l i n k s
1222 f o r each s a t e l l i t e , with a d i s t a n c e l e s s than max_coms_range
1223
1224 Parameters
1225 −−−−−−−−−−
1226 max_stg_range : i n t
1227 t h e max space −ground coms r a n g e
1228 i n i t i a l i z e : bool
1229 Because PlusGrid ISL a r e s t a t i c , they o n l y need t o be g e n e r a t e d once ,
1230 I f i n i t i a l i z e =F a l s e , o n l y update l i n k d i s t a n c e s , do not r e g e r e r a t e
1231 crosslink_interpolation : int
1232 This v a l u e i s used t o make o n l y 1 out o f e v e r y
crosslink_interpolation
1233 s a t e l l i t e s a b l e t o have c r o s s l i n k s . For example , with a i n t e r p o l a t i o n
1234 v a l u e o f ’ 2 ’ , o n l y e v e r y o t h e r s a t e l l i t e w i l l have c r o s s l i n k s , t h e
rest
1235 w i l l have o n l y i n t r a −p l a n e l i n k s
1236
1237 """
1238
1239 if initialize :
1240
1241 link_idx = 0
1242
1243 # add t h e i n t r a −p l a n e l i n k s
1244 f o r p l a n e i n r a n g e ( number_of_planes ) :
1245 f o r node i n r a n g e ( nodes_per_plane ) :
1246 node_1 = node + ( p l a n e ∗ nodes_per_plane )
1247 i f node == nodes_per_plane − 1 :
1248 node_2 = p l a n e ∗ nodes_per_plane
1249 else :
1250 node_2 = node + ( p l a n e ∗ nodes_per_plane ) + 1
1251
1252 i f link_idx < link_array_size − 1:
1253 l i n k _ a r r a y [ l i n k _ i d x ] [ ’ node_1 ’ ] = np . i n t 1 6 ( node_1 )
1254 l i n k _ a r r a y [ l i n k _ i d x ] [ ’ node_2 ’ ] = np . i n t 1 6 ( node_2 )
1255 link_idx = link_idx + 1
1256 else :
1257 p r i n t ( ’ERROR! ran out o f room i n t h e l i n k a r r a y f o r i n t r a −p l a n e
links ’ )
1258 return
1259 # add t h e c r o s s −p l a n e l i n k s
1260 f o r p l a n e i n r a n g e ( number_of_planes ) :
1261 i f p l a n e == number_of_planes − 1 :
1262 plane2 = 0
1263 #XXX: AlMa −−− Exclude seam l i n k s
1264 i f arcOfAscendingNodes == 1 8 0 . 0 :
1265 break
1266 #break
1267 else :
1268 plane2 = plane + 1
1269 f o r node i n r a n g e ( nodes_per_plane ) :
1270 node_1 = node + ( p l a n e ∗ nodes_per_plane )
1271 node_2 = node + ( p l a n e 2 ∗ nodes_per_plane )
1272 i f link_idx < link_array_size − 1:
1273 i f ( node_1 + 1 ) % c r o s s l i n k _ i n t e r p o l a t i o n == 0 :
1274 l i n k _ a r r a y [ l i n k _ i d x ] [ ’ node_1 ’ ] = np . i n t 1 6 ( node_1 )
1275 l i n k _ a r r a y [ l i n k _ i d x ] [ ’ node_2 ’ ] = np . i n t 1 6 ( node_2 )
1276 link_idx = link_idx + 1
1277 else :
1278 p r i n t ( ’ERROR! ran out o f room i n t h e l i n k a r r a y f o r c r o s s −p l a n e
links ’ )
1279 return
1280
1281 number_of_isl_links = link_idx
1282
1283 link_idx = number_of_isl_links
1284
1285 # update ISL l i n k d i s t a n c e s
1286 f o r i s l _ i d x in range ( number_of_isl_links ) :
1287 sat_1 = l i n k _ a r r a y [ i s l _ i d x ] [ ’ node_1 ’ ]
1288 sat_2 = l i n k _ a r r a y [ i s l _ i d x ] [ ’ node_2 ’ ]
1289 d = i n t ( math . s q r t (
1290 math . pow ( s a t e l l i t e s _ a r r a y [ sat_1 ] [ ’ x ’ ] − s a t e l l i t e s _ a r r a y [ sat_2 ] [ ’ x ’
] , 2) +
1291 math . pow ( s a t e l l i t e s _ a r r a y [ sat_1 ] [ ’ y ’ ] − s a t e l l i t e s _ a r r a y [ sat_2 ] [ ’ y ’
] , 2) +
1292 math . pow ( s a t e l l i t e s _ a r r a y [ sat_1 ] [ ’ z ’ ] − s a t e l l i t e s _ a r r a y [ sat_2 ] [ ’ z ’
] , 2) ) )
1293 i f d > max_isl_range :
1294 l i n k _ a r r a y [ i s l _ i d x ] [ ’ node_1 ’ ] = np . i n t 1 6 ( 0 )
1295 l i n k _ a r r a y [ i s l _ i d x ] [ ’ node_2 ’ ] = np . i n t 1 6 ( 0 )
1296 l i n k _ a r r a y [ i s l _ i d x ] [ ’ d i s t a n c e ’ ] = np . i n t 3 2 ( 0 )
1297 else :
1298 l i n k _ a r r a y [ i s l _ i d x ] [ ’ d i s t a n c e ’ ] = np . i n t 3 2 ( d )
1299
1300 # add t h e StG l i n k s
1301 f o r gnd_idx i n r a n g e (−ground_node_counter ) :
1302 gnd_pos = [
1303 g r o u n d p o i n t s _ a r r a y [ gnd_idx ] [ ’ x ’ ] ,
1304 g r o u n d p o i n t s _ a r r a y [ gnd_idx ] [ ’ y ’ ] ,
1305 g r o u n d p o i n t s _ a r r a y [ gnd_idx ] [ ’ z ’ ]
1306 ]
1307
1308 f o r sat_idx in range ( t o t a l _ s a t s ) :
1309 # calculate distance
1310 d = i n t ( math . s q r t (
1311 math . pow ( s a t e l l i t e s _ a r r a y [ s a t _ i d x ] [ ’ x ’ ] − gnd_pos [ 0 ] , 2 ) +
1312 math . pow ( s a t e l l i t e s _ a r r a y [ s a t _ i d x ] [ ’ y ’ ] − gnd_pos [ 1 ] , 2 ) +
1313 math . pow ( s a t e l l i t e s _ a r r a y [ s a t _ i d x ] [ ’ z ’ ] − gnd_pos [ 2 ] , 2 ) ) )
1314
1315 # d e i c i d e i f l i n k i s v a l i d o r not
1316 i f d < max_stg_range :
1317 i f link_idx < link_array_size − 1:
1318 gnd_id = g r o u n d p o i n t s _ a r r a y [ gnd_idx ] [ ’ ID ’ ]
1319 s a t _ i d = s a t e l l i t e s _ a r r a y [ s a t _ i d x ] [ ’ ID ’ ]
1320 l i n k _ a r r a y [ l i n k _ i d x ] [ ’ node_1 ’ ] = gnd_id
1321 l i n k _ a r r a y [ l i n k _ i d x ] [ ’ node_2 ’ ] = s a t _ i d
1322 l i n k _ a r r a y [ l i n k _ i d x ] [ ’ d i s t a n c e ’ ] = np . i n t 3 2 ( d )
1323 link_idx = link_idx + 1
1324 else :
1325 p r i n t ( ’ERROR! ran out o f room i n t h e l i n k a r r a y ’ )
1326 return
1327
1328 number_of_gnd_links = l i n k _ i d x − n u m b e r _ o f _ i s l _ l i n k s
1329 total_links = link_idx
1330 r e t u r n [ number_of_isl_links , number_of_gnd_links , t o t a l _ l i n k s ]
1331
1332 d e f import_links_from_gml_data ( s e l f , l i n k s ) :
1333 " " " Takes a l i n k s array , and f i l l s i n t e r n a l l i n k s _ a r r a y with them .
1334
1335 Paramaters
1336 −−−−−−−−−−
1337 l i n k s : a r r a y [ [ ( i n t : node_1_ID ) , ( i n t : node_2_ID ) ] , . . . ]
1338 An a r r a y where each i n d e x i s a p a i r o f e n d p o i n t IDs d e s c r i b i n g a l i n k
.
1339
1340 """
1341
1342 link_idx = 0
1343
1344 # add t h e i n t e r s a t e l l i t e l i n k s
1345 f o r idx in range ( len ( l i n k s ) ) :
1346 node_1 = l i n k s [ i d x ] [ 0 ]
1347 node_2 = l i n k s [ i d x ] [ 1 ]
1348 # i f both node IDs a r e p o s i t i v e ( both s a t e l l i t e s )
1349 # we add them h e r e
1350 i f ( node_1 >= 0 ) and ( node_2 >= 0 ) :
1351 i f link_idx < s e l f . link_array_size − 1:
1352 s e l f . l i n k _ a r r a y [ l i n k _ i d x ] [ ’ node_1 ’ ] = np . i n t 1 6 ( node_1 )
1353 s e l f . l i n k _ a r r a y [ l i n k _ i d x ] [ ’ node_2 ’ ] = np . i n t 1 6 ( node_2 )
1354 link_idx = link_idx + 1
1355 else :
1356 p r i n t ( ’ERROR! ran out o f room i n t h e l i n k a r r a y f o r i n t r a −p l a n e
links ’ )
1357 r e t u r n None
1358
1359 s e l f . number_of_isl_links = link_idx
1360
1361 # no we go back o v e r t h e l i n k s array , and add
1362 # a l l t h e l i n k s i n v o l v i n g g r o u n d p o i n t s ( n e g a t i v e IDs )
1363 f o r idx in range ( len ( l i n k s ) ) :
1364 node_1 = l i n k s [ i d x ] [ 0 ]
1365 node_2 = l i n k s [ i d x ] [ 1 ]
1366 # i f one o f t h e IDs i s n e g a t i v e , i t i s a ground p o i n t
1367 i f ( node_1 < 0 ) o r ( node_2 < 0 ) :
B.3 Linkb.py
1 #Link budget f u n c t i o n s
2 import math
3 import numpy a s np
4
80 f=f ∗10∗∗9 #l i n k f r e c u e n c y
81 lamda=c / f
82 Lf =20∗np . l o g 1 0 ( 4 ∗ math . p i ∗d/ lamda ) # f r e e s p a c e l o s s e s
83
84 Pr=pr −30 # R e c e i v e r s e n s i t i v i t y i n dB
85
86 #Antennas g a i n s
87 t h e t a=antena . k e y s ( )
88 t h e t a= l i s t ( t h e t a )
89 g a i n=antena . v a l u e s ( )
90 g a i n= l i s t ( g a i n )
91 Gsat1=np . i n t e r p ( thet a_sat1 , t h e t a , g a i n )
92 Gsat2=np . i n t e r p ( thet a_sat2 , t h e t a , g a i n )
93
94 Pt=Pr−Gsat1−Gsat2+Lf # Transmitted power r e q u i r e d
95
96 r e t u r n 1 0 ∗ ∗ ( Pt / 1 0 )
97
98
99
100
101
102 d e f GSL_linkBudget ( d , xsat , ysat , z s a t , xgs , ygs , zgs , antenna_sat , antenna_gs ) :
103 i f d==0:
104 return (0)
105 else :
106 Dgs =1.5 # g s antenna d i a m e t e r i n m
107 e f f =0.8 # Antenna e f f i e n c y
108 c =299792458 # l i g h t s p e e d
109 k= −228.6 # Boltzmann c o n s t a n t dBW/K/Hz
110 B=10∗np . l o g 1 0 ( 5 1 2 ∗ 1 0 ∗ ∗ 3 ) ; #Bandwidth dBHz
111 T0=290
112 r_earth =6371000
113 gs_v=np . a r r a y ( [ xgs , ygs , z g s ] ) ; # g s t o Earth c e n t e r v e c t o r
114 sat_v= np . a r r a y ( [ xsat , ysat , z s a t ] ) ;# s a t t o Eath c e n t e r v e c t o r
115 sat_gs= np . a r r a y ( [ xsat −xgs , ysat −ygs , z s a t −z g s ] ) ; # Link d i r e c t i o n
116
117 v1=gs_v/np . l i n a l g . norm ( gs_v )
118 v2=sat_v /np . l i n a l g . norm ( sat_v )
119 v3=sat_gs /np . l i n a l g . norm ( sat_gs )
120
124
125 #S a t e l l i t e antenna r a d i a t i o n p a t t e r n
126 theta_s=antenna_sat . k e y s ( ) ;
127 theta_s= l i s t ( theta_s ) ;
128 gain_s=antenna_sat . v a l u e s ( ) ;
129 gain_s= l i s t ( gain_s ) ;
130 Gsat=np . i n t e r p ( theta_sat , theta_s , gain_s ) # s a t antenna g a i n with
radiation pattern
131
132
133 # GS antenna r a d i a t i o n p a t t e r n
134 #theta_g=antenna_gs . k e y s ( ) ;
135 #theta_g= l i s t ( theta_g ) ;
136 #gain_g=antenna_gs . v a l u e s ( ) ;
137 #gain_g= l i s t ( gain_g ) ;
138
139
140
141 ######### E l e v a t i o n Angle ##########
142 #H=math . s q r t ( math . pow ( xsat , 2 ) + math . pow ( ysat , 2 ) + math . pow ( z s a t , 2 ) )−
r_earth
143 #s i n E I =(H∗ (H+2∗ r_earth )−d ∗ ∗ 2 ) / ( 2 ∗ d∗ r_earth )
144 #i f s i n E I <=1:
145 # EI=math . d e g r e e s ( math . a s i n ( s i n E I ) )
146 #e l s e :
147 # EI=90
148
149 ###### Atmospheric L o s s e s #######
150 #fGhz=f ∗10∗∗( −9)
151 #gamma_0=( 7 . 1 / ( f ∗∗2+0.36) + 4 . 5 / ( ( fGhz −57) ∗∗2+0.98) ) ∗ fGhz ∗∗2
∗10∗∗( −3)
152 #gamma_w=( 0 . 0 6 7 + 3 / ( ( fGhz −22.3) ∗∗2+7.3) ) ∗12∗ fGhz ∗∗2 ∗10∗∗( −4)
153 #h_w=2.2+ 3/ ( ( fGhz −22.3) ∗∗2 + 3 )
154 #hs =0.3
155 #L_gd = (gamma_0∗6∗ np . e ∗∗(− hs / 6 ) + gamma_w∗h_w) / s i n E I
156
157
158 #Downlink
159 f =437∗10∗∗6; #downlink f r e c u e n c y
160 lamda=c / f #
161 Ggs=10∗np . l o g 1 0 ( e f f ∗ ( np . p i ∗Dgs∗ f / c ) ∗ ∗ 2 ) # GS antenna g a i n with f o r m u l a
162 #Ggs=np . i n t e r p ( theta_gs , theta_g , gain_g ) # GS antenna g a i n with
radiation pattern
163 Pt=10∗np . l o g 1 0 ( 1 ) ; # Downlink t r a n s m i t t e d power
164 Lfd =20∗np . l o g 1 0 ( 4 ∗ np . p i ∗d/ lamda ) ; # Free s p a c e l o s s e
165 Pr=Pt+Ggs+Gsat−Lfd ; # R e c e i v e d power dB
166 NF=3 # R e c e i v e r n o i s e f i g u r e (GS)
167 Tant=290 # Antenna t e m p e r a t u r e
168 Tsyst =10∗np . l o g 1 0 ( Tant+T0 ∗ ( 1 0 ∗ ∗ (NF/ 1 0 ) −1) ) ; # System t e m p e r a t u r e dB
169 Nout=k+Tsyst+B # N o i s e power dBW
170 SNRd=Pr−Nout # Downlink SNR
171
172 #Uplink
173 f =146∗10∗∗6; #u p l i n k f r e c u e n c y
174 lamda=c / f ;
175 Ggs=10∗np . l o g 1 0 ( e f f ∗ ( np . p i ∗Dgs∗ f / c ) ∗ ∗ 2 ) # GS antenna g a i n with f o r m u l a
176 #Ggs=np . i n t e r p ( theta_gs , theta_g , gain_g ) # GS antenna g a i n with
radiation pattern
177 Pt=10∗np . l o g 1 0 ( 7 0 ) # Uplink t r a n s m i t e d power i n dBW
178 Lfu =20∗np . l o g 1 0 ( 4 ∗ np . p i ∗d/ lamda ) # Free s p a c e l o s s e s
179 Pr=Pt+Ggs+Gsat−Lfu # R e c e i v e d power dB
180 NF=2.05 # R e c e i v e r n o i s e f i g u r e ( s a t e l l i t e )
181 Tant=290 # Antenna t e m p e r a t u r e
182 Tsyst =10∗np . l o g 1 0 ( Tant+T0 ∗ ( 1 0 ∗ ∗ (NF/ 1 0 ) −1) ) # System t e m p e r a t u r e
183 Nout=k+Tsyst+B # N o i s e Power dB
184 SNRu=Pru−Nout # Uplink SNR
185
186 r e t u r n SNRd, SNRu
B.4 Simulation.py
1 # used t o make program f a s t e r & r e s p o n s i v e
2 import t h r e a d i n g a s td
3
4 # memory a l i g n e d a r r a y s t h e i r m a n i p u l a t i o n f o r Python
5 import numpy a s np
6
7 # custom c l a s s e s
8 from c o n s t e l l a t i o n import C o n s t e l l a t i o n , RAAN
9
10 # OpenGL API f o r Python
11 import vtk
12
13 # P r i m a r i l y u s i n g t h e write_gml ( ) f u n c t i o n . . .
14 import networkx a s nx
15
16 # u s e t o measure program p e r f o r m a n c e ( sim f r a m e r a t e )
17 import time
18
19
20 # t r y t o import numba f u n c s
21 try :
22 import numba_funcs a s n f
23 USING_NUMBA = F a l s e
24 e x c e p t ModuleNotFoundError :
25 USING_NUMBA = F a l s e
26 p r i n t ( " you p r o b a b l y do not have numba i n s t a l l e d . . . " )
27 p r i n t ( " r e v e r t i n g t o non−numba mode " )
28
29
30 #################### GLOBAL VARS ##############################
31
32 EARTH_RADIUS = 6371000 # r a d i u s o f Earth i n m e t e r s
33
34 PNG_OUTPUT_PATH = " p i c s /p " # where t o s a v e images o f t h e a n i m a t i o n
35 GML_OUTPUT_PATH = ’ gmls / g ’ # where t o s a v e gml f i l e s
36
37 MIN_SAT_ELEVATION = 30 # degrees
38
39 LANDMASS_OUTLINE_COLOR = ( 0 . 0 , 0 . 0 , 0 . 0 ) # bla ck , b e s t c o n t r a s t
40 EARTH_LAND_OPACITY = 1 . 0
41
50 GND_COLOR = ( 0 . 0 , 1 . 0 , 0 . 0 ) # green , c o l o r o f g r o u n d s t a t i o n s
51 GND_OPACITY = 1 . 0
52
53 ISL_LINK_COLOR = ( 0 . 9 , 0 . 5 , 0 . 1 ) # y e l l o w −brown , s a t e l l i t e − s a t e l l i t e l i n k s
54 ISL_LINK_OPACITY = 1 . 0
55 ISL_LINE_WIDTH = 3 # how wide t o draw l i n e i n p i x e l s
56
57 SGL_LINK_COLOR = ( 0 . 5 , 0 . 9 , 0 . 5 ) # g r e e n i s h ? s a t e l l i t e −g r o u n d s t a t i o n l i n k s
58 SGL_LINK_OPACITY = 0 . 7 5
59 SGL_LINE_WIDTH = 2 # how wide t o draw l i n e i n p i x e l s
60
61 PATH_LINK_COLOR = ( 0 . 8 , 0 . 2 , 0 . 8 ) # p u r p l e i s h ? path l i n k s
62 PATH_LINK_OPACITY = 0 . 7
63 PATH_LINE_WIDTH = 13 # how wide t o draw l i n e i n p i x e l s
64
65 EARTH_SPHERE_POINTS = 5000 # h i g h e r = smoother e a r t h model , s l o w e r t o
generate
66
67 SAT_POINT_SIZE = 9 # how b i g s a t e l l i t e s a r e i n ( p r o b a b l y ) s c r e e n p i x e l s
68 GND_POINT_SIZE = 8 # how b i g ground p o i n t s a r e i n ( p r o b a b l y ) s c r e e n p i x e l s
69
70 SECONDS_PER_DAY = 86400 # number o f s e c o n d s p e r e a r t h r o t a t i o n ( day )
71 SPEED_OF_LIGHT_M_PER_S = 2 9 9 7 9 2 4 5 8 . 0
72
73
74 d e f getFileNumber ( var ) :
75 """
76 Makes a n i c e i n t with l e a d i n g z e r o s f o r f i l e naming
77
78 Attributes
79 −−−−−−−−−−
80 var : i n t
81 an i n t t h a t w i l l be used t o l a b e l e x p o r t f i l e s
82
83 Returns
84 −−−−−−−
85 string : string
86 a 7 char int , using l e a d i n g z e r o s
87 """
88
89 mask = [ ’ 0 ’ , ’ 0 ’ , ’ 0 ’ , ’ 0 ’ , ’ 0 ’ , ’ 0 ’ , ’ 0 ’ ]
90 var = l i s t ( s t r ( var ) )
91 t = l e n ( mask ) − l e n ( var )
92 f o r i i n r a n g e ( l e n ( var ) ) :
93 mask [ i+t ] = var [ i ]
94 r e t u r n ’ ’ . j o i n ( mask )
95
96
97 #
##############################################################################
98 # SIMULATION CONTROL
#
99 #
##############################################################################
100
101
102 c l a s s Simulation () :
103
104 d e f __init__ (
105 self ,
106 pipeConn=None ,
107 p l a n e s =1,
108 nodesPerPlane =1,
109 i n c l i n a t i o n =70 ,
110 f r e q u e n c y =1,
111 t r a n s m i s s i o n P o w e r =1.0 ,
112 bandwidth =1.0 ,
113 n o i s e F i g u r e =1.0 ,
114 r e c e i v e r S e n s i t i v i t y =1.0 ,
115 s n r =0.0 ,
116 semiMajorAxis =6472000 ,
117 t i m e S t e p =10 ,
118 makeLinks=True ,
119 animate=True ,
120 c a p t u r e I m a g e s=F a l s e ,
121 c a p t u r e I n t e r p o l a t i o n =1,
122 captureGML=F a l s e ,
123 g r o u n d P t s F i l e= ’ c i t y _ d a t a . t x t ’ ,
124 gmlImportFileName=None ) :
125
126 i f gmlImportFileName i s not None :
127 # t r y t o import t h e g i v e n f i l e a s a networkX graph
128 try :
129 G = nx . read_gml ( gmlImportFileName )
130 e x c e p t FileNotFoundError a s e r r o r :
131 p r i n t ( "ERROR! t r i e d t o import gml f i l e , f i l e not found \n " , e r r o r )
132 r e t u r n None
133
134 # assuming gml import worked , we e x t r a c t t h e s i m u l a t i o n
135 # s t r u c t u r e data l i k e time , num−p l a n e s , i n c l i n a t i o n . . . e t c
136 # c o n s t i l l a t i o n structure information
137 s e l f . num_planes = i n t (G. graph [ ’ numPlanes ’ ] )
138 s e l f . num_nodes_per_plane = i n t (G. graph [ ’ numNodesPerPlane ’ ] )
139 s e l f . p l a n e _ i n c l i n a t i o n = f l o a t (G. graph [ ’ p l a n e I n c l i n a t i o n ’ ] )
140 s e l f . communication_frequency = f l o a t (G. graph [ ’ f r e q u e n c y ’ ] )
141 s e l f . t r a n s m i s s i o n _ p o w e r = f l o a t (G. graph [ ’ t r a n s m i s s i o n P o w e r ’ ] )
142 s e l f . bandwidth= f l o a t (G. graph [ ’ bandwidth ’ ] )
143 s e l f . n o i s e _ f i g u r e=f l o a t (G. graph [ ’ n o i s e F i g u r e ’ ] )
144 s e l f . r e c e i v e r _ s e n s i t i v i t y=f l o a t (G. graph [ ’ r e c e i v e r S e n s i t i v i t y ’ ] )
145 s e l f . snr_minimum= f l o a t (G. graph [ ’ s n r ’ ] )
146 s e l f . semi_major_axis = i n t ( f l o a t (G. graph [ ’ semiMajorAxisMeters ’ ] ) )
147 s e l f . min_communications_altitude = i n t (G. graph [ ’
minCommunicationsAltitudeMeters ’ ] )
148 s e l f . m i n _ s a t _ e l e v a t i o n = i n t (G. graph [ ’ m i n S a t E l e v a t i o n D e g r e e s ’ ] )
149
150
151 # path c a l c u l a t i o n
152 s e l f . path_node_1 = None
153 s e l f . path_node_2 = None
154 s e l f . path_length = 0 . 0
155 s e l f . p a t h _ l i n k s = None
156 s e l f . max_node_degree = −1
157
158 # control flags
159 s e l f . animate = True
160 s e l f . capture_gml = F a l s e
161 s e l f . capture_images = F a l s e
162 s e l f . capt_interpolation = 1
163 s e l f . make_links = True
164 s e l f . linking_method = ’+GRID ’ # used b e c a u s e i t d o e s not r e g e n e r a t e
links
165 s e l f . enable_path_calculation = False
166
167 # timing c o n t r o l
168 s e l f . time_step = 1
169 s e l f . c u r r e n t _ s i m u l a t i o n _ t i m e = i n t ( f l o a t (G. graph [ ’ s i m u l a t i o n T i m e ’ ] ) )
170 s e l f . pause = True
171 s e l f . num_steps_to_run = −1
172
173 # p e r f o r m a n c e data
174 s e l f . time_1 = 1
175 s e l f . time_for_frame = 1
176 s e l f . time_to_update_model = 1
177 s e l f . time_to_export_gml = 1
178 s e l f . time_to_update_render = 1
179 s e l f . time_to_export_img = 1
180
181 # g e t a l l o f t h e edge data
182 edge_data = l i s t (G. e d g e s ( ) )
183 # r e t u r n s i n data i n s t r i n g format , s o I c o n v e r t data t o i n t s
184 f o r i i n r a n g e ( l e n ( edge_data ) ) :
185 edge_data [ i ] = [ i n t ( edge_data [ i ] [ 0 ] ) , i n t ( edge_data [ i ] [ 1 ] ) ]
186
187 # i n i t t h e ’ p i p e ’ o b j e c t used f o r i n t e r −p r o c e s s communication
188 # t h i s comes from t h e m u l t i p r o c e s s i n g l i b r a r y
189 s e l f . pipeConn = pipeConn
190 s e l f . c o n t r o l T h r e a d = td . Thread ( t a r g e t= s e l f . c o n t r o l T h r e a d H a n d l e r )
191 s e l f . controlThread . s t a r t ()
192
193 # i n i t t h e C o n s t e l l a t i o n model
194 s e l f . model = C o n s t e l l a t i o n (
195 p l a n e s= s e l f . num_planes ,
196 nodes_per_plane= s e l f . num_nodes_per_plane ,
197 i n c l i n a t i o n= s e l f . p l a n e _ i n c l i n a t i o n ,
198 f r e q u e n c y= s e l f . communication_frequency ,
199 t r a n s m i s s i o n _ p o w e r= s e l f . transmission_power ,
200 bandwidth= s e l f . bandwidth ,
201 n o i s e _ f i g u r e= s e l f . n o i s e _ f i g u r e ,
202 r e c e i v e r _ s e n s i t i v i t y= s e l f . r e c e i v e r _ s e n s i t i v i t y ,
203 s n r= s e l f . snr_minimum ,
204 semi_major_axis= s e l f . semi_major_axis ,
205 minCommunicationsAltitude= s e l f . min_communications_altitude ,
206 m i n S a t E l e v a t i o n= s e l f . min_sat_elevation ,
207 l i n k i n g M e t h o d= s e l f . linking_method ,
208 arcOfAscendingNodes =180.0)
209
265 return
266
267 else : # i f gmlImportFileName i s None
268
269 # c o n s t i l l a t i o n structure information
270 s e l f . num_planes = p l a n e s
271 s e l f . num_nodes_per_plane = nodesPerPlane
272 s e l f . plane_inclination = inclination
273 s e l f . communication_frequency = f r e q u e n c y
274 s e l f . transmission_power = transmissionPower
275 s e l f . bandwidth=bandwidth
276 s e l f . n o i s e _ f i g u r e=n o i s e F i g u r e
277 s e l f . r e c e i v e r _ s e n s i t i v i t y= r e c e i v e r S e n s i t i v i t y
278 s e l f . snr_minimum=s n r
279 s e l f . semi_major_axis = semiMajorAxis
280 s e l f . min_communications_altitude = 100000
281 s e l f . m i n _ s a t _ e l e v a t i o n = MIN_SAT_ELEVATION
282
283 # path c a l c u l a t i o n
284 s e l f . path_node_1 = None
285 s e l f . path_node_2 = None
286 s e l f . path_length = 0 . 0
287 s e l f . p a t h _ l i n k s = None
288 s e l f . max_node_degree = −1
289
290 # control flags
291 s e l f . animate = animate
292 s e l f . capture_gml = captureGML
293 s e l f . capture_images = c a p t u r e I m a g e s
294 s e l f . capt_interpolation = 1
295 s e l f . make_links = makeLinks
296 s e l f . linking_method = ’SPARSE ’ # o p t i o n s : ’IDEAL ’ , ’+GRID ’ , ’SPARSE ’
297 s e l f . enable_path_calculation = False
298
299 # timing c o n t r o l
300 s e l f . time_step = t i m e S t e p
301 s e l f . current_simulation_time = 0.0
302 s e l f . pause = True
303 s e l f . num_steps_to_run = −1
304
305 # p e r f o r m a n c e data
306 s e l f . time_1 = 1
307 s e l f . time_for_frame = 1
308 s e l f . time_to_update_model = 1
309 s e l f . time_to_export_gml = 1
310 s e l f . time_to_update_render = 1
311 s e l f . time_to_export_img = 1
312
313 # i n i t t h e ’ p i p e ’ o b j e c t used f o r i n t e r −p r o c e s s communication
314 # t h i s comes from t h e m u l t i p r o c e s s i n g l i b r a r y
315 s e l f . pipeConn = pipeConn
316 s e l f . c o n t r o l T h r e a d = td . Thread ( t a r g e t= s e l f . c o n t r o l T h r e a d H a n d l e r )
317 s e l f . controlThread . s t a r t ()
318
319 # i n i t t h e C o n s t e l l a t i o n model
320 s e l f . model = C o n s t e l l a t i o n (
321 p l a n e s= s e l f . num_planes ,
322 nodes_per_plane= s e l f . num_nodes_per_plane ,
323 i n c l i n a t i o n= s e l f . p l a n e _ i n c l i n a t i o n ,
324 f r e q u e n c y= s e l f . communication_frequency ,
325 t r a n s m i s s i o n _ p o w e r= s e l f . transmission_power ,
326 bandwidth= s e l f . bandwidth ,
327 n o i s e _ f i g u r e= s e l f . n o i s e _ f i g u r e ,
328 r e c e i v e r _ s e n s i t i v i t y= s e l f . r e c e i v e r _ s e n s i t i v i t y ,
329 s n r= s e l f . snr_minimum ,
330 semi_major_axis= s e l f . semi_major_axis ,
331 minCommunicationsAltitude= s e l f . min_communications_altitude ,
332 m i n S a t E l e v a t i o n= s e l f . min_sat_elevation ,
333 l i n k i n g M e t h o d= s e l f . linking_method ,
334 arcOfAscendingNodes=RAAN)
335
336 # add ground p o i n t s t o t h e c o n s t i l l a t i o n model
337 # from t h e g i v e n f i l e path
338 # TODO: add e r r o r p r o t e c t i o n . . .
339 data = [ ]
340 s e l f . city_names = [ ]
341 with open ( g r o u n d P t s F i l e , ’ r ’ ) a s f :
342 for l i n e in f :
343 my_line = [ ]
344 f o r word i n l i n e . s p l i t ( ) :
345 my_line . append ( word )
346 data . append ( my_line )
347 f o r i i n r a n g e ( 1 , l e n ( data ) ) :
348 s e l f . city_names . append ( data [ i ] [ 0 ] )
349 s e l f . model . addGroundPoint ( f l o a t ( data [ i ] [ 1 ] ) , f l o a t ( data [ i ] [ 2 ] ) )
350
351 # send t h e names t o t h e GUI s o t h e u s e r
352 # can s e e them i n drop down menu
353 s e l f . pipeConn . send ( [ " placeNames " , s e l f . city_names ] )
354
355 # i n i t t h e network d e s i g n
356 i f s e l f . make_links :
357 s e l f . initializeNetworkDesign ()
358
359 # so , a f t e r much e f f o r t i t a p p e a r s t h a t I cannot c o n t r o l an
360 # i n t e r a c t i v e vtk window e x t e r n a l l y . T h e r e f o r e when r u n n i n g
361 # with an animation , t h e a n i m a t i o n c l a s s w i l l have t o d r i v e
362 # t h e s i m u l a t i o n u s i n g an i n t e r n a l t i m e r . . .
363 i f s e l f . animate :
364 s e l f . setupAnimation (
365 s e l f . model . t o t a l _ s a t s ,
366 s e l f . model . g e t A r r a y O f S a t P o s i t i o n s ( ) ,
367 − s e l f . model . ground_node_counter ,
368 s e l f . model . g e t A r r a y O f G n d P o s i t i o n s ( ) ,
369 s e l f . time_step ,
370 s e l f . current_simulation_time ,
371 s e l f . capture_images
372 )
373
374 else :
375 # TODO: then we run d r i v e t h e s i m u l a t i o n from h e r e
376 return
377
378 def initializeNetworkDesign ( s e l f ) :
379 p r i n t ( " i n i t a l i z i n g network d e s i g n . . . " )
380 s e l f . m a x _ i s l _ d i s t a n c e = s e l f . model . c a l c u l a t e M a x I S L D i s t a n c e (
381 s e l f . min_communications_altitude )
382
412 """
413
414 w h i l e True :
415 r e c e i v e d _ d a t a = s e l f . pipeConn . r e c v ( )
416 i f type ( r e c e i v e d _ d a t a ) == s t r :
417 i f r e c e i v e d _ d a t a == " doTestFunc " :
418 s e l f . testFunc ( )
419
420 i f r e c e i v e d _ d a t a == " enableImageCapture " :
421 p r i n t ( " e n a b l e d image c a p t u r e " )
422 s e l f . capture_images = True
423
424 i f r e c e i v e d _ d a t a == " d i s a b l e I m a g e C a p t u r e " :
425 p r i n t ( " d i s a b l e d image c a p t u r e " )
426 s e l f . capture_images = F a l s e
427
428 i f r e c e i v e d _ d a t a == " enableGMLCapture " :
429 p r i n t ( " e n a b l e d GML c a p t u r e " )
430 s e l f . capture_gml = True
431
432 i f r e c e i v e d _ d a t a == " disableGMLCapture " :
451 e l i f type ( r e c e i v e d _ d a t a ) == l i s t :
452 command = r e c e i v e d _ d a t a [ 0 ]
453 i f command == " s e t T i m e s t e p " :
454 p r i n t ( " s e t t i n g timestep to : " , received_data [ 1 ] )
455 s e l f . time_step = r e c e i v e d _ d a t a [ 1 ]
456
457 i f command == " se tL in ki ng Me th od " :
458 s e l f . linking_method = r e c e i v e d _ d a t a [ 1 ]
459 p r i n t ( " s e t l i n k i n g method t o : " , r e c e i v e d _ d a t a [ 1 ] )
460 # i f r e s e t l i n k i n g method , must r e i n i t network
461 s e l f . initializeNetworkDesign ()
462
463 i f command == " s e t R u n f o r " :
464 s e l f . num_steps_to_run = i n t ( r e c e i v e d _ d a t a [ 1 ] / s e l f . time_step )−1
465 p r i n t ( " r u n n i n g f o r : " , s e l f . num_steps_to_run , " t i m e s t e p s . . . " )
466 s e l f . pause = F a l s e
467
516 """
517
518 # grab i n i t i a l time
519 s e l f . time_1 = time . time ( )
520
521 s e l f . frameCount += 1
522
523 if s e l f . num_steps_to_run > 0 :
524 s e l f . num_steps_to_run −= 1
525 e l i f s e l f . num_steps_to_run == 0 :
526 s e l f . pause = True
527 s e l f . num_steps_to_run = −1
528
529 # update l i n k s / network d e s i g n / s a t p o s i t i o n s
530 s e l f . model . s e t C o n s t i l l a t i o n T i m e ( new_time )
531 i f s e l f . make_links :
532 i f s e l f . linking_method == ’IDEAL ’ :
533 s e l f . model . c a l c u l a t e I d e a l L i n k s (
534 s e l f . max_isl_distance ,
535 s e l f . max_stg_distance )
536 i f s e l f . linking_method == ’+GRID ’ :
537 s e l f . model . c a l c u l a t e P l u s G r i d L i n k s ( s e l f . max_stg_distance ,
max_isl_range= s e l f . m a x _ i s l _ d i s t a n c e )
538 i f s e l f . linking_method == ’SPARSE ’ :
539 s e l f . model . c a l c u l a t e P l u s G r i d L i n k s ( s e l f . max_stg_distance )
540
541 s e l f . time_to_update_model = time . time ( ) − s e l f . time_1
542
543 # g e n e r a t e GML graph i f a p p l i c a b l e
544 #i f s e l f . capture_gml and \
545 # s e l f . frameCount % s e l f . c a p t _ i n t e r p o l a t i o n == 0 o r \
546 # s e l f . enable_path_calculation :
547 i f s e l f . capture_gml and \
548 s e l f . frameCount % s e l f . c a p t _ i n t e r p o l a t i o n == 0 :
549 # s e t up graph , r e c o r d i n g i m p o r t a n t i n f o about t h e c u r r e n t model
550 s e l f . model . generateNetworkGraph ( s e l f . city_names )
551
552 # c a l c u l a t e max node d e g r e e ( number o f e d g e s c o n n e c t e d t o a node )
553 d e g r e e _ l i s t = l i s t ( s e l f . model .G. d e g r e e ( ) )
554 f o r i in range ( len ( d e g r e e _ l i s t ) ) :
555 degree_list [ i ] = int ( degree_list [ i ] [ 1 ] )
556 s e l f . max_node_degree = max( d e g r e e _ l i s t )
557
558 # i f enabled , we run d i j k s t r a ’ s between two p o i n t s
559 i f s e l f . enable_path_calculation :
560 node_1 = s e l f . path_node_1
561 node_2 = s e l f . path_node_2
562 i f ( node_1 i s not None ) and ( node_2 i s not None ) :
563 id_1 = −( s e l f . city_names . i n d e x ( node_1 ) + 1 )
564 id_2 = −( s e l f . city_names . i n d e x ( node_2 ) + 1 )
565 s e l f . model . generateNetworkGraph2 ( s e l f . city_names , id_1 , id_2 )
566 #p r i n t ( " node_1 %s , node_2 %s , id_1 %d , id_2 %s " % ( node_1 , node_2 ,
id_1 , id_2 ) )
567
568 # run s h o r t e s t path , h a n d l e e x c e p t i o n i f path not e x i s t
569 try :
570 path = nx . s h o r t e s t _ p a t h (
571 s e l f . model . G,
572 s o u r c e=s t r ( id_1 ) ,
573 t a r g e t=s t r ( id_2 ) ,
574 w e i g h t= ’ d i s t a n c e ’ )
575
576 # c o n v e r t l i s t o f nodes i n t o e d g e s
577 s e l f . path_links = [ ]
578
579
580
581 # XXX: Plathon −− P r i n t r o u t e nodes and compute and p r i n t end t o
end RTT
582 dist = 0.0
583 f o r i i n r a n g e ( l e n ( path ) −1) :
584 s e l f . p a t h _ l i n k s . append ( [ path [ i ] , path [ i + 1 ] ] )
585 d i s t = d i s t + f l o a t ( s e l f . model .G[ path [ i ] ] [ path [ i + 1 ] ] [ ’ d i s t a n c e ’
])
586
587 p r i n t ( " End t o End path : %s " % s t r ( path ) )
588 RTT = 2 . 0 ∗ d i s t /SPEED_OF_LIGHT_M_PER_S
589
590 p r i n t ( " d i t a n c i a : %d " % d i s t )
591 p r i n t ( "RTT: %f " % RTT)
592 p r i n t ( path )
593
594 e x c e p t nx . e x c e p t i o n . NetworkXNoPath :
635 d e f setupAnimation (
636 self ,
637 total_satellites ,
638 satellite_positions ,
639 total_groundpoints ,
640 groundpoint_positions ,
641 t i m e s t e p =60 ,
642 c u r r e n t _ s i m u l a t i o n _ t i m e =0,
643 capture_images=F a l s e ) :
644 """
645 Makes vtk r e n d e r window , and s e t s up p i p e l i n e s .
646
647 Parameters
648 −−−−−−−−−−
649 total_satellites : int
704
705 # r o t a t e e a r t h and l a n d
706 r o t a t i o n _ p e r _ t i m e _ s t e p = 3 6 0 . 0 / (SECONDS_PER_DAY / s e l f . time_step )
707 s e l f . e a r t h A c t o r . RotateZ ( r o t a t i o n _ p e r _ t i m e _ s t e p )
708 s e l f . s p h e r e A c t o r . RotateZ ( r o t a t i o n _ p e r _ t i m e _ s t e p )
709
710 else :
711 new_simulation_time = s e l f . c u r r e n t _ s i m u l a t i o n _ t i m e
712
713 # grab new p o s i t i o n data
714 n e w _ s a t _ p o s i t i o n s = s e l f . model . g e t A r r a y O f S a t P o s i t i o n s ( )
715 n e w _ gr o u n d p o in t _ p o s i ti o n s = s e l f . model . g e t A r r a y O f G n d P o s i t i o n s ( )
716
717 # update s a t p o i n t s
718 f o r i in range ( s e l f . t o t a l S a t s ) :
719 x = new_sat_positions [ i ] [ ’ x ’ ]
720 y = new_sat_positions [ i ] [ ’ y ’ ]
721 z = new_sat_positions [ i ] [ ’ z ’ ]
722 s e l f . satVtkPts . S e t P o i n t ( s e l f . s a t P o i n t I D s [ i ] , x , y , z )
723 s e l f . satPolyData . GetPoints ( ) . M o d i f i e d ( )
724
725 # update gnd p t s
726 f o r i in range ( s e l f . totalGroundpoints ) :
727 x = n e w _ g ro u n d p o i nt _ p o s i t i on s [ i ] [ ’ x ’ ]
728 y = n e w _ g ro u n d p o i nt _ p o s i t i on s [ i ] [ ’ y ’ ]
729 z = n e w_ g r o u n d po i n t _ p o s it i o n s [ i ] [ ’ z ’ ]
730 s e l f . gndVtkPts . S e t P o i n t ( s e l f . gndPointIDs [ i ] , x , y , z )
731 s e l f . gndPolyData . GetPoints ( ) . M o d i f i e d ( )
732
788 s e l f . pathPolyData . S e t P o i n t s ( s e l f . l i n k P o i n t s )
789 s e l f . pathPolyData . S e t L i n e s ( s e l f . p a t h L i n k L i n e s )
790
791 o b j . GetRenderWindow ( ) . Render ( )
792 s e l f . c u r r e n t _ s i m u l a t i o n _ t i m e = new_simulation_time
793 i f not s e l f . pause :
794 s e l f . time_to_update_render = ( time . time ( ) − s e l f . time_1 ) −\
795 ( s e l f . time_to_update_model + s e l f . time_to_export_gml )
796
797 if s e l f . capture_images \
798 and s e l f . frameCount % s e l f . c a p t _ i n t e r p o l a t i o n == 0\
799 and not s e l f . pause :
800 s e l f . renderToPng ( )
801
802 i f not s e l f . pause :
803 s e l f . time_to_export_img = ( time . time ( ) − s e l f . time_1 ) −\
804 ( s e l f . time_to_update_model + s e l f . time_to_export_gml +
805 s e l f . time_to_update_render )
806
807 s e l f . time_for_frame = time . time ( ) − s e l f . time_1
808 s e l f . statusReport ()
809
810 d e f renderToPng ( s e l f , path=PNG_OUTPUT_PATH) :
811 """
812 Take a . png o f t h e r e n d e r window , and s a v e i t .
813
814 Parameters
815 −−−−−−−−−−
816 path : s t r
817 The r e l a t i v e path o f where t o s a v e t h e image
818
819 """
820
837 d e f makeRenderWindow ( s e l f ) :
838 """
839 Makes a r e n d e r window o b j e c t u s i n g vtk .
840
841 This s h o u l d not be c a l l e d u n t i l a l l t h e a c t o r s a r e c r e a t e d .
842
843 """
844
845 # create a renderer object
846 s e l f . r e n d e r e r = vtk . vtk Ren dere r ( )
847 s e l f . renderWindow = vtk . vtkRenderWindow ( )
848 s e l f . renderWindow . AddRenderer ( s e l f . r e n d e r e r )
849
850 # c r e a t e an i n t e r a c t o r o b j e c t , t o i n t e r a c t with t h e window . . . duh
851 s e l f . i n t e r a c t o r = vtk . vtkRenderWindowInteractor ( )
852 s e l f . i n t e r a c t o r . S e t I n t e r a c t o r S t y l e ( vtk .
vtkInteractorStyleTrackballCamera () )
853 s e l f . i n t e r a c t o r . SetRenderWindow ( s e l f . renderWindow )
854
855 # add t h e a c t o r o b j e c t s
856 s e l f . r e n d e r e r . AddActor ( s e l f . s a t s A c t o r )
857 s e l f . r e n d e r e r . AddActor ( s e l f . e a r t h A c t o r )
858 s e l f . r e n d e r e r . AddActor ( s e l f . gndActor )
859 s e l f . r e n d e r e r . AddActor ( s e l f . s p h e r e A c t o r )
860 i f s e l f . make_links :
861 s e l f . r e n d e r e r . AddActor ( s e l f . i s l A c t o r )
862 s e l f . r e n d e r e r . AddActor ( s e l f . s g l A c t o r )
863 s e l f . r e n d e r e r . AddActor ( s e l f . pathActor )
864
869 s e l f . interactor . I n i t i a l i z e ()
870 print ( ’ i n i t i a l i z e d interactor ’ )
871
872 # s e t up a t i m e r t o c a l l t h e update f u n c t i o n a t a max r a t e
873 # o f e v e r y 7 ms (~144 hz )
874 s e l f . i n t e r a c t o r . AddObserver ( ’ TimerEvent ’ , s e l f . updateAnimation )
875 s e l f . i n t e r a c t o r . CreateRepeatingTimer ( 7 )
876 p r i n t ( ’ s e t up t i m e r ’ )
877
878 # s t a r t t h e model
879 s e l f . renderWindow . S e t S i z e ( 5 1 2 , 5 1 2 )
880 s e l f . renderWindow . Render ( )
881 print ( ’ started render ’ )
882 s e l f . interactor . Start ()
883 print ( ’ started interactor ’ )
884
885 d e f makeSatsActor ( s e l f , t o t a l _ s a t e l l i t e s , s a t e l l i t e _ p o s i t i o n s ) :
886 """
887 generate the point cloud to r e p r e s e n t s a t e l l i t e s
888
889 Parameters
890 −−−−−−−−−−
891 total_satellites : int
892 number o f s a t e l l t i e s i n t h e s i m u l a t i o n
893 s a t e l l i t e _ p o s i t i o n s : np . a r r a y [ [ ( ’ x ’ , i n t 3 2 ) , ( ’ y ’ , i n t 3 2 ) , ( ’ z ’ , i n t 3 2 )
]]
894 s a t e l l i t e p o s i t i o n data , s a t e l l i t e " unique_id " = i n d e x number
895 """
896
941 Parameters
942 −−−−−−−−−−
943 total_groundpoints : int
944 number o f s a t e l l t i e s i n t h e s i m u l a t i o n
945 g r o u n d p o i n t _ p o s i t i o n s : np . a r r a y [ [ ( ’ x ’ , i n t 3 2 ) , ( ’ y ’ , i n t 3 2 ) , ( ’ z ’ , i n t 3 2
) ]]
946 ground p o i n t p o s i t i o n data , s a t e l l i t e " unique_id " = −(index_number −1)
947 """
948
949 # i n i t p o i n t and c e l l a r r a y s
950 s e l f . gndVtkPts = vtk . v t k P o i n t s ( )
951 s e l f . gndVtkVerts = vtk . v t k C e l l A r r a y ( )
952
953 # f i g u r e out t h e t o t a l number o f g r o u n d p t s i n t h e c o n s t i l l a t i o n
954 s e l f . totalGroundpoints = total_groundpoints
955
956 # i n i t a a r r a y f o r IDs ?
957 s e l f . gndPointIDs = [ None ] ∗ s e l f . t o t a l G r o u n d p o i n t s
958
959 # init positions
960 f o r i in range ( s e l f . totalGroundpoints ) :
961 s e l f . gndPointIDs [ i ] = s e l f . gndVtkPts . I n s e r t N e x t P o i n t (
962 groundpoint_positions [ i ] [ ’x ’ ] ,
963 groundpoint_positions [ i ] [ ’y ’ ] ,
964 groundpoint_positions [ i ] [ ’ z ’ ] )
965
966 s e l f . gndVtkVerts . I n s e r t N e x t C e l l ( 1 )
967 s e l f . gndVtkVerts . I n s e r t C e l l P o i n t ( s e l f . gndPointIDs [ i ] )
968
969 # more s t a n d a r d p i p e l i n e c r e a t i o n . . .
970 s e l f . gndPolyData = vtk . vtkPolyData ( )
971 s e l f . gndPolyData . S e t P o i n t s ( s e l f . gndVtkPts )
972 s e l f . gndPolyData . S e t V e r t s ( s e l f . gndVtkVerts )
973 s e l f . gndMapper = vtk . vtkPolyDataMapper ( )
974 s e l f . gndMapper . SetInputData ( s e l f . gndPolyData )
975 s e l f . gndActor = vtk . vtkActor ( )
976 s e l f . gndActor . SetMapper ( s e l f . gndMapper )
977
1049 ##
1050
1051 s e l f . i s l A c t o r = vtk . vtkActor ( )
1052 s e l f . i s l A c t o r . SetMapper ( s e l f . i s l M a p p e r )
1053
1060 ##
1061
1062 s e l f . i s l A c t o r . GetProperty ( ) . S e t O p a c i t y (ISL_LINK_OPACITY)
1063 s e l f . i s l A c t o r . GetProperty ( ) . S e t C o l o r (ISL_LINK_COLOR)
1064 s e l f . i s l A c t o r . GetProperty ( ) . SetLineWidth (ISL_LINE_WIDTH)
1065
1099 # c o n t r o l e s t h e r e s o l u t i o n o f s u r f a c e data ( 1 = f u l l r e s o l u t i o n )
1100 s e l f . e a r t h S o u r c e . SetOnRatio ( 1 )
1101
1102 # C r e a t e a mapper
1103 s e l f . earthMapper = vtk . vtkPolyDataMapper ( )
1104 s e l f . earthMapper . S e t I n p u t C o n n e c t i o n ( s e l f . e a r t h S o u r c e . GetOutputPort ( ) )
1105
1106 # C r e a t e an a c t o r
1107 s e l f . e a r t h A c t o r = vtk . vtkActor ( )
1108 s e l f . e a r t h A c t o r . SetMapper ( s e l f . earthMapper )
1109
1143
1144 # C r e a t e a mapper
1145 sphereMapper = vtk . vtkPolyDataMapper ( )
1146 sphereMapper . SetInputData ( s p h e r e P o l y )
1147
1148 # C r e a t e an a c t o r
1149 s e l f . s p h e r e A c t o r = vtk . vtkActor ( )
1150 s e l f . s p h e r e A c t o r . SetMapper ( sphereMapper )
1151
1152 # set color
1153 s e l f . s p h e r e A c t o r . GetProperty ( ) . S e t C o l o r (EARTH_BASE_COLOR)
1154 s e l f . s p h e r e A c t o r . GetProperty ( ) . S e t O p a c i t y (EARTH_OPACITY)
B.5 City_data.txt
1 name l a t l o n
2 CNU 3 7 . 0 6 3 9 −76.4947
3 Madrid 4 0 . 4 1 6 5 −3.70256
4 Buenos−A i r e s −34.605083 −58.400368
5 Lima −12.04318 −77.02824
6 R e y k i a v i k 6 4 . 2 2 0 7 0 −21.96139
7 Cape−Town −33.92584 1 8 . 4 2 3 2 2
8 B r i s b a n e −27.46794 1 5 3 . 0 2 8 0 9
9 Trondheim 6 3 . 4 3 3 0 0 1 0 . 3 9 5 1 6
10 Tokyo 3 5 . 6 8 9 5 1 3 9 . 6 9 1 7 1
11 Los−Angeles−Long−Beach−Santa−Ana 3 4 . 0 3 1 6 5 6 −118.241716
12 Halifax_CA 4 7 . 1 1 7 4 0 −63.54726