Önceden küçük bir feragatname: Astronomi veya bu konuda herhangi bir kesin bilimi (BT bile değil) hiç çalışmadım, bu yüzden bu boşluğu kendi kendine eğitim ile doldurmaya çalışıyorum. Astronomi dikkatimi çeken alanlardan biri ve kendi kendine eğitim fikrim uygulamalı yaklaşıma yöneliyor. Yani, doğrudan - bu, zaman / ruh hali olduğunda rasgele üzerinde çalıştığım yörünge simülasyon modeli. Benim asıl amacım hareket halinde tam bir güneş sistemi oluşturmak ve diğer gezegenlere uzay aracı fırlatma planlamak için yeteneği.
Bu projeyi istediğiniz zaman alabilir ve eğlenceli deneyler yapabilirsiniz!
Güncelleme!!! (Nov10)
- hız artık uygun deltaV ve ek hareket vermek artık hızın toplam vektörünü hesaplıyor
- hareket halindeki birim nesnenin tüm kaynaklardan yerçekimi vektörlerini kontrol ettiğinde (ve çarpışma olup olmadığını kontrol ettiğinizde) istediğiniz kadar statik nesne yerleştirebilirsiniz.
- hesaplamaların performansını büyük ölçüde geliştirdi
- matplotlib'deki etkileşimli modun hesabına yönelik bir düzeltme. Bu sadece ipython için varsayılan seçenek gibi görünüyor. Düzenli python3 bu ifadeyi açıkça gerektirir.
Temel olarak, Dünya'nın yüzeyinden bir uzay aracını "başlatmak" ve giveMotion () aracılığıyla deltaV vektör düzeltmeleri yaparak Ay'a bir görev çizmek mümkündür. Sırada, uzay aracı yerçekimi destek manevrasını denerken, eş zamanlı hareket sağlamak için küresel zaman değişkenini uygulamaya çalışıyor.
İyileştirmeler için yorum ve öneriler her zaman bekleriz!
Python3'te matplotlib kütüphanesi ile yapıldı
import matplotlib.pyplot as plt
import math
plt.ion()
G = 6.673e-11 # gravity constant
gridArea = [0, 200, 0, 200] # margins of the coordinate grid
gridScale = 1000000 # 1 unit of grid equals 1000000m or 1000km
plt.clf() # clear plot area
plt.axis(gridArea) # create new coordinate grid
plt.grid(b="on") # place grid
class Object:
_instances = []
def __init__(self, name, position, radius, mass):
self.name = name
self.position = position
self.radius = radius # in grid values
self.mass = mass
self.placeObject()
self.velocity = 0
Object._instances.append(self)
def placeObject(self):
drawObject = plt.Circle(self.position, radius=self.radius, fill=False, color="black")
plt.gca().add_patch(drawObject)
plt.show()
def giveMotion(self, deltaV, motionDirection, time):
if self.velocity != 0:
x_comp = math.sin(math.radians(self.motionDirection))*self.velocity
y_comp = math.cos(math.radians(self.motionDirection))*self.velocity
x_comp += math.sin(math.radians(motionDirection))*deltaV
y_comp += math.cos(math.radians(motionDirection))*deltaV
self.velocity = math.sqrt((x_comp**2)+(y_comp**2))
if x_comp > 0 and y_comp > 0: # calculate degrees depending on the coordinate quadrant
self.motionDirection = math.degrees(math.asin(abs(x_comp)/self.velocity)) # update motion direction
elif x_comp > 0 and y_comp < 0:
self.motionDirection = math.degrees(math.asin(abs(y_comp)/self.velocity)) + 90
elif x_comp < 0 and y_comp < 0:
self.motionDirection = math.degrees(math.asin(abs(x_comp)/self.velocity)) + 180
else:
self.motionDirection = math.degrees(math.asin(abs(y_comp)/self.velocity)) + 270
else:
self.velocity = self.velocity + deltaV # in m/s
self.motionDirection = motionDirection # degrees
self.time = time # in seconds
self.vectorUpdate()
def vectorUpdate(self):
self.placeObject()
data = []
for t in range(self.time):
motionForce = self.mass * self.velocity # F = m * v
x_net = 0
y_net = 0
for x in [y for y in Object._instances if y is not self]:
distance = math.sqrt(((self.position[0]-x.position[0])**2) +
(self.position[1]-x.position[1])**2)
gravityForce = G*(self.mass * x.mass)/((distance*gridScale)**2)
x_pos = self.position[0] - x.position[0]
y_pos = self.position[1] - x.position[1]
if x_pos <= 0 and y_pos > 0: # calculate degrees depending on the coordinate quadrant
gravityDirection = math.degrees(math.asin(abs(y_pos)/distance))+90
elif x_pos > 0 and y_pos >= 0:
gravityDirection = math.degrees(math.asin(abs(x_pos)/distance))+180
elif x_pos >= 0 and y_pos < 0:
gravityDirection = math.degrees(math.asin(abs(y_pos)/distance))+270
else:
gravityDirection = math.degrees(math.asin(abs(x_pos)/distance))
x_gF = gravityForce * math.sin(math.radians(gravityDirection)) # x component of vector
y_gF = gravityForce * math.cos(math.radians(gravityDirection)) # y component of vector
x_net += x_gF
y_net += y_gF
x_mF = motionForce * math.sin(math.radians(self.motionDirection))
y_mF = motionForce * math.cos(math.radians(self.motionDirection))
x_net += x_mF
y_net += y_mF
netForce = math.sqrt((x_net**2)+(y_net**2))
if x_net > 0 and y_net > 0: # calculate degrees depending on the coordinate quadrant
self.motionDirection = math.degrees(math.asin(abs(x_net)/netForce)) # update motion direction
elif x_net > 0 and y_net < 0:
self.motionDirection = math.degrees(math.asin(abs(y_net)/netForce)) + 90
elif x_net < 0 and y_net < 0:
self.motionDirection = math.degrees(math.asin(abs(x_net)/netForce)) + 180
else:
self.motionDirection = math.degrees(math.asin(abs(y_net)/netForce)) + 270
self.velocity = netForce/self.mass # update velocity
traveled = self.velocity/gridScale # grid distance traveled per 1 sec
self.position = (self.position[0] + math.sin(math.radians(self.motionDirection))*traveled,
self.position[1] + math.cos(math.radians(self.motionDirection))*traveled) # update pos
data.append([self.position[0], self.position[1]])
collision = 0
for x in [y for y in Object._instances if y is not self]:
if (self.position[0] - x.position[0])**2 + (self.position[1] - x.position[1])**2 <= x.radius**2:
collision = 1
break
if collision != 0:
print("Collision!")
break
plt.plot([x[0] for x in data], [x[1] for x in data])
Earth = Object(name="Earth", position=(50.0, 50.0), radius=6.371, mass=5.972e24)
Moon = Object(name="Moon", position=(100.0, 100.0), radius=1.737, mass = 7.347e22) # position not to real scale
Craft = Object(name="SpaceCraft", position=(49.0, 40.0), radius=1, mass=1.0e4)
Craft.giveMotion(deltaV=8500.0, motionDirection=100, time=130000)
Craft.giveMotion(deltaV=2000.0, motionDirection=90, time=60000)
plt.show(block=True)
Nasıl çalışır
Her şey iki şeye kadar kaynar:
Earth = Object(name="Earth", position=(50.0, 50.0), radius=6.371, mass=5.972e24)
Izgara üzerindeki konum parametreleriyle (1 birim ızgara varsayılan olarak 1000km'dir, ancak bu da değiştirilebilir), ızgara birimlerinde yarıçap ve kg cinsinden kütle gibi nesne oluşturma .- Nesneye
Craft.giveMotion(deltaV=8500.0, motionDirection=100, time=130000)
açık bir şekilde deltaV vermek gibiCraft = Object(...)
, ilk noktada daha önce belirtildiği gibi yaratılması gerekir . Buradaki parametrelerdeltaV
m / s cinsindendir (şimdilik ivmenin anlık olduğunu unutmayın),motionDirection
deltaV'ın derece cinsinden yönüdür (mevcut konumdan nesnenin etrafında 360 derece daire hayal edin, bu nedenle yön o dairenin üzerindeki bir noktadır) ve son olarak parametretime
kaç saniye sonra nesnenin deltaV itme yörünge izlenecektir. Sonraki öncekiningiveMotion()
son konumundan başlayarakgiveMotion()
.
Sorular:
- Bu yörüngeleri hesaplamak için geçerli bir algoritma mı?
- Yapılacak belirgin iyileştirmeler nelerdir?
- Her saniye için vektörleri ve konumları yeniden hesaplamak gerekmeyebileceğinden, hesaplamaları optimize edecek "timeScale" değişkenini göz önünde bulunduruyorum. Nasıl uygulanması gerektiğine dair herhangi bir düşünce ya da genellikle iyi bir fikir mi? (gelişmiş performansa karşı doğruluk kaybı)
Temel olarak amacım konuyla ilgili bir tartışma başlatmak ve nereye götürdüğünü görmek. Ve mümkünse, yeni ve ilginç bir şey öğrenin (veya daha iyisi - öğretin).
Denemekten çekinmeyin!
Kullanmayı deneyin:
Earth = Object(name="Earth", position=(50.0, 100.0), radius=6.371, mass=5.972e24)
Moon = Object(name="Moon", position=(434.0, 100.0), radius=1.737, mass = 7.347e22)
Craft = Object(name="SpaceCraft", position=(43.0, 100.0), radius=1, mass=1.0e4)
Craft.giveMotion(deltaV=10575.0, motionDirection=180, time=322000)
Craft.giveMotion(deltaV=400.0, motionDirection=180, time=50000)
İki yanıkla - Dünya yörüngesinde bir ilerleme ve Ay yörüngesinde bir retrograd, kararlı Ay yörüngesine ulaştım. Bunlar teorik olarak beklenen değerlere yakın mı?
Önerilen egzersiz: 3 yanıkta deneyin - Dünya yüzeyinden kararlı Dünya yörüngesi, Ay'a ulaşmak için yanmayı ilerletin, Ay çevresindeki yörüngeyi stabilize etmek için yanmayı retrograd yapın. Ardından deltaV'ı en aza indirmeye çalışın.
Not: Kodu python3 sözdizimine aşina olmayanlar için kapsamlı yorumlarla güncellemeyi planlıyorum.