В первая часть симулятор, я описал правила игры и их простейшую реализацию.
Я благодарен всем, кто оставил конструктивные комментарии по первой версии.
Это помогло мне оценить глубину проблемы.
Особая благодарность пользователям кахи4 , Этрил , Ури И лексасс Теперь симулятор вырос.
Все тела влияют друг на друга по общим правилам, метод Эйлера ушел в прошлое, теперь можно выбирать системы для моделирования и т. д. Пришло время двигаться дальше – покорять просторы космоса с помощью управляемого транспортного средства.
Траектория ясна Что твой полет подходит к концу Мы помним вас, скорбим и любим вас.Ваш МЦК.
Пузыри
Наша цель – коммунизм.
Завод по производству ракет Итак, симулятор звездных систем Спейссим позволяет задать начальное состояние системы и смоделировать ее поведение.
Давайте теперь представим, что у нас есть классическая идеальная одноступенчатая ракета.
ракета Пусть ракета имеет сухую массу m, он наполнен топливом массой mf тяга двигателя - z и расход топлива - н Пусть у двигателя неограниченный ресурс и неограниченное количество запусков.
Предположим, что наша ракета находится на поверхности планеты массой М и радиусом Н.
Нашей основной задачей будет вывод ракеты на круговую орбиту вокруг планеты.
рай впереди
Прежде чем выйти на круговую орбиту, мы запустим нашу ракету вертикально вверх и понаблюдаем за ее движением.На ракету действуют две силы: 1. Тяга двигателя (вверх): F=n*z 2. Гравитация планеты (внизу): F = G*M*(m + mf)/r^2, m + mf — полная масса ракеты, r — расстояние от ракеты до центра планеты.
.
Далее будем считать всюду G = 1 Результирующая сила, действующая на ракету, будет равна: n * z - G*M*(m + mf)/r^2. Отсюда можно найти ускорение ракеты: a = n * z/(m + mf) - M/r^2 Теперь вы легко можете рассчитать движение ракеты вертикально вверх под действием гравитации планеты: Использование метода? Yler:
Метод Рунге-КуттыH=409.0 #Start level above sea t=0 m=2 #Mass of equipment mf=9 #Mass of Fuel M=600000 #Planet mass y=H + 1 #Initial position a=0 #accel v=0 #speed f=0 #engine accel n=1 #Fuel consumption z=40.0 #Fuel impulse cnt = 0 #Step count dt = .
1 maxy = 0 while(y > H and cnt < 300000000): if mf > 0: f = n*z/(m + mf) #Engine gives acceleration to mf -= dt*n #Fuel goes down else: f = 0 #Out of fuel a = f - M/y**2 #Total = engine - gravity v += dt*a #new speed y += dt*v #new altitude maxy = max(maxy, y) print("Step: ", cnt, " Height: ", y, " VSpeed: ", v) cnt += 1 print(dt ,maxy)
H=409.0 #Start level above sea
t=0
m=2 #Mass of equipment
mf=9 #Mass of Fuel
M=600000 #Planet mass
x=H + 1 #Initial position
a=0 #accel
v=0 #speed
f=0 #engine accel
n=1 #Fuel consumption
z=40.0 #Fuel impulse
cnt = 0 #Step count
dt = .
1
maxy = 0
def f(t, x, v):
global m,mf,n,z
if mf > 0:
f = n*z/(m + mf) #Engine gives acceleration to
else:
f = 0 #Out of fuel
a = f - M/x**2 #Total = engine - gravity
#We'll use Runge-Kutta method
return a #new speed
def g(t, x, v):
return v
while(x > H and cnt < 30000):
maxy = max(maxy, x)
k1 = dt * f(t, x, v)
q1 = dt * g(t, x, v)
k2 = dt * f(t + dt/2, x + q1/2, v + k1/2)
q2 = dt * g(t + dt/2, x + q1/2, v + k1/2)
k3 = dt * f(t + dt/2, x + q2/2, v + k2/2)
q3 = dt * g(t + dt/2, x + q2/2, v + k2/2)
k4 = dt * f(t + dt, x + q3, v + k3)
q4 = dt * g(t + dt, x + q3, v + k3)
v1 = v + (k1 + 2*k2 + 2*k3 + k4)/6
x1 = x + (q1 + 2*q2 + 2*q3 + q4)/6
print("Step: ", cnt,
" Height: ", x1,
" Speed: ", v1)
cnt += 1
t += dt
v = v1
x = x1
if mf > 0:
mf -= dt*n #Fuel goes down
print(dt ,maxy)
Как видите, результаты совпадают с большой точностью.
Собираем все это вместе
Итак, мы научились запускать реактивный двигатель и взлетать вертикально.Еще у нас есть симулятор из предыдущей части, в котором тела движутся под действием гравитационных сил относительно друг друга.
Давайте объединим их! Добавим в симулятор ракету.
Добавим в ракету бортовой компьютер, который работает по программе.
Для выхода на круговую орбиту будет действовать следующий алгоритм: 1. Запускаем двигатель и ракета начинает лететь вверх.
2. Выключите двигатель.
Ракета летит вверх по инерции 3. Поверните корпус ракеты на 90 градусов.
4. В тот момент, когда вертикальная скорость станет нулевой, включить двигатель.
5. Через небольшой промежуток времени заглушите двигатель.
А вот как выглядит реализация: class EarthOrbiter(Rocket):
def flightProgram(self):
#Take off and turn 90" right
if self.mode == 0:
self.engineOn()
self.mode = 1
if self.t > 12.0 and self.mode == 1:
self.engineOff()
self.setHead(90)
self.mode = 2
#Go to round orbit
if self.t > 20 and self.mode == 2:
self.engineOn()
self.mode = 3
if self.t >= 27 and self.mode == 3:
self.engineOff()
self.mode = 4
События в нашей ракете происходят в зависимости от времени полета и предыдущего состояния.
Бинго! Полет нормальный.
Траектория стабильна.
Вот короткое видео о первом полете: Видео полета 1 Видео полета 2 Полетим на Луну! Следующим шагом будет добавление Луны в систему и полет к ней.
Есть также планы по созданию многоступенчатых ракет. Исходники - здесь Update1: добавлен полет на Луну.
Добавлена возможность сажать ракеты на планеты.
Обновление2: добавлена возможность стыковки двух космических кораблей.
Теги: #развлечение #python #разработка игр
-
Хабрахрана И Культура Речи
19 Oct, 24 -
Оформление Резюме Для Иностранных Компаний
19 Oct, 24 -
Редакция №1. Клавиша Запуска
19 Oct, 24 -
Начались «Открытые» Брифинги Black Hat
19 Oct, 24 -
Дело Попова-Бабушкина Продолжает Жить
19 Oct, 24