Skip to content

Commit 5bb76e8

Browse files
committed
Example scenario file initializing BSK with a TLE
1 parent 104bbb3 commit 5bb76e8

File tree

6 files changed

+2299
-1
lines changed

6 files changed

+2299
-1
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ISS (ZARYA)
2+
1 25544U 98067A 26007.20987549 .00008643 00000-0 16393-3 0 9995
3+
2 25544 51.6331 16.3696 0007633 350.2178 9.8661 15.49149320546808
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
## TLE Files
2+
3+
Up-to-date Two-Line Element (TLE) files can be downloaded from **CelesTrak**:
4+
5+
- Main site: [https://celestrak.org/](https://celestrak.org/)
6+
- Direct TLE collections: [https://www.celestrak.org/NORAD/elements/](https://www.celestrak.org/NORAD/elements/)

examples/MultiSatBskSim/scenariosMultiSat/TLE/oneWeb.tle

Lines changed: 1953 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
1 25544U 98067A 26006.24223504 .00010833 00000+0 20347-3 0 9999
2+
2 25544 51.6328 21.1584 0007565 346.4032 13.6751 15.49129493546659
3+
1 48274U 21035A 26006.30286804 .00016438 00000+0 19904-3 0 9998
4+
2 48274 41.4648 227.4700 0010932 230.4345 129.5529 15.60228155267869
5+
1 49044U 21066A 26006.24223504 .00010833 00000+0 20347-3 0 9995
6+
2 49044 51.6328 21.1584 0007565 346.4032 13.6751 15.49129493230447
7+
1 49271U 11037PF 26004.64318340 .00028978 00000+0 61383-1 0 9991
8+
2 49271 51.6484 131.7222 0876295 274.1689 75.9608 12.35042644204760
9+
1 53239U 22085A 26005.66276822 .00017089 00000+0 20692-3 0 9997
10+
2 53239 41.4649 231.3621 0010833 226.1462 133.8482 15.60206666173848
11+
1 54216U 22143A 26005.66276822 .00017089 00000+0 20692-3 0 9998
12+
2 54216 41.4649 231.3621 0010833 226.1462 133.8482 15.60206666158645
13+
1 63632U 25082A 26005.66276822 .00017089 00000+0 20692-3 0 9995
14+
2 63632 41.4649 231.3621 0010833 226.1462 133.8482 15.60206666255308
15+
1 64751U 25146A 26005.53262344 .00012388 00000+0 23158-3 0 9996
16+
2 64751 51.6326 24.6699 0007562 343.7680 16.3066 15.49114570 6752
17+
1 64786U 25149A 26005.66276822 .00017089 00000+0 20692-3 0 9990
18+
2 64786 41.4649 231.3621 0010833 226.1462 133.8482 15.60206666255309
19+
1 65077U 25166A 26005.53262344 .00012388 00000+0 23158-3 0 9990
20+
2 65077 51.6326 24.6699 0007562 343.7680 16.3066 15.49114570 2143
21+
1 65304U 25186A 26005.53262344 .00012388 00000+0 23158-3 0 9995
22+
2 65304 51.6326 24.6699 0007562 343.7680 16.3066 15.49114570 111
23+
1 65586U 25204A 26005.53262344 .00012388 00000+0 23158-3 0 9998
24+
2 65586 51.6326 24.6699 0007562 343.7680 16.3066 15.49114570 270
25+
1 65616U 25208A 26005.53262344 .00012388 00000+0 23158-3 0 9996
26+
2 65616 51.6326 24.6699 0007562 343.7680 16.3066 15.49114570 229
27+
1 65729U 98067XH 26005.25607600 .00356045 00000+0 15848-2 0 9998
28+
2 65729 51.6226 14.5241 0008650 52.9557 307.2235 15.82735395 16874
29+
1 65731U 98067XK 26005.43946464 .00154863 00000+0 11738-2 0 9993
30+
2 65731 51.6284 16.5460 0005192 29.2258 330.9029 15.71346613 16861
31+
1 65732U 98067XL 26005.26086524 .00225689 00000+0 13692-2 0 9993
32+
2 65732 51.6254 16.0815 0006449 34.8932 325.2490 15.76291933 16863
33+
1 65733U 98067XM 26005.26759737 .00529026 11769-3 17284-2 0 9998
34+
2 65733 51.6256 13.1042 0009396 58.5879 301.6044 15.89985351 16909
35+
1 65941U 98067XN 26005.46108388 .00104506 00000+0 11065-2 0 9996
36+
2 65941 51.6289 20.4464 0003782 57.6045 302.5315 15.63308997 13560
37+
1 65942U 98067XP 26005.27220087 .00168177 00000+0 14036-2 0 9992
38+
2 65942 51.6277 19.9288 0004507 48.4983 311.6401 15.68988816 13555
39+
1 65943U 98067XQ 26005.33313382 .00100451 00000+0 10653-2 0 9993
40+
2 65943 51.6303 21.0978 0002309 51.2346 308.8854 15.63289724 13545
41+
1 66052U 98067XR 26005.42961506 .00041695 00000+0 59203-3 0 9991
42+
2 66052 51.6306 23.2345 0001361 314.3370 45.7510 15.55989869 12520
43+
1 66174U 25241A 26005.53262344 .00012388 00000+0 23158-3 0 9993
44+
2 66174 51.6326 24.6699 0007562 343.7680 16.3066 15.49114570 511
45+
1 66515U 25246C 26004.98707992 .00031246 00000+0 32469-3 0 9997
46+
2 66515 41.4747 234.0941 0001852 45.0993 314.9997 15.63935128 8082
47+
1 66645U 25272A 26005.66276822 .00017089 00000+0 20692-3 0 9993
48+
2 66645 41.4649 231.3621 0010833 226.1462 133.8482 15.60206666267498
49+
1 66664U 25275A 26005.53262344 .00012388 00000+0 23158-3 0 9994
50+
2 66664 51.6326 24.6699 0007562 343.7680 16.3066 15.49114570 1280
51+
1 66906U 98067XS 26005.56531310 .00027185 00000+0 44965-3 0 9997
52+
2 66906 51.6316 24.1401 0002463 329.0837 31.0008 15.51999087 5315
53+
1 66907U 98067XT 26005.34218786 .00090644 00000+0 13190-2 0 9998
54+
2 66907 51.6312 24.8999 0003876 10.4657 349.6414 15.54979680 5286
55+
1 66908U 98067XU 26005.40540667 .00095543 00000+0 13889-2 0 9990
56+
2 66908 51.6305 24.5711 0003785 8.0344 352.0707 15.54982540 5296
57+
1 66909U 98067XV 26005.52920379 .00100146 00000+0 14248-2 0 9992
58+
2 66909 51.6315 23.8985 0003947 17.1564 342.9559 15.55546038 5313
59+
1 66910U 98067XW 26005.33604344 .00094853 00000+0 13658-2 0 9995
60+
2 66910 51.6301 24.8576 0003072 348.0526 12.0391 15.55248947 5283
61+
1 66911U 98067XX 26005.51971312 .00116634 00000+0 16158-2 0 9998
62+
2 66911 51.6303 23.8342 0002979 5.2842 354.8181 15.56195124 5300
63+
1 66912U 98067XY 26005.35310433 .00067371 00000+0 10252-2 0 9994
64+
2 66912 51.6318 24.9729 0003700 357.3172 2.7798 15.53885560 5274
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
#
2+
# ISC License
3+
#
4+
# Copyright (c) 2021, Autonomous Vehicle Systems Lab, University of Colorado at Boulder
5+
#
6+
# Permission to use, copy, modify, and/or distribute this software for any
7+
# purpose with or without fee is hereby granted, provided that the above
8+
# copyright notice and this permission notice appear in all copies.
9+
#
10+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16+
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17+
#
18+
19+
r"""
20+
Overview
21+
--------
22+
23+
This script demonstrates how to use the Basilisk v2.1 multi-threading to simulate a constellation
24+
of 16 spacecraft using 4 threads. The simulation scenario setup is very similar to
25+
:ref:`scenario_BasicOrbitMultiSat`. To setup the unique satellite orbits, the script here loops
26+
over all satellites an incrementally changes the orbit elements. The following Vizard screen capture
27+
illustrate the family of orbits being simulated.
28+
29+
.. image:: /_images/static/scenario_BasicOrbitMultiSat_MT.jpg
30+
:align: center
31+
32+
Inside the ``run()`` command the number of threads is specified using::
33+
34+
TheScenario.TotalSim.resetThreads(numThreads)
35+
36+
With this basic setup it is assumed that each BSK process can run independently in a thread. Note that this script
37+
does not use any spacecraft flight software which is running in a separate process. The Basilisk v2.1
38+
multi-threading only functions for simulations where each Basilisk process can be evaluated independently.
39+
40+
.. warning::
41+
42+
The Basilisk v2.1 multi-threading does not have a thread-safe messaging system. This will be
43+
added in a later release.
44+
45+
Illustration of Simulation Results
46+
----------------------------------
47+
48+
::
49+
50+
showPlots = True, numberSpacecraft=16, environment = 'Earth', numThreads = 4
51+
52+
.. image:: /_images/Scenarios/scenario_BasicOrbitMultiSat_MT_spacecraft_orbits.svg
53+
:align: center
54+
55+
56+
"""
57+
58+
# Get current file path
59+
import inspect
60+
import os
61+
import sys
62+
63+
from Basilisk.architecture import messaging
64+
# Import utilities
65+
from Basilisk.utilities import orbitalMotion, macros, vizSupport, tleHandling
66+
67+
filename = inspect.getframeinfo(inspect.currentframe()).filename
68+
path = os.path.dirname(os.path.abspath(filename))
69+
70+
# Import master classes: simulation base class and scenario base class
71+
sys.path.append(path + '/../')
72+
sys.path.append(path + '/../modelsMultiSat')
73+
sys.path.append(path + '/../plottingMultiSat')
74+
from BSK_MultiSatMasters import BSKSim, BSKScenario
75+
import BSK_EnvironmentEarth, BSK_MultiSatDynamics
76+
77+
# Import plotting files for your scenario
78+
import BSK_MultiSatPlotting as plt
79+
80+
# Create your own scenario child class
81+
class scenario_BasicOrbitFormationFlying(BSKSim, BSKScenario):
82+
def __init__(self, tleData):
83+
super(scenario_BasicOrbitFormationFlying, self).__init__(len(tleData), fswRate=10, dynRate=10, envRate=10)
84+
self.name = 'scenario_constellationFromTle'
85+
86+
self.set_EnvModel(BSK_EnvironmentEarth)
87+
88+
# Here we are setting the list of spacecraft dynamics to be a homogenous formation.
89+
# To use a heterogeneous spacecraft formation, this list can contain different classes
90+
# of type BSKDynamicModels
91+
self.set_DynModel([BSK_MultiSatDynamics] * self.numberSpacecraft)
92+
93+
# declare empty class variables
94+
self.samplingTime = []
95+
self.snTransLog = []
96+
self.snAttLog = []
97+
self.rwSpeedLog = []
98+
self.rwLogs = [[] for _ in range(self.numberSpacecraft)]
99+
100+
# declare empty containers for orbital elements
101+
self.oe = []
102+
103+
self.configure_initial_conditions(tleData)
104+
self.log_outputs()
105+
106+
if vizSupport.vizFound:
107+
# if this scenario is to interface with the BSK Viz, uncomment the saveFile line
108+
DynModelsList = []
109+
rwStateEffectorList = []
110+
for i in range(self.numberSpacecraft):
111+
DynModelsList.append(self.DynModels[i].scObject)
112+
rwStateEffectorList.append(self.DynModels[i].rwStateEffector)
113+
114+
batteryPanel = vizSupport.vizInterface.GenericStorage()
115+
batteryPanel.label = "Battery"
116+
batteryPanel.units = "Ws"
117+
batteryPanel.color = vizSupport.vizInterface.IntVector(
118+
vizSupport.toRGBA255("red") + vizSupport.toRGBA255("green"))
119+
batteryPanel.thresholds = vizSupport.vizInterface.IntVector([20])
120+
batteryInMsg = messaging.PowerStorageStatusMsgReader()
121+
batteryInMsg.subscribeTo(self.DynModels[0].powerMonitor.batPowerOutMsg)
122+
batteryPanel.batteryStateInMsg = batteryInMsg
123+
124+
tankPanel = vizSupport.vizInterface.GenericStorage()
125+
tankPanel.label = "Tank"
126+
tankPanel.units = "kg"
127+
tankPanel.color = vizSupport.vizInterface.IntVector(vizSupport.toRGBA255("cyan"))
128+
tankInMsg = messaging.FuelTankMsgReader()
129+
tankInMsg.subscribeTo(self.DynModels[0].fuelTankStateEffector.fuelTankOutMsg)
130+
tankPanel.fuelTankStateInMsg = tankInMsg
131+
132+
# Add this line to maintain Python references
133+
self.vizPanels = [batteryPanel, tankPanel]
134+
135+
storageList = [None] * self.numberSpacecraft
136+
storageList[0] = [batteryPanel, tankPanel]
137+
138+
viz = vizSupport.enableUnityVisualization(self, self.DynModels[0].taskName, DynModelsList
139+
, saveFile=__file__
140+
, rwEffectorList=rwStateEffectorList
141+
, genericStorageList=storageList
142+
)
143+
vizSupport.setInstrumentGuiSetting(viz, showGenericStoragePanel=True)
144+
145+
def configure_initial_conditions(self, tleData):
146+
EnvModel = self.get_EnvModel()
147+
DynModels = self.get_DynModel()
148+
149+
# Configure Dynamics initial conditions
150+
for i in range(self.numberSpacecraft):
151+
self.oe.append(orbitalMotion.ClassicElements())
152+
self.oe[i].a = tleData[i].oe.a
153+
#self.oe[i].a = 1.1 * EnvModel.planetRadius + 1E5 * (i + 1) # meters
154+
self.oe[i].e = tleData[i].oe.e
155+
#self.oe[i].e = 0.01 + 0.001 * (i)
156+
self.oe[i].i = tleData[i].oe.i
157+
#self.oe[i].i = 45.0 * macros.D2R
158+
self.oe[i].Omega = tleData[i].oe.Omega
159+
#self.oe[i].Omega = (48.2 + 5.0 * i) * macros.D2R
160+
self.oe[i].omega = tleData[i].oe.omega
161+
#self.oe[i].omega = 347.8 * macros.D2R
162+
self.oe[i].f = tleData[i].oe.f
163+
#self.oe[i].f = 85.3 * macros.D2R
164+
rN, vN = orbitalMotion.elem2rv(EnvModel.mu, self.oe[i])
165+
orbitalMotion.rv2elem(EnvModel.mu, rN, vN)
166+
DynModels[i].scObject.hub.r_CN_NInit = rN # m - r_CN_N
167+
DynModels[i].scObject.hub.v_CN_NInit = vN # m/s - v_CN_N
168+
DynModels[i].scObject.hub.sigma_BNInit = [[0.1], [0.2], [-0.3]] # sigma_BN_B
169+
DynModels[0].scObject.hub.omega_BN_BInit = [[0.0], [0.0], [0.0]] # rad/s - omega_BN_B
170+
171+
def log_outputs(self):
172+
# Process outputs
173+
DynModels = self.get_DynModel()
174+
175+
# Set the sampling time
176+
self.samplingTime = macros.sec2nano(1)
177+
178+
# Loop through every spacecraft
179+
for spacecraft in range(self.numberSpacecraft):
180+
181+
# log the navigation messages
182+
self.snTransLog.append(DynModels[spacecraft].simpleNavObject.transOutMsg.recorder(self.samplingTime))
183+
self.snAttLog.append(DynModels[spacecraft].simpleNavObject.attOutMsg.recorder(self.samplingTime))
184+
self.AddModelToTask(DynModels[spacecraft].taskName, self.snTransLog[spacecraft])
185+
self.AddModelToTask(DynModels[spacecraft].taskName, self.snAttLog[spacecraft])
186+
187+
# log the RW wheel speed information
188+
self.rwSpeedLog.append(DynModels[spacecraft].rwStateEffector.rwSpeedOutMsg.recorder(self.samplingTime))
189+
self.AddModelToTask(DynModels[spacecraft].taskName, self.rwSpeedLog[spacecraft])
190+
191+
# log addition RW information (power, etc)
192+
for item in range(DynModels[spacecraft].numRW):
193+
self.rwLogs[spacecraft].append(
194+
DynModels[spacecraft].rwStateEffector.rwOutMsgs[item].recorder(self.samplingTime))
195+
self.AddModelToTask(DynModels[spacecraft].taskName, self.rwLogs[spacecraft][item])
196+
197+
def pull_outputs(self, show_plots):
198+
#
199+
# Retrieve the logged data
200+
#
201+
202+
r_BN_N = []
203+
for i in range(self.numberSpacecraft):
204+
r_BN_N.append(self.snTransLog[i].r_BN_N)
205+
206+
#
207+
# Plot results
208+
#
209+
210+
plt.clear_all_plots()
211+
212+
plt.plot_orbits(r_BN_N, self.numberSpacecraft, 1)
213+
214+
figureList = {}
215+
if show_plots:
216+
plt.show_all_plots()
217+
else:
218+
fileName = os.path.basename(os.path.splitext(__file__)[0])
219+
figureNames = ["spacecraft_orbits"]
220+
figureList = plt.save_all_plots(fileName, figureNames)
221+
222+
# close the plots being saved off to avoid over-writing old and new figures
223+
plt.clear_all_plots()
224+
225+
return figureList
226+
227+
228+
def runScenario(scenario):
229+
# Initialize simulation
230+
scenario.InitializeSimulation()
231+
232+
# Configure run time and execute simulation
233+
simulationTime = macros.hour2nano(2)
234+
scenario.ConfigureStopTime(simulationTime)
235+
236+
scenario.ExecuteSimulation()
237+
238+
239+
def run(show_plots, tleData, numThreads):
240+
"""
241+
The scenarios can be run with the followings setups parameters:
242+
243+
Args:
244+
show_plots (bool): Determines if the script should display plots
245+
orbElem (list): list of orbital elements for each satellite (list of ClasssicElements)
246+
metaData (list): list of metadata for each satellite
247+
numThreads (int): number of threads
248+
"""
249+
250+
# Configure a scenario in the base simulation
251+
TheScenario = scenario_BasicOrbitFormationFlying(tleData)
252+
# This call allocates out the requested number of threads into the simulation
253+
# Note that unless the user does something further, processes will be assigned
254+
# in a round-robin fashion to the allocated threads. If you desire to specify
255+
# which processes execute on a given thread, then the addProcessToThread in
256+
# the SimModel (TotalSim in SimulationBaseClass) should be used.
257+
TheScenario.TotalSim.resetThreads(numThreads)
258+
runScenario(TheScenario)
259+
figureList = TheScenario.pull_outputs(show_plots)
260+
261+
return figureList
262+
263+
264+
if __name__ == "__main__":
265+
# show current path
266+
tleFile = "oneWeb.tle" # Options are "ISS_ZARYA.tle", "oneWeb.tle", "spacestations.2le"
267+
tleDataClass = tleHandling.satTle2elem(os.path.join(path, "TLE", tleFile))
268+
269+
run(show_plots=True,
270+
tleData=tleDataClass,
271+
numThreads=4
272+
)

src/tests/test_readTLE.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import Basilisk.utilities.orbitalMotion as om
77
from datetime import datetime, timedelta, timezone
88

9-
A_TOL = 1e-14 #[-]
9+
A_TOL = 1e-9 #[-]
1010
A_TOL_ROUNDTRIP = 1e-4 #[-] Tolerance for eccentricity (roundtrip error)
1111
A_TOL_DEG_ROUNDTRIP = 1.5 # [deg] Tolerance for angles in degrees (roundtrip error)
1212

0 commit comments

Comments
 (0)