A continuació et facilito un enllaç on apareixen tots els codigs de tots els Chapters: Codig dels 12 chapters.
En que consisteix el Chapter 6: Aquest projecte tracta sobre la simulació de la trajectòria de retorn lliure proposada per a la missió Apollo 8 utilitzant el mòdul de dibuix Python anomenat "turtle". La missió Apollo 8 va ser la primera missió tripulada a orbitar la Lluna i la trajectòria de retorn lliure era un concepte crucial per a la seguretat de la missió. Aquest projecte simula aquest tipus de trajectòria en un entorn 2D per facilitar la comprensió de com funciona i com s'ha utilitzat en missions com la de Apollo 8. El projecte consta de definir les condicions inicials, calcular les posicions intermèdia i final, i finalment dibuixar la trajectòria en si. Tot i que aquest és un enfocament simplificat, proporciona una bona base per entendre el concepte imperceptible i el paper que juga en les trajectòries de les naus espacials.
Biblioteca Turtle.Els 4 codis que té el Chapter 6:
import time ------ # Importem el mòdul time per poder utilitzar la funció sleep. import random import turtle SA_X = 600 # Definim la longitud de l'àrea de cerca. SA_Y = 480 # Definim l'alçada de l'àrea de cerca. TRACK_SPACING = 40 # Definim l'espaiat entre les passes de la cerca. # Inicialitzem la pantalla i definim les seves dimensions. screen = turtle.Screen() screen.setup(width=SA_X, height=SA_Y) turtle.resizemode('user') screen.title("Search Pattern") # Generem una posició aleatòria per al mariner. rand_x = random.randint(0, int(SA_X / 2)) * random.choice([-1, 1]) rand_y = random.randint(0, int(SA_Y / 2)) * random.choice([-1, 1]) # Carreguem les imatges per al mariner i l'helicòpter. seaman_image = 'seaman.gif' screen.addshape(seaman_image) copter_image_left = 'helicopter_left.gif' copter_image_right = 'helicopter_right.gif' screen.addshape(copter_image_left) screen.addshape(copter_image_right) # Instanciem el mariner. seaman = turtle.Turtle(seaman_image) seaman.hideturtle() seaman.penup() seaman.setpos(rand_x, rand_y) seaman.showturtle() # Instanciem l'helicòpter. turtle.shape(copter_image_right) turtle.hideturtle() turtle.pencolor('black') turtle.penup() turtle.setpos(-(int(SA_X / 2) - TRACK_SPACING), int(SA_Y / 2) - TRACK_SPACING) turtle.showturtle() turtle.pendown() # Executem el patró de cerca i anunciem el descobriment del mariner. for i in range(int(SA_Y / TRACK_SPACING)): turtle.fd(SA_X - TRACK_SPACING * 2) turtle.rt(90) turtle.fd(TRACK_SPACING / 2) turtle.rt(90) turtle.shape(copter_image_left) turtle.fd(SA_X - TRACK_SPACING * 2) turtle.lt(90) turtle.fd(TRACK_SPACING / 2) turtle.lt(90) turtle.shape(copter_image_right) # Comprovem si l'helicòpter està prou a prop del mariner. if turtle.ycor() - seaman.ycor() <= 10: turtle.write(" Seaman found!", align='left', font=("Arial", 15, 'normal', 'bold', 'italic')) time.sleep(3) # Si el trobem, aturem la cerca. break
La simulació implica un mariner (representat per una tortuga amb una imatge de mariner) i un helicòpter (representat per una tortuga amb una imatge d'helicòpter). L'helicòpter es mou en un patró de ziga-zaga per la zona de cerca, mentre el mariner roman en una posició aleatòria dins la zona de cerca.
El patró de cerca es implementa utilitzant un bucle que es repeteix un cert nombre de vegades (determinat per l'alçada de la zona de cerca dividida per la distància entre pistes). En cada iteracció del bucle, l'helicòpter es mou cap endavant per l'amplada de la zona de cerca menys dues vegades la distància entre pistes, gira cap a la dreta per 90 graus, es mou cap endavant per la meitat de la distància entre pistes, gira cap a l'esquerra per 90 graus i es mou cap endavant per la meitat de la distància entre pistes. Aquest patró es repeteix dues vegades en cada iteracció del bucle.
Durant cada iteracció del bucle, l'helicòpter verifica si la seva coordenada (y) està a menys de 10 unitats de la coordenada (y) del mariner. Si ho és, l'helicòpter escriu un missatge a la pantalla anunciant la trobada del mariner i després dorm durant 3 segons. El bucle llavors es trenca, acabant la simulació.
Imatges utilitzades:
"""gravity_assist_intersecting.py Moon and ship cross orbits and moon slows and turns ship. Credit: Eric T. Mortenson """ from turtle import Shape, Screen, Turtle, Vec2D as Vec import turtle import math import sys # User input: G = 8 # Gravitational constant used for the simulation. NUM_LOOPS = 7000 # Number of time steps in simulation. Ro_X = -152.18 # Ship starting position x coordinate. Ro_Y = 329.87 # Ship starting position y coordinate. Vo_X = 423.10 # Ship translunar injection velocity x component. Vo_Y = -512.26 # Ship translunar injection velocity y component. MOON_MASS = 1_250_000 class GravSys(): """Runs a gravity simulation on n-bodies.""" def __init__(self): self.bodies = [] self.t = 0 self.dt = 0.001 def sim_loop(self): """Loop bodies in a list through time steps.""" for index in range(NUM_LOOPS): # stops simulation after while self.t += self.dt for body in self.bodies: body.step() class Body(Turtle): """Celestial object that orbits and projects gravity field.""" def __init__(self, mass, start_loc, vel, gravsys, shape): super().__init__(shape=shape) self.gravsys = gravsys self.penup() self.mass=mass self.setpos(start_loc) self.vel = vel gravsys.bodies.append(self) self.pendown() # uncomment to draw path behind object def acc(self): """Calculate combined force on body and return vector components.""" a = Vec(0,0) for body in self.gravsys.bodies: if body != self: r = body.pos() - self.pos() a += (G * body.mass / abs(r)**3) * r # units dist/time^2 return a def step(self): """Calculate position, orientation, and velocity of a body.""" dt = self.gravsys.dt a = self.acc() self.vel = self.vel + dt * a xOld, yOld = self.pos() # for orienting ship self.setpos(self.pos() + dt * self.vel) xNew, yNew = self.pos() # for orienting ship if self.gravsys.bodies.index(self) == 1: # the CSM dir_radians = math.atan2(yNew-yOld,xNew-xOld) # for orienting ship dir_degrees = dir_radians * 180 / math.pi # for orienting ship self.setheading(dir_degrees+90) # for orienting ship def main(): # Setup screen screen = Screen() screen.setup(width = 1.0, height = 1.0) # for fullscreen screen.bgcolor('black') screen.title("Gravity Assist Example") # Instantiate gravitational system gravsys = GravSys() # Instantiate Planet image_moon = 'moon_27x27.gif' screen.register_shape(image_moon) moon = Body(MOON_MASS, (-250, 0), Vec(500, 0), gravsys, image_moon) moon.pencolor('gray') # Build command-service-module (csm) shape csm = Shape('compound') cm = ((0, 30), (0, -30), (30, 0)) csm.addcomponent(cm, 'red', 'red') sm = ((-60,30), (0, 30), (0, -30), (-60, -30)) csm.addcomponent(sm, 'red', 'black') nozzle = ((-55, 0), (-90, 20), (-90, -20)) csm.addcomponent(nozzle, 'red', 'red') screen.register_shape('csm', csm) # Instantiate Apollo 8 CSM turtle ship = Body(1, (Ro_X, Ro_Y), Vec(Vo_X, Vo_Y), gravsys, "csm") ship.shapesize(0.2) ship.color('red') # path color ship.getscreen().tracer(1, 0) ship.setheading(90) gravsys.sim_loop() if __name__=='__main__': main()
Aquest és el codi d'un simulador de física newtoniana en 2 dimensions, on s'il·lustra el concepte d'assistència gravitatòria utilitzant un objecte "naus espacials" i un objecte "lluna". El codi està escrit en Python i utilitza la biblioteca turtle per a la visualització gràfica.
La funció main és l'entrada al programa i on es creen i configuren tots els objectes i es crida a la simulació.
1. S'inicialitza la pantalla amb screen = Screen(). S'estableix el fons en negre i el títol en "Gravity Assist Example".
2. Es crea el sistema gravitatori amb gravity_system = GravSys().
3. Es crea la lluna amb moon = Body(MOON_MASS, ...). S'especifica la massa, la posició inicial, la velocitat inicial i el sistema gravitatori al qual pertany. També s'especifica la forma de la lluna utilitzant una imatge.
4. Es crea la nau espacial amb ship = Body(1, ...). S'especifica la massa, la posició inicial, la velocitat inicial i el sistema gravitatori al qual pertany. També s'especifica la forma de la nau espacial utilitzant una forma composta definida a la biblioteca turtle.
5. Finalment, es crida a la simulació amb gravity_system.sim_loop().
La classe GravSys representa el sistema gravitatori i conté una llista d'objectes que interaccionen entre ells. La classe Body representa un objecte que interacciona amb altres objectes del sistema gravitatori. Té atributs com la massa, la posició, la velocitat i el sistema gravitatori al qual pertany. A més, implementa el càlcul de l'acceleració deguda a la interacció gravitatòria amb altres objectes.
En resum, aquest codi il·lustra el concepte d'assistència gravitatòria utilitzant un objecte "naus espacials" i un objecte "lluna" en un entorn de simulació física newtoniana en 2 dimensions.
Imatges utilitzades:
"""gravity_assist_stationary.py Moon approaches stationary ship which is swung around and flung away. Credit: Eric T. Mortenson """ from turtle import Shape, Screen, Turtle, Vec2D as Vec import turtle import math # User input: G = 8 # Gravitational constant used for the simulation. NUM_LOOPS = 4100 # Number of time steps in simulation. Ro_X = 0 # Ship starting position x coordinate. Ro_Y = -50 # Ship starting position y coordinate. Vo_X = 0 # Ship velocity x component. Vo_Y = 0 # Ship velocity y component. MOON_MASS = 1_250_000 class GravSys(): """Runs a gravity simulation on n-bodies.""" def __init__(self): self.bodies = [] self.t = 0 self.dt = 0.001 def sim_loop(self): """Loop bodies in a list through time steps.""" for _ in range(NUM_LOOPS): self.t += self.dt for body in self.bodies: body.step() class Body(Turtle): """Celestial object that orbits and projects gravity field.""" def __init__(self, mass, start_loc, vel, gravsys, shape): super().__init__(shape=shape) self.gravsys = gravsys self.penup() self.mass=mass self.setpos(start_loc) self.vel = vel gravsys.bodies.append(self) self.pendown() # uncomment to draw path behind object def acc(self): """Calculate combined force on body and return vector components.""" a = Vec(0,0) for body in self.gravsys.bodies: if body != self: r = body.pos() - self.pos() a += (G * body.mass / abs(r)**3) * r # units dist/time^2 return a def step(self): """Calculate position, orientation, and velocity of a body.""" dt = self.gravsys.dt a = self.acc() self.vel = self.vel + dt * a xOld, yOld = self.pos() # for orienting ship self.setpos(self.pos() + dt * self.vel) xNew, yNew = self.pos() # for orienting ship if self.gravsys.bodies.index(self) == 1: # the CSM dir_radians = math.atan2(yNew-yOld,xNew-xOld) # for orienting ship dir_degrees = dir_radians * 180 / math.pi # for orienting ship self.setheading(dir_degrees+90) # for orienting ship def main(): # Setup screen screen = Screen() screen.setup(width = 1.0, height = 1.0) # for fullscreen screen.bgcolor('black') screen.title("Gravity Assist Example") # Instantiate gravitational system gravsys = GravSys() # Instantiate Planet image_moon = 'moon_27x27.gif' screen.register_shape(image_moon) moon = Body(MOON_MASS, (500, 0), Vec(-500, 0), gravsys, image_moon) moon.pencolor('gray') # Build command-service-module (csm) shape csm = Shape('compound') cm = ((0, 30), (0, -30), (30, 0)) csm.addcomponent(cm, 'red', 'red') sm = ((-60,30), (0, 30), (0, -30), (-60, -30)) csm.addcomponent(sm, 'red', 'black') nozzle = ((-55, 0), (-90, 20), (-90, -20)) csm.addcomponent(nozzle, 'red', 'red') screen.register_shape('csm', csm) # Instantiate Apollo 8 CSM turtle ship = Body(1, (Ro_X, Ro_Y), Vec(Vo_X, Vo_Y), gravsys, "csm") ship.shapesize(0.2) ship.color('red') # path color ship.getscreen().tracer(1, 0) ship.setheading(90) gravsys.sim_loop() if __name__=='__main__': main()
Aquest és un altre de simulació de física newtoniana en 2 dimensions que il·lustra el concepte d'assistència gravitatòria utilitzant un objecte "naus espacials" i un objecte "lluna". A diferència del codi anterior, en aquest cas la lluna s'aproxima a una nau espacial que està en repòs i la fa girar i allunyar. El codi està escrit en Python i utilitza la biblioteca turtle per a la visualització gràfica.
La funció main és l'entrada al programa i on es creen i configuren tots els objectes i es crida a la simulació.
1. S'inicialitza la pantalla amb screen = Screen(). S'estableix el fons en negre i el títol en "Gravity Assist Example".
2. Es crea el sistema gravitatori amb gravity_system = GravSys().
3. Es crea la lluna amb moon = Body(MOON_MASS, ...). S'especifica la massa, la posició inicial, la velocitat inicial i el sistema gravitatori al qual pertany. També s'especifica la forma de la lluna utilitzant una imatge.
4. Es crea la nau espacial amb ship = Body(1, ...). S'especifica la massa, la posició inicial, la velocitat inicial i el sistema gravitatori al qual pertany. També s'especifica la forma de la nau espacial utilitzant una forma composta definida a la biblioteca turtle.
5. Finalment, es crida a la simulació amb gravity_system.sim_loop().
La classe GravSys representa el sistema gravitatori i conté una llista d'objectes que interaccionen entre ells. La classe Body representa un objecte que interacciona amb altres objectes del sistema gravitatori. Té atributs com la massa, la posició, la velocitat i el sistema gravitatori al qual pertany. A més, implementa el càlcul de l'acceleració deguda a la interacció gravitatòria amb altres objectes.
En resum, aquest codi il·lustra el concepte d'assistència gravitatòria utilitzant un objecte "naus espacials" i un objecte "lluna" en un entorn de simulació física newtoniana en 2 dimensions. En aquest cas, la lluna s'aproxima a una nau espacial que està en repòs i la fa girar i allunyar.
Imatges utilitzades:
from turtle import Shape, Screen, Turtle, Vec2D as Vec from turtle import Shape, Screen, Turtle, Vec2D as Vec # User input: G = 8 # Gravitational constant used for the simulation. NUM_LOOPS = 4100 # Number of time steps in the simulation. Ro_X = 0 # Ship starting position x coordinate. Ro_Y = -85 # Ship starting position y coordinate. Vo_X = 485 # Ship translunar injection velocity x component. Vo_Y = 0 # Ship translunar injection velocity y component. class GravSys(): """Runs a gravity simulation on n-bodies.""" def __init__(self): self.bodies = [] self.t = 0 self.dt = 0.001 def sim_loop(self): """Loop bodies in a list through time steps.""" for _ in range(NUM_LOOPS): # Stops simulation after capsule splashdown. self.t += self.dt for body in self.bodies: body.step() class Body(Turtle): """Celestial object that orbits and projects gravity field.""" def __init__(self, mass, start_loc, vel, gravsys, shape): super().__init__(shape=shape) self.gravsys = gravsys self.penup() self.mass = mass self.setpos(start_loc) self.vel = vel gravsys.bodies.append(self) #self.resizemode("user") #self.pendown() # Uncomment to draw path behind object. def acc(self): """Calculate combined force on body and return vector components.""" a = Vec(0, 0) for body in self.gravsys.bodies: if body != self: r = body.pos() - self.pos() a += (G * body.mass / abs(r)**3) * r # Units: dist/time^2. return a def step(self): """Calculate position, orientation, and velocity of a body.""" dt = self.gravsys.dt a = self.acc() self.vel = self.vel + dt * a self.setpos(self.pos() + dt * self.vel) if self.gravsys.bodies.index(self) == 2: # Index 2 = CSM. rotate_factor = 0.0006 self.setheading((self.heading() - rotate_factor * self.xcor())) if self.xcor() < -20: self.shape('arrow') self.shapesize(0.5) self.setheading(105) def main(): # Setup screen screen = Screen() screen.setup(width=1.0, height=1.0) # For fullscreen. screen.bgcolor('black') screen.title("Apollo 8 Free Return Simulation") # Instantiate gravitational system gravsys = GravSys() # Instantiate Earth turtle image_earth = 'earth_100x100.gif' screen.register_shape(image_earth) earth = Body(1000000, (0, -25), Vec(0, -2.5), gravsys, image_earth) earth.pencolor('white') earth.getscreen().tracer(0, 0) # So csm polys won't show while drawing. # Instantiate moon turtle image_moon = 'moon_27x27.gif' screen.register_shape(image_moon) moon = Body(32000, (344, 42), Vec(-27, 147), gravsys, image_moon) moon.pencolor('gray') # Build command-service-module(csm)shape csm = Shape('compound') cm = ((0, 30), (0, -30), (30, 0)) csm.addcomponent(cm, 'white', 'white') # Silver and red are also good. sm = ((-60, 30), (0, 30), (0, -30), (-60, -30)) csm.addcomponent(sm, 'white', 'black') nozzle = ((-55, 0), (-90, 20), (-90, -20)) csm.addcomponent(nozzle, 'white', 'white') screen.register_shape('csm', csm) # Instantiate Apollo 8 CSM turtle ship = Body(1, (Ro_X, Ro_Y), Vec(Vo_X, Vo_Y), gravsys, 'csm') ship.shapesize(0.2) ship.color('white') # Path color. Silver and red are also good. ship.getscreen().tracer(1, 0) ship.setheading(90) gravsys.sim_loop() if __name__ == '__main__': main()
Aquest és un altre exemple de simulació de física newtoniana en 2 dimensions que il·lustra el concepte d'una missió Apollo 8 de retorn lliure utilitzant un objecte "naus espacials", un objecte "Terra" i un objecte "Lluna". El codi està escrit en Python i utilitza la biblioteca turtle per a la visualització gràfica.
La funció main és l'entrada al programa i on es creen i configuren tots els objectes i es crida a la simulació.
1. S'inicialitza la pantalla amb screen = Screen(). S'estableix el fons en negre i el títol en "Apollo 8 Free Return Simulation".
2. Es crea el sistema gravitatori amb gravity_system = GravSys().
3. Es crea la Terra amb earth = Body(1000000, (0, -25), Vec(0, -2.5), gravsys, image_earth). S'especifica la massa, la posició inicial, la velocitat inicial i el sistema gravitatori al qual pertany. També s'especifica la forma de la Terra utilitzant una imatge.
4. Es crea la Lluna amb moon = Body(32000, (344, 42), Vec(-27, 147), gravsys, image_moon). S'especifica la massa, la posició inicial, la velocitat inicial i el sistema gravitatori al qual pertany. També s'especifica la forma de la Lluna utilitzant una imatge.
5. Es crea la nau espacial amb ship = Body(1, (Ro_X, Ro_Y), Vec(Vo_X, Vo_Y), gravsys, 'csm'). S'especifica la massa, la posició inicial, la velocitat inicial i el sistema gravitatori al qual pertany. També s'especifica la forma de la nau espacial utilitzant una forma composta definida a la biblioteca turtle.
6. Finalment es crida a la simulació amb gravity_system.sim_loop().
La classe GravSys representa el sistema gravitatori i conté una llista d'objectes que interaccionen entre ells. La classe Body representa un objecte que interacciona amb altres objectes del sistema gravitatori. Té atributs com la massa, la posició, la velocitat i el sistema gravitatori al qual pertany. A més, implementa el càlcul de l'acceleració deguda a la interacció gravitatòria amb altres objectes.
En aquest exemple, la nau espacial gira lleugerament en la seva direcció de moviment cada cop que el seu eix x és inferior a -20. Això es fa per simular la rotació de la nau espacial durant el viatge.
En resum, aquest codi il·lustra el concepte d'una missió Apollo 8 de retorn lliure utilitzant un objecte "naus espacials", un objecte "Terra" i un objecte "Lluna" en un entorn de simulació física newtoniana en 2 dimensions..
Imatges utilitzades: