from IPython.core.display import HTML
style=open('notebooks.css', "r").read()
HTML(style)
import numpy as np
import matplotlib.pyplot as plt
# Style pour les figure matplotlib (A choisir)
#plt.style.use('ggplot')
#plt.style.use('dark_background')
#plt.style.use('fivethirtyeight')
plt.style.use('fast')
#Option pour afficher les figures dans le notebook et eviter le plt.show():
%matplotlib inline
fs=16
plt.rc('xtick',labelsize=fs)
plt.rc('ytick',labelsize=fs)
# Constante célestes:
G=6.67408e-11 # Constante de gravitation -
Rt=6380000 # Rayon terrestre - m
Rl=1736000 # Rayon luniare - m
Ms=1.9884e30 # Masse du soleil - kg
Mt=5.9722e24 # Masse de la terre - kg
Ml=7.3477e22 # Masse Lune - kg
al=384e6 # Distance Terre-Lune - m
at=149.598262e9 # Distance Terre-Soleil - m
g0=9.81 # Accélération de la pesanteur terrestre au niveau de la mer
Le module SOLSTICE permet l'intégration de la trajectoire d'un module motorisé dans un champ gravitationnel composé d'un corp principal (body) et d'un corp secondaire (moon). Par défaut, c'est le système Terre-Lune qui est choisi
Il tient également compte des effets atmosphériques au décollage et des flux thermiques lors d'une rentrée atmosphérique.
Le module contient 3 classes d'utilisation différentes:
Vous pouvez trouver en ligne la documentation complète du module SOLSTICE. Ce notebook présente l'utilisation basique du module.
Pour télécharger le module, éxecuter la cellule suivante (décommenter puis recommenter):
# Importation de la classe capsule
from SOLSTICE import Capsule,Stage
L'utilisation de la class capsule permet de se familiariser avec les trajectoires spatiales et les manoeuvres. Ici on se propose de placer une capsule sur une orbite initiale circulaire à 400km d'altitude. La class prend comme argument initiaux, l'altitude et la vitesse $r\dot{\theta}$ initiale.
Rappeler l'expression de la vitesse sur une orbite circulaire à une altitude $zs$
</b>
$$ U_c=\sqrt{\dfrac{GM_t}{R_t+z_s}} $$
zs=5000e3
us=np.sqrt(G*Mt/(Rt+zs))
cap=Capsule(z0=zs,u=us) # cap est le nom de notre capsule
print(cap)
---- 27, Nov 2024 | 00:35 ---- time= 0j 0h 0min 0s ---- Position--(/Terre/)------ u=5918.228711879594 z=5000000.0 theta=0.0 Assiette=0.0 deg Incidence=0.0deg --------Parametres----------- beta=0.005 finesse=0.0
Si on veut regarder l'évolution de la capsule pendant une periode entière de révolution, on intégre la trajectoire sur une periode avec la méthode run().
# Periode de l'orbite à zs:
T1=np.sqrt(4*np.pi**2*(Rt+zs)**3/(G*Mt))
delta_t=1.
cap.run(dt=delta_t,ntmax=T1/delta_t)
---- 27, Nov 2024 | 03:57 ---- time= 0j 3h 21min 22s ---- Position--(/Terre/)------ u=5918.7468027094465 z=4998771.406397952 theta=360.00617956090133 Assiette=0.0015401771318610206 deg Incidence=0.0deg --------Parametres----------- beta=0.005 finesse=0.0
La capsule a donc parcouru un tour complet ($\theta=360$), on peut tracer la trajectoire à l'aide de la méthode plotraj():
cap.plotraj('polar')
plt.ylim(0,20000)
0-time | 1-r | 2-theta | 3-U | 4-Gamma | 5-Pdyn | 6-phi | 7-Acc | 8-Fl | 9-Alpha | 10-ref | 11-thetaL | 12-Ft | 13-Engine | 14-r2 | 15-theta2 | 16-Moon
(0.0, 20000.0)
On va maintenant changer d'orbite. Pour cela on va utiliser un tranfert de Hohmann pour passer de notre orbite initiale circulaire de rayon $r_1=5000$km et de vitesse $V_1$ à une seconde orbite circulaire de rayon $r_2=20000$km et de vitesse $V_2$. Pour atteindre la seconde orbite on va donc emprunter une orbite de transfert elliptique (dite de Hohmann) de demi grand axe $a_T=\dfrac{r_1+r_2}{2}$.
r1=Rt+cap.z
r2=36000e3
aT=(r1+r2)/2
dv1=cap.u*(np.sqrt(r2/aT)-1)
Ttrans=np.pi*np.sqrt(aT**3/(G*Mt))
print(dv1)
1377.5772243157423
On va maintenant réaliser la manoeuvre à l'aide de la méthode mvr() qui prend comme argument le $\Delta V$ et l'angle de la manoeuvre (ici 0):
cap.mvr(dv1,0) # Manoeuvre
---- 27, Nov 2024 | 03:57 ---- time= 0j 3h 21min 22s ---- Position--(/Terre/)------ u=7296.324027025189 z=4998771.406397952 theta=360.00617956090133 Assiette=0.0015401771318610206 deg Incidence=0.0deg --------Parametres----------- beta=0.005 finesse=0.0
Notez que la vitesse à changée. On intègre maintenant pendant la durée du transfert $T_t$ et on trace la nouvelle trajectoire:
cap.run(dt=delta_t,ntmax=Ttrans/delta_t) # Intégration pendant le transfert
# On trace la trajectoire:
cap.plotraj('polar')
plt.ylim(0,40000)
---- 27, Nov 2024 | 08:59 ---- time= 0j 8h 23min 46s ---- Position--(/Terre/)------ u=2305.183113211793 z=29629999.47788117 theta=539.9861901070234 Assiette=-0.01697917296869883 deg Incidence=0.0deg --------Parametres----------- beta=0.005 finesse=0.0 0-time | 1-r | 2-theta | 3-U | 4-Gamma | 5-Pdyn | 6-phi | 7-Acc | 8-Fl | 9-Alpha | 10-ref | 11-thetaL | 12-Ft | 13-Engine | 14-r2 | 15-theta2 | 16-Moon
(0.0, 40000.0)
Enfin on "circularise" l'orbite en ajoutant l'incrément de vitesse pour passer de $V_{tp}$ à $V_2$:
8. Calculer l'incrément de vitesse $\Delta V_{t2}=V_2-V_{tp}$<br/>
9. Calculer la periode de la nouvelle orbite circulaire $T_2$<br/>
10. Effectuer la manoeuvre et intégrer sur toute la periode $T_2$
</b>
dv2=cap.u*(np.sqrt(aT/r1)-1)
T2=2*np.pi*np.sqrt(r2**3/(G*Mt))
print(dv2)
1020.9118348443955
cap.mvr(dv2,0) # Manoeuvre
---- 27, Nov 2024 | 08:59 ---- time= 0j 8h 23min 46s ---- Position--(/Terre/)------ u=3326.0949480561885 z=29629999.47788117 theta=539.9861901070234 Assiette=-0.01697917296869883 deg Incidence=0.0deg --------Parametres----------- beta=0.005 finesse=0.0
cap.run(dt=delta_t,ntmax=T2/delta_t) # Intégration pendant la periode orbitale T2
# On trace la trajectoire:
cap.plotraj('polar')
plt.ylim(0,40000)
---- 28, Nov 2024 | 03:52 ---- time= 1j 3h 16min 45s ---- Position--(/Terre/)------ u=3326.3925430848917 z=29611339.39998024 theta=900.3445898846404 Assiette=-0.01537070590702409 deg Incidence=0.0deg --------Parametres----------- beta=0.005 finesse=0.0 0-time | 1-r | 2-theta | 3-U | 4-Gamma | 5-Pdyn | 6-phi | 7-Acc | 8-Fl | 9-Alpha | 10-ref | 11-thetaL | 12-Ft | 13-Engine | 14-r2 | 15-theta2 | 16-Moon
(0.0, 40000.0)
On peut réaliser les simulations précédentes en utilisant un niveau supérieur de modélisation. La class Stage permet de spécifier les caractéristiques propulsives comme l'ISP, le débit massique de carburant $q_m$ et le paramètre constructif $k_s$ représentant le ratio entre la masse des structures et la masse d'ergols.
On va donc initialiser notre véhicule spatial sur la même orbite que précedemment.
Pour les paramètres propulsifs, nous allons d'abord estimer la masse $\delta m$ de carburant nécessaire pour réaliser la manoeuvre précédente.
11. Donner l'expression de la masse de carburant $\delta m$ à consommer pour fournir un incrément de vitesse $\Delta V$ et une masse initiale de carburant $m_e$.
</b>
$$ \delta m = M_i \left(1 - e^{\frac{-\Delta V}{g_0 ISP}} \right) $$et $M_i=m_s+m_e=m_e(k_s+1)$
ks=0.24
ISP=445
me=1000
dm=me*(ks+1)*(1-np.exp(-dv1/(g0*ISP)))
print("dm=",dm)
dm= 335.57169748575075
tm=dm/280
print(tm)
1.1984703481633956
On peut à présent initialiser notre objet Stage et réaliser la simulation: IC représente l'Indice Constructif, qm le débit massique du moteur et mc la masse de carburant présente.
cap=Stage(ISP=ISP,IC=ks,qm=280,mc=me,z0=zs,u0=us,gamma0=0)
delta_t=1
cap.theta=np.pi/2.64
print(cap)
---- 27, Nov 2024 | 00:35 ---- time= 0j 0h 0min 0s ---- Position--(/Terre/)------ u=5918.228711879594 z=5000000.0 theta=68.18181818181817 Assiette=0.0 deg Incidence=0.0deg ---- Propulsion Etage en cours ---- Indice propulsif (Ft/9.81)=100.40290088638194 Duree Propulsion (s): 3.5714285714285716 Moteur: Off ISP: 445 s ---- Masses ---- Charge Utile:1.0 kg Ergols :1000 kg Structures :240.0 kg Total :1241.0 kg IC : 0.24
On remarque que par défaut, le moteur est éteint. On peut donc réaliser une orbite sans rien faire comme dans la première partie:
cap.run(dt=delta_t,ntmax=T1/delta_t-1)
cap.plotraj('polar')
plt.ylim(0,20000)
---- 27, Nov 2024 | 03:57 ---- time= 0j 3h 21min 21s ---- Position--(/Terre/)------ u=5918.558815200403 z=4998891.5370050445 theta=428.1816710721171 Assiette=-0.0011967013571344601 deg Incidence=0.0deg ---- Propulsion Etage en cours ---- Indice propulsif (Ft/9.81)=100.40290088638194 Duree Propulsion (s): 3.5714285714285716 Moteur: Off ISP: 445 s ---- Masses ---- Charge Utile:1.0 kg Ergols :1000.0 kg Structures :240.0 kg Total :1241.0 kg IC : 0.24 0-time | 1-r | 2-theta | 3-U | 4-Gamma | 5-Pdyn | 6-phi | 7-Acc | 8-Fl | 9-Alpha | 10-ref | 11-thetaL | 12-Ft | 13-Engine | 14-r2 | 15-theta2 | 16-Moon
(0.0, 20000.0)
Maintenant nous allons réaliser la manoeuvre en allumant le moteur pendant le temps $t_m$ calculé précedemment. Attention, la précision d'intégration est très importante ici !! Il faudra donc adapter le pas de temps pour atteindre la précision voulue:
cap.engine_start()
cap.run(dt=delta_t/100,ntmax=100*tm/delta_t)
cap.engine_stop()
---- 27, Nov 2024 | 03:57 ---- time= 0j 3h 21min 22s ---- Position--(/Terre/)------ u=7298.726385783635 z=4998892.021014232 theta=428.22138329013904 Assiette=-0.007862478278657712 deg Incidence=0.0deg ---- Propulsion Etage en cours ---- Indice propulsif (Ft/9.81)=137.6795580110489 Duree Propulsion (s): 2.371428571428591 Moteur: On ISP: 445 s ---- Masses ---- Charge Utile:1.0 kg Ergols :664.0000000000055 kg Structures :240.0 kg Total :905.0000000000055 kg IC : 0.3614457831325272
Puis on réalise une periode complète sur la nouvelle orbite:
cap.run(dt=delta_t,ntmax=Ttrans/delta_t)
---- 27, Nov 2024 | 08:59 ---- time= 0j 8h 23min 46s ---- Position--(/Terre/)------ u=2299.933232676752 z=29725953.458026677 theta=607.9683114890074 Assiette=-0.22810039115558514 deg Incidence=0.0deg ---- Propulsion Etage en cours ---- Indice propulsif (Ft/9.81)=137.6795580110489 Duree Propulsion (s): 2.371428571428591 Moteur: Off ISP: 445 s ---- Masses ---- Charge Utile:1.0 kg Ergols :664.0000000000055 kg Structures :240.0 kg Total :905.0000000000055 kg IC : 0.3614457831325272
cap.plotraj('polar')
plt.ylim(0,40000)
0-time | 1-r | 2-theta | 3-U | 4-Gamma | 5-Pdyn | 6-phi | 7-Acc | 8-Fl | 9-Alpha | 10-ref | 11-thetaL | 12-Ft | 13-Engine | 14-r2 | 15-theta2 | 16-Moon
(0.0, 40000.0)
dm2=cap.m*(1-np.exp(-dv2/(g0*ISP)))
print(dm2)
188.71854711413872
tm2=dm2/280
print(tm2)
0.6739948111219239
cap.engine_start()
cap.run(dt=delta_t/100,ntmax=100*tm2/delta_t)
cap.engine_stop()
---- 27, Nov 2024 | 08:59 ---- time= 0j 8h 23min 46s ---- Position--(/Terre/)------ u=3332.90004087153 z=29725959.65803639 theta=607.971328650315 Assiette=-0.15639033528767246 deg Incidence=0.0deg ---- Propulsion Etage en cours ---- Indice propulsif (Ft/9.81)=174.36328015672893 Duree Propulsion (s): 1.691428571428599 Moteur: On ISP: 445 s ---- Masses ---- Charge Utile:1.0 kg Ergols :473.60000000000775 kg Structures :240.0 kg Total :714.6000000000085 kg IC : 0.5067567567567485
cap.run(dt=delta_t,ntmax=T2/delta_t)
---- 28, Nov 2024 | 03:52 ---- time= 1j 3h 16min 45s ---- Position--(/Terre/)------ u=3334.607024757439 z=29691356.4321656 theta=963.1511251119862 Assiette=-0.10858862805210982 deg Incidence=0.0deg ---- Propulsion Etage en cours ---- Indice propulsif (Ft/9.81)=174.36328015672893 Duree Propulsion (s): 1.691428571428599 Moteur: Off ISP: 445 s ---- Masses ---- Charge Utile:1.0 kg Ergols :473.60000000000775 kg Structures :240.0 kg Total :714.6000000000085 kg IC : 0.5067567567567485
cap.plotraj('polar')
plt.ylim(0,40000)
0-time | 1-r | 2-theta | 3-U | 4-Gamma | 5-Pdyn | 6-phi | 7-Acc | 8-Fl | 9-Alpha | 10-ref | 11-thetaL | 12-Ft | 13-Engine | 14-r2 | 15-theta2 | 16-Moon
(0.0, 40000.0)
On pourra refaire tous les calculs en changeant les caractéristiques propulsives (changer le moteur Vinci).
On pourra également essayer d'expliquer et d'interpréter les données du monitoring:
cap.monit(plt.figure(figsize=(12,12)))
0-time | 1-r | 2-theta | 3-U | 4-Gamma | 5-Pdyn | 6-phi | 7-Acc | 8-Fl | 9-Alpha | 10-ref | 11-thetaL | 12-Ft | 13-Engine | 14-r2 | 15-theta2 | 16-Moon
Pour se mettre directement en orbite autour du corps secondaire (CS), on doit injecter une capsule à la vitesse $V_{cs}+V_o$ avec $V_{cs}$ vitesse du corp secondaire par rapport au corps principal (CP):
$$ V_l=\sqrt{\dfrac{GM_t}{a_l}} $$et $V_o$ la vitesse de la sonde par rapport au corps secondaire:
$$ V_o=\sqrt{\dfrac{GM_l}{r_o}} $$Attention le corps secondaire se trouve initialement à la position $\theta=\pi/2$.
15. Placer une capsule en orbite circulaire autour du corps secondaire à 5000 km d'altitude et intégrer la trajectoire pendant 2 jours.
</b>
Par défaut le système CP/CS est le système Terre/Lune.
Ainsi dans le module SOLSTICE les parametres relatifs au corps principal (CP) sont notés Rt et Mt et ceux relatifs au corps secondaire (CS) sont notés Rl et Ml.
Le demi grand axe de l'orbite du CS autour du CP est noté al
# Corps principal:
CP='Terre'
# Corps secondaire:
CS='Lune'
cap=Capsule(body=CP)
cap.setmoon(CS)
# Altitude/corp secondaire
z2=5000e3
# Altitude / corp principal
z1=cap.al-cap.Rt+cap.Rl+z2
# Vitesse du corp secondaire / corp principal
Vl=np.sqrt(G*cap.Mt/cap.al)
# Vitesse / corp secondaire
V2=np.sqrt(G*cap.Ml/(cap.Rl+z2))
# Vitesse / corp principal:
V1=Vl+V2
#V1=np.sqrt(G*cap.Mt/(cap.al+cap.Rl+z2))
#cap=Stage(z0=z1,u0=V1,body=CP,gamma0=0,mc=4000,IC=0.2,ISP=445)
cap=Capsule(u=V1,z0=z1,body=CP)
cap.setmoon(CS)
cap.theta=np.pi/2
print(Vl,V2,V1)
print(cap)
1018.8195346412764 853.238361157138 1872.0578957984144 ---- 27, Nov 2024 | 00:36 ---- time= 0j 0h 0min 0s ---- Position--(/Terre/)------ u=1872.0578957984144 z=384356000.0 theta=90.0 Assiette=0.0 deg Incidence=0.0deg --------Parametres----------- beta=0.005 finesse=0.0
dt=1.
cap.run(dt=dt,ntmax=2*24*60*60/dt)
---- 29, Nov 2024 | 00:36 ---- time= 2j 0h 0min 1s ---- Position--(/Lune/)------ u=849.512656829577 z=4989568.287412709 theta=-95.21664837039606 Assiette=0.5876431477431445 deg Incidence=0.0deg --------Parametres----------- beta=0.005 finesse=0.0
Par défaut la fonction plotraj trace la trajectoire dans le référentiel du CP.
cap.plotraj('polar')
0-time | 1-r | 2-theta | 3-U | 4-Gamma | 5-Pdyn | 6-phi | 7-Acc | 8-Fl | 9-Alpha | 10-ref | 11-thetaL | 12-Ft | 13-Engine | 14-r2 | 15-theta2 | 16-Moon
Pour tracer la trajectoire dans le référentiel du CS il faut rajouter l'option ref=1:
cap.plotraj('polar',impref=1)
plt.ylim(0,7000)
0-time | 1-r | 2-theta | 3-U | 4-Gamma | 5-Pdyn | 6-phi | 7-Acc | 8-Fl | 9-Alpha | 10-ref | 11-thetaL | 12-Ft | 13-Engine | 14-r2 | 15-theta2 | 16-Moon
(0.0, 7000.0)
La flèche bleu indique le vecteur vitesse du CS par rapport au CP, la petite flèche brune indique la direction du CP.
On souhaite maintenant se rapprocher du corps secondaire et effectuer un transfert vers une orbite circulaire à $400$km de sa surface.
# La fonction e2m permet de récupérer la vitesse
# de la capsule par rapport au CS
ur2,ut2=cap.e2m()
r1=cap.r2
r2=cap.Rl+400e3
aT=(r1+r2)/2
dv1=ut2*(np.sqrt(r2/aT)-1)
Tt2=np.pi*np.sqrt(aT**3/(G*cap.Ml))
print(dv1)
-259.66448500210925
# Pour que la manoeuvre soit prise en compte dans le referentiel du CS on rajoute l'option ref=1
cap.mvr(abs(dv1),180,ref=1)
---- 29, Nov 2024 | 00:36 ---- time= 2j 0h 0min 1s ---- Position--(/Lune/)------ u=585.0085078744925 z=4989568.287412709 theta=-95.21664837039606 Assiette=1.380528543109958 deg Incidence=0.0deg --------Parametres----------- beta=0.005 finesse=0.0
cap.run(dt=dt,ntmax=Tt2/dt)
---- 29, Nov 2024 | 04:16 ---- time= 2j 3h 40min 33s ---- Position--(/Lune/)------ u=1876.2045751599574 z=379709.83281366853 theta=92.59004797770233 Assiette=-2.778647474271813 deg Incidence=0.0deg --------Parametres----------- beta=0.005 finesse=0.0
cap.plotraj('polar',impref=1)
plt.ylim(0,7000)
0-time | 1-r | 2-theta | 3-U | 4-Gamma | 5-Pdyn | 6-phi | 7-Acc | 8-Fl | 9-Alpha | 10-ref | 11-thetaL | 12-Ft | 13-Engine | 14-r2 | 15-theta2 | 16-Moon
(0.0, 7000.0)
ur2,ut2=cap.e2m()
dv2=ut2*(np.sqrt(aT/r1)-1)
T2=2*np.pi*np.sqrt(r2**3/(G*cap.Ml))
print(dv2)
-352.9430978216564
cap.mvr(abs(dv2),180,ref=1)
---- 29, Nov 2024 | 04:16 ---- time= 2j 3h 40min 33s ---- Position--(/Lune/)------ u=1522.111292055673 z=379709.83281366853 theta=92.59004797770233 Assiette=-2.6984716705123484 deg Incidence=0.0deg --------Parametres----------- beta=0.005 finesse=0.0
cap.run(dt=dt,ntmax=T2/dt)
---- 29, Nov 2024 | 06:44 ---- time= 2j 6h 8min 11s ---- Position--(/Lune/)------ u=1516.5569452649618 z=387804.43177902047 theta=97.09629312945185 Assiette=-2.702950248746436 deg Incidence=0.0deg --------Parametres----------- beta=0.005 finesse=0.0
cap.plotraj('polar',impref=1)
plt.ylim(0,2500)
0-time | 1-r | 2-theta | 3-U | 4-Gamma | 5-Pdyn | 6-phi | 7-Acc | 8-Fl | 9-Alpha | 10-ref | 11-thetaL | 12-Ft | 13-Engine | 14-r2 | 15-theta2 | 16-Moon
(0.0, 2500.0)
cap.run(dt=dt,ntmax=60*60*24*2/dt)
---- 01, Dec 2024 | 06:44 ---- time= 4j 6h 8min 12s ---- Position--(/Lune/)------ u=1595.379667717212 z=279156.945717287 theta=2.635872591001223 Assiette=-0.1492993680232374 deg Incidence=0.0deg --------Parametres----------- beta=0.005 finesse=0.0
On peut, en passant, jeter un oeil à la trajectoire dans le reférentiel du CP:
cap.plotraj('polar')
0-time | 1-r | 2-theta | 3-U | 4-Gamma | 5-Pdyn | 6-phi | 7-Acc | 8-Fl | 9-Alpha | 10-ref | 11-thetaL | 12-Ft | 13-Engine | 14-r2 | 15-theta2 | 16-Moon
Pour réaliser l'animation de la trajectoire on utilise la fonction anim en précisant le pas d'images à sauter (skip).
from IPython.display import Video
# Animation en prenant une image sur 1000
cap.anim(skip=1000)
0-time | 1-r | 2-theta | 3-U | 4-Gamma | 5-Pdyn | 6-phi | 7-Acc | 8-Fl | 9-Alpha | 10-ref | 11-thetaL | 12-Ft | 13-Engine | 14-r2 | 15-theta2 | 16-Moon 367.692 images zmax = 36604.441325556436 km
<Figure size 1440x1440 with 0 Axes>
Video('Rentree_Terre.mp4', width=512, height=512)
Par défaut, l'animation est réalisée dans le référentiel du CP. Pour avoir une animation dans le référentiel du CS on rajoute l'option ref=1
cap.anim(skip=1000,ref=1)
0-time | 1-r | 2-theta | 3-U | 4-Gamma | 5-Pdyn | 6-phi | 7-Acc | 8-Fl | 9-Alpha | 10-ref | 11-thetaL | 12-Ft | 13-Engine | 14-r2 | 15-theta2 | 16-Moon 367.692 images zmax = 36604.441325556436 km
<Figure size 1440x1440 with 0 Axes>
Video('Rentree_Terre_CS.mp4', width=512, height=512)