Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pull Request: Basic/Advanced Distinction + Examples Estimation Section Additions and Changes #55

Closed
wants to merge 52 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
670b942
multi-arc propagation example (JUICE flybys).
SamFayolle Jul 24, 2024
ae3bc16
fixed JUICE GCO estimation example.
SamFayolle Jul 24, 2024
080d01a
temporary fix for obs bias partials issue.
SamFayolle Jul 24, 2024
7a2e49e
commented consider parameters for now.
SamFayolle Jul 24, 2024
07429b5
reduced propagation time to 100 days to reduce runtime.
SamFayolle Jul 24, 2024
65c9f56
switched to single station setup.
SamFayolle Jul 25, 2024
56dcc3c
Update full_estimation_example.py
luigigisolfi Aug 13, 2024
9d93de5
fixed ellipsoide feature in full_estimation_example.py
luigigisolfi Aug 14, 2024
fb76bc4
made a change to juice_orbital_phase.py
luigigisolfi Aug 16, 2024
0682a79
merging my_juice_examples onto luigi_examples, since my_juice_example…
luigigisolfi Aug 16, 2024
17a6790
added some comments to juice_orbital_phase.py, and also used spice to…
luigigisolfi Aug 16, 2024
eba9147
Comments and improvements of juice_orbital_phase.py. Stopped at the m…
luigigisolfi Aug 16, 2024
fc41819
working on pseudo_mpc data retrieval from a customized URL (for insta…
luigigisolfi Aug 18, 2024
45e1500
made some small changes to retrieving_pseudo_mpc.py
luigigisolfi Aug 19, 2024
743da01
made some small changes to retrieving_pseudo_mpc.py
luigigisolfi Aug 19, 2024
8dfec53
added minor changes to retrieve_pseudo_mpc.py
luigigisolfi Aug 19, 2024
5195b15
added minor changes to retrieve_pseudo_mpc.py
luigigisolfi Aug 19, 2024
4e551d9
Implemented Comments to clarify the juice_orbital_phase.py, up to the…
luigigisolfi Aug 19, 2024
b5ecaf4
small changes to juice_orbital_phase.py
luigigisolfi Aug 19, 2024
abc3510
changed juice_orbital_phase.py
luigigisolfi Aug 19, 2024
f201785
finished commenting juice_orbital_phase.py
luigigisolfi Aug 20, 2024
33a25bc
tested new version of juice_orbital_phase.py with comments. it works.
luigigisolfi Aug 20, 2024
5567d05
tried a fix of retrieve_pseudo_mpc.py...but it didnt work.
luigigisolfi Aug 20, 2024
bb9c187
added JUICE_GCO500.ipynb, converted it to .py and removed the old 'ju…
luigigisolfi Aug 22, 2024
cbf5ba6
cleared outputs of JUICE_GCO500.ipynb
luigigisolfi Aug 22, 2024
a532a70
edited the full_estimation_example.py, adding the comparison between …
luigigisolfi Aug 22, 2024
a0a4c78
Implemented Lars's comments on the JUICE's example: 1) d&o up to 15; …
luigigisolfi Aug 23, 2024
da21cf5
Edited full_estimation_example.py, but not doneyet
luigigisolfi Aug 26, 2024
82891f4
Small Changes in Juice_orbital_phase and retrieving_pseudo_mpc.py
luigigisolfi Aug 26, 2024
14307bb
Working on a new covariance example based on Starlink Satellite Simul…
luigigisolfi Aug 27, 2024
bb94ab2
minor changes to starlink_covariance_example.ipynb. (mainly plot colo…
luigigisolfi Aug 27, 2024
890de43
minor changes to starlink_covariance_example.ipynb. (mainly plot colo…
luigigisolfi Aug 27, 2024
ad874bb
minor changes to starlink_covariance_example.ipynb. (mainly plot colo…
luigigisolfi Aug 27, 2024
e1ae018
Starlink-32101 example was renamed into covariance_propagatino_exampl…
luigigisolfi Aug 28, 2024
e2935f1
commit for covariance_propagation_example.py
luigigisolfi Aug 29, 2024
5eb8ca5
modified covariance_estimated_parameters.ipynb and made it into pytho…
luigigisolfi Aug 29, 2024
c7c9e27
modified estimation_dynamical_models.ipynb and made it into python file.
luigigisolfi Aug 29, 2024
e7f0ec3
modified estimation_dynamical_models.ipynb and made it into python file.
luigigisolfi Aug 29, 2024
20d1258
modified estimation_dynamical_models.ipynb and made it into python file.
luigigisolfi Aug 29, 2024
1343648
edited the estimation_with_mpc.ipynb and made it into a python code a…
luigigisolfi Aug 29, 2024
7a0e225
Put the confidence ellipsoid plot inside covariance_estimated_paramet…
luigigisolfi Aug 29, 2024
d060bc6
1) Gave meaningful titles (objective-related) to each file (EXCEPT FO…
luigigisolfi Aug 30, 2024
6bfd16b
Finished editing Covariance propagation jupyter example, and made it …
luigigisolfi Aug 30, 2024
26b5567
nothing to declare
luigigisolfi Aug 30, 2024
6cbb73d
Minor changes to the intro of JUICE example.
luigigisolfi Aug 30, 2024
3896fab
Resolved merge conflict in covariance_propagation_example.py
luigigisolfi Aug 30, 2024
eb551cd
merged conflicts for JUICE_GCO500.ipynb and JUICE_GCO500.py
luigigisolfi Aug 30, 2024
8dbe7e5
edited full_estimation_Example.ipynb and made it into .py
luigigisolfi Aug 30, 2024
3d75d25
deleted retrieving_pseudo_mpc.py
luigigisolfi Sep 2, 2024
81b4427
Added Key API Reference table for the covariance_estimated_parameters…
luigigisolfi Sep 3, 2024
52f992d
added Key API References for covariance_estimated_parameters.ipynb an…
luigigisolfi Sep 3, 2024
54654c9
Moved all files back to single folder
DominicDirkx Sep 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,370 changes: 1,370 additions & 0 deletions estimation/JUICE_GCO500.ipynb

Large diffs are not rendered by default.

917 changes: 917 additions & 0 deletions estimation/JUICE_GCO500.py

Large diffs are not rendered by default.

595 changes: 504 additions & 91 deletions estimation/covariance_estimated_parameters.ipynb

Large diffs are not rendered by default.

559 changes: 401 additions & 158 deletions estimation/covariance_estimated_parameters.py

Large diffs are not rendered by default.

817 changes: 817 additions & 0 deletions estimation/covariance_propagation_example.ipynb

Large diffs are not rendered by default.

564 changes: 564 additions & 0 deletions estimation/covariance_propagation_example.py

Large diffs are not rendered by default.

2,052 changes: 0 additions & 2,052 deletions estimation/data/mrorange2006-2013.txt

This file was deleted.

217 changes: 155 additions & 62 deletions estimation/estimation_dynamical_models.ipynb

Large diffs are not rendered by default.

197 changes: 121 additions & 76 deletions estimation/estimation_dynamical_models.py

Large diffs are not rendered by default.

240 changes: 134 additions & 106 deletions estimation/estimation_with_mpc.ipynb

Large diffs are not rendered by default.

271 changes: 176 additions & 95 deletions estimation/estimation_with_mpc.py

Large diffs are not rendered by default.

179 changes: 99 additions & 80 deletions estimation/full_estimation_example.ipynb

Large diffs are not rendered by default.

333 changes: 187 additions & 146 deletions estimation/full_estimation_example.py

Large diffs are not rendered by default.

159 changes: 104 additions & 55 deletions estimation/galilean_moons_state_estimation.ipynb

Large diffs are not rendered by default.

197 changes: 125 additions & 72 deletions estimation/galilean_moons_state_estimation.py

Large diffs are not rendered by default.

139 changes: 95 additions & 44 deletions estimation/mro_range_estimation.ipynb

Large diffs are not rendered by default.

110 changes: 75 additions & 35 deletions estimation/mro_range_estimation.py

Large diffs are not rendered by default.

156 changes: 77 additions & 79 deletions estimation/retrieving_mpc_observation_data.ipynb

Large diffs are not rendered by default.

195 changes: 113 additions & 82 deletions estimation/retrieving_mpc_observation_data.py

Large diffs are not rendered by default.

Binary file added kernels/kernel_juice.bsp
Binary file not shown.
Binary file added kernels/kernel_noe.bsp
Binary file not shown.
Binary file added propagation/callisto_map.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added propagation/europa_map.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added propagation/ganymede_map.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
245 changes: 245 additions & 0 deletions propagation/juice_flybys.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
import sys

sys.path.insert(0, '/home/mfayolle/Tudat/tudat-bundle/build/tudatpy')

# Load required standard modules
import os
import numpy as np
from matplotlib import pyplot as plt

# Load required tudatpy modules
from tudatpy import constants
from tudatpy.interface import spice
from tudatpy import numerical_simulation
from tudatpy.numerical_simulation import environment
from tudatpy.numerical_simulation import environment_setup
from tudatpy.numerical_simulation import propagation, propagation_setup
from tudatpy.numerical_simulation import estimation, estimation_setup
from tudatpy.numerical_simulation.estimation_setup import observation
from tudatpy.astro.time_conversion import DateTime
from tudatpy.astro import element_conversion
from tudatpy.util import result2array


# Function retrieving JUICE's position wrt the flyby moon from their SPICE ephemerides, at a given time.
def get_juice_position_wrt_moon(time):
return spice.get_body_cartesian_position_at_epoch(
"-28", flyby_moon, "J2000", aberration_corrections="none", ephemeris_time=time)


# Function identifying JUICE's closest approaches wrt the flyby moon occurring within the specified time bounds, based on their SPICE trajectories.
# Only events where the closest distance meets the threshold are selected.
def find_closest_approaches(lower_time_bound, upper_time_bound, threshold):
flyby_times = []

tolerance = 1.0
step = 100.0

lower_time = lower_time_bound
mid_time = lower_time_bound + step
upper_time = lower_time_bound + 2.0 * step

while upper_time <= upper_time_bound:
upper_value = np.linalg.norm(get_juice_position_wrt_moon(upper_time))
mid_value = np.linalg.norm(get_juice_position_wrt_moon(mid_time))
lower_value = np.linalg.norm(get_juice_position_wrt_moon(lower_time))

if (upper_value - mid_value) > 0 and (mid_value - lower_value) < 0:

current_lower_time = lower_time
current_upper_time = upper_time
current_mid_time = (current_lower_time + current_upper_time) / 2.0
current_test_time = current_mid_time
counter = 0

while np.abs(current_mid_time - current_test_time) > tolerance:

current_test_time = current_mid_time

current_lower_distance = np.linalg.norm(get_juice_position_wrt_moon(current_lower_time))
current_upper_distance = np.linalg.norm(get_juice_position_wrt_moon(current_upper_time))
current_test_distance = np.linalg.norm(get_juice_position_wrt_moon(current_test_time))

sign_upper_derivative = np.sign((current_upper_distance - np.linalg.norm(
get_juice_position_wrt_moon(current_upper_time - tolerance))) / tolerance)
sign_lower_derivative = np.sign((current_lower_distance - np.linalg.norm(
get_juice_position_wrt_moon(current_lower_time - tolerance))) / tolerance)
sign_test_derivative = np.sign((current_test_distance - np.linalg.norm(
get_juice_position_wrt_moon(current_test_time - tolerance))) / tolerance)

if sign_upper_derivative > 0 and sign_test_derivative < 0:
current_mid_time = (current_upper_time + current_test_time) / 2.0
current_lower_time = current_test_time
elif sign_lower_derivative < 0 and sign_test_derivative > 0:
current_mid_time = (current_test_time + current_lower_time) / 2.0
current_upper_bound = current_test_time

counter += 1
if counter > 1000:
raise Exception("no minimum identified")

possible_time = current_mid_time

if np.linalg.norm(get_juice_position_wrt_moon(possible_time)) <= threshold:
flyby_times.append(possible_time)

lower_time = lower_time + step
mid_time = mid_time + step
upper_time = upper_time + step

return flyby_times


# Specify which moon is to be considered for the JUICE flybys (can be set to Europa, Ganymede, or Callisto)
flyby_moon = "Callisto"
if flyby_moon != "Europa" and flyby_moon != "Ganymede" and flyby_moon != "Callisto":
raise NameError('flyby_moon should be set to Europa, Ganymede, or Callisto.')

# Load spice kernels
path = os.path.dirname(__file__)
kernels = [path + '/../kernels/kernel_juice.bsp', path + '/../kernels/kernel_noe.bsp']
spice.load_standard_kernels(kernels)

# Set simulation start and end epochs according to JUICE mission timeline
start_epoch = 32.0 * constants.JULIAN_YEAR
end_epoch = 34.5 * constants.JULIAN_YEAR

# Define default body settings
bodies_to_create = ["Europa", "Ganymede", "Callisto", "Jupiter", "Sun"]
global_frame_origin = "Jupiter"
global_frame_orientation = "J2000"
body_settings = environment_setup.get_default_body_settings(bodies_to_create, global_frame_origin,
global_frame_orientation)

# Set rotation of flyby moon to synchronous
body_settings.get(flyby_moon).rotation_model_settings = environment_setup.rotation_model.synchronous(
"Jupiter", global_frame_orientation, "IAU_" + flyby_moon)

# Create empty settings for JUICE spacecraft
body_settings.add_empty_settings("JUICE")

# Set empty ephemeris for JUICE
empty_ephemeris_dict = dict()
juice_ephemeris = environment_setup.ephemeris.tabulated(
empty_ephemeris_dict,
global_frame_origin,
global_frame_orientation)
body_settings.get("JUICE").ephemeris_settings = juice_ephemeris

# Create system of bodies
bodies = environment_setup.create_system_of_bodies(body_settings)

# Add JUICE spacecraft to system of bodies
bodies.get("JUICE").mass = 5.0e3

# Create radiation pressure settings
ref_area = 100.0
srp_coef = 1.2
occulting_bodies = {"Sun": [flyby_moon]}
juice_srp_settings = environment_setup.radiation_pressure.cannonball_radiation_target(
ref_area, srp_coef, occulting_bodies)
environment_setup.add_radiation_pressure_target_model(bodies, "JUICE", juice_srp_settings)

# Find all JUICE flybys around the specified flyby moon.
# This finding algorithm identifies all closest approaches of the JUICE spacecraft with respect to the flyby moon,
# based on the JUICE's SPICE trajectory. Only those with a closest distance smaller or equal to 2.0e7 m are kept.
closest_approaches_juice = find_closest_approaches(start_epoch, end_epoch, 2.0e7)

# Extract number of JUICE flybys
nb_flybys = len(closest_approaches_juice)
print("nb_flybys ", nb_flybys)

# Define accelerations acting on JUICE
accelerations_settings_juice = dict(
Europa=[
propagation_setup.acceleration.spherical_harmonic_gravity(2, 2),
],
Ganymede=[
propagation_setup.acceleration.spherical_harmonic_gravity(2, 2),
],
Callisto=[
propagation_setup.acceleration.spherical_harmonic_gravity(2, 2),
],
Jupiter=[
propagation_setup.acceleration.spherical_harmonic_gravity(2, 0)
],
Sun=[
propagation_setup.acceleration.radiation_pressure(),
propagation_setup.acceleration.point_mass_gravity()
])

acceleration_settings = {"JUICE": accelerations_settings_juice}

body_to_propagate = ["JUICE"]
central_body = [flyby_moon]

acceleration_models = propagation_setup.create_acceleration_models(
bodies, acceleration_settings, body_to_propagate, central_body)

# Define integrator settings
integrator = propagation_setup.integrator.runge_kutta_fixed_step_size(
initial_time_step=10.0, coefficient_set=propagation_setup.integrator.rkf_78)

# Define dependent variables
dependent_variables_names = [
propagation_setup.dependent_variable.latitude("JUICE", flyby_moon),
propagation_setup.dependent_variable.longitude("JUICE", flyby_moon),
propagation_setup.dependent_variable.altitude("JUICE", flyby_moon)
]

# Define propagator settings for each arc (i.e., each flyby)
propagator_settings_list = []
for k in range(nb_flybys):
# The initial time of the propagation is set at the time of closest approach (obtained from SPICE), and the JUICE spacecraft is then
# propagated backwards and forwards from that point.
flyby_time = closest_approaches_juice[k]

# Get initial state of JUICE wrt the flyby moon from SPICE (JUICE's SPICE ID: -28)
initial_state = spice.get_body_cartesian_state_at_epoch("-28", flyby_moon, "J2000", "None", flyby_time)
print('flyby altitude ',
(np.linalg.norm(initial_state[:3]) - bodies.get(flyby_moon).shape_model.average_radius) / 1e3, 'km')

# Create termination settings (propagate between 30 min before and after closest approach)
time_around_closest_approach = 0.5 * 3600.0
termination_condition = propagation_setup.propagator.non_sequential_termination(
propagation_setup.propagator.time_termination(flyby_time + time_around_closest_approach),
propagation_setup.propagator.time_termination(flyby_time - time_around_closest_approach))

# Define arc-wise propagator settings
propagator_settings_list.append(propagation_setup.propagator.translational(
central_body, acceleration_models, body_to_propagate, initial_state, flyby_time, integrator,
termination_condition,
propagation_setup.propagator.cowell, dependent_variables_names))

# Concatenate all arc-wise propagator settings into multi-arc propagator settings
propagator_settings = propagation_setup.propagator.multi_arc(propagator_settings_list)

# Propagate dynamics
simulator = numerical_simulation.create_dynamics_simulator(bodies, propagator_settings)
propagation_results = simulator.propagation_results.single_arc_results

# Plot flybys
moon_map = flyby_moon.lower() + '_map.jpg'
img = plt.imread(moon_map)

fig, ax = plt.subplots()
ax.imshow(img, extent=[0, 360, -90, 90])
for k in range(nb_flybys):
dependent_variables = result2array(propagation_results[k].dependent_variable_history)

# Resolve 2pi ambiguity for longitude
for i in range(len(dependent_variables)):
if dependent_variables[i, 2] < 0:
dependent_variables[i, 2] = dependent_variables[i, 2] + 2.0 * np.pi

plot = ax.scatter(dependent_variables[:, 2] * 180 / np.pi, dependent_variables[:, 1] * 180 / np.pi, s=2,
c=dependent_variables[:, 3] / 1e3, cmap='rainbow_r', vmin=0, vmax=5000)
cb = plt.colorbar(plot)

plt.xlabel('Longitude [deg]')
plt.ylabel('Latitude [deg]')
plt.xticks(np.arange(0, 361, 40))
plt.yticks(np.arange(-90, 91, 30))
cb.set_label('Altitude [km]')
plt.title('JUICE flybys at ' + flyby_moon)
plt.show()
1 change: 1 addition & 0 deletions propagation/reentry_trajectory.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ def updateGuidance(self, current_time: float):
mach_number = self.vehicle_flight_conditions.mach_number
airspeed = self.vehicle_flight_conditions.airspeed
density = self.vehicle_flight_conditions.density
print(f'Density:{density}')

# Set the current Angle of Attack (AoA). The following line enforces the followings:
# * the AoA is constant at 40deg when the Mach number is above 12
Expand Down