Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Симулятор ясной системы. Ключ на старт!

Anna | 16.06.2014 | нет комментариев
В первой части симулятора я описал правила игры и простейшую их реализацию.

Я признателен каждому кто оставил конструктивный комментарии первой версии. Это помогло мне оценить всю глубину задачи. Отдельное спасибо пользователям kahi4EthrilUri и lexasss

Теперь симулятор подрос. Все тела влияют друг на друга по всеобщим правилам, способ Эйлера ушел в прошлое, возникла вероятность выбирать системы для симуляции и т.д.

Настала пора двигаться дальше — к покорению просторов космоса управляемым агрегатом.

По траектории ясно
Что Ваш полет идет к концу
Мы помним Вас, скорбим и любим.
Ваш ЦУП.

Наша цель — коммунизм. Завод по производству ракет

Выходит, симулятор звездных систем Spacesim разрешает задавать исходное состояние системы и моделировать ее поведение.

Предположим сейчас, что у нас есть классическая безупречная одноступенчатая ракета ракета

Пускай ракета имеет сухую массу m,
в нее залито горючее массой mf
тяга мотора — z
и расход топлива — n
Пускай мотор имеет неограниченный источник и неограниченное число включений.

Представим, что наша ракета находится на поверхности планеты массой М и радиусом H. Нашей стержневой задачей будет выведение ракеты на круговую орбиту вокруг планеты.

heaven ahead

Перед запуском на круговую орбиту запустим нашу ракету вертикально вверх и понаблюдаем за ее движением.
На ракету действуют две силы:
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

сейчас легко дозволено рассчитать движение ракеты вертикально вверх под действием гравитации планеты:

Способом Эйлера:

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

Дальнейшим этапом будет доббавление Луны в систему и полет к ней.
Также в планах есть многоступенчатые ракеты.

Исходники — здесь

Источник: programmingmaster.ru
Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB