Как решить задачу двух тел в системе ECI с помощью численного интегрирования?

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

р ¨ "=" мю р 3 р

Как мне это сделать и как мне использовать это для вывода траектории в MATLAB?

+1 У нас нет тега Matlab, но у нас есть тег Python, и они достаточно похожи на языки (на первый взгляд), так что, надеюсь, этот тег привлечет программистов обоих. Я добавил стандарт форматирования MathJax для большинства сайтов Stack Exchange.
Я опубликовал ответ, используя бесплатный, открытый, дружелюбный, популярный, забавный и хорошо документированный Python. Возможно, это может помочь вам попытаться двигаться к нему и отказаться от дорогого и черного ящика MATLAB.

Ответы (1)

Есть несколько способов сделать это. Самый простой и простой способ — разбить его на два набора, включив скорость в качестве переменной и решить вместе.

Вместо одного дифференциального уравнения второго порядка

р ¨ "=" мю р 3 р

Мы можем решить следующую пару дифференциальных уравнений первого порядка параллельно

в ˙ "=" мю р 3 р
р ˙ "=" в

используя различные простые методы, включая стандартные библиотеки или самодельные реализации Рунге-Кутта, включая мой любимый простой RK4/5 с переменным размером шага .

Замечательно и по-настоящему познавательно написать код один раз для себя и сначала оценить задачу, прежде чем использовать стандартные библиотеки.

Чтобы узнать больше об ошибках с использованием решателей дифференциальных уравнений и о том, как проверить их самостоятельно, см. мой вопрос в Math SE: нужно понять лучшую точность решения ODE по сравнению с численной точностью (что я должен был задать в Computational Science SE )

Для целей программирования вы можете написать р / р 3 какr * (r**2).sum()**-1.5

Из этого ответа вы можете увидеть 2D-реализацию, использующую не только монополь 1 / р 2 гравитационный член, но дополнительный квадруполь Дж 2 термин для обозначения сплюснутой формы и поля Земли. Подробнее об этом см. в этом ответе на проблему с получением прямоугольных составляющих ускорения спутника на орбите вокруг Земли с учетом J2.

См. также аналогичное решение в этом ответе на Как определить орбиту спутника для обнаружения столкновения? .

Кроме того, вы можете подумать о том, чтобы обойтись без единиц измерения, используя мю "=" 1 и период Т "=" 2 π и большая полуось а "=" 1 . Некоторые интеграторы справятся с этим немного лучше.

Синяя линия верна, красная линия имеет J2 в десять раз больше реального значения, чтобы показать преувеличенную прецессию апсид для развлечения.

апсидальная прецессия с нормальной и в 10 раз более сильной J2

def deriv(X, t):

    x, v = X.reshape(2, -1)

    acc0  = -GMe * x * ((x**2).sum())**-1.5
    acc2  = -1.5 * GMe * J2 * Re**2 * x * ((x**2).sum())**-2.5

    return np.hstack([v, acc0 + acc2])


import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint as ODEint

# David Hammen's nice table https://physics.stackexchange.com/a/141981/83380
# See http://www.iag-aig.org/attach/e354a3264d1e420ea0a9920fe762f2a0/51-groten.pdf
# https://en.wikipedia.org/wiki/Geopotential_model#The_deviations_of_Earth.27s_gravitational_field_from_that_of_a_homogeneous_sphere

GMe = 3.98600418E+14  # m^3 s^-2
J2e = 1.08262545E-03  # unitless
Re  = 6378136.3 # meters

X0 = np.hstack([6778000.0, 0.0, 0.0, 10000.])  # x, y, vx, vy

time = np.arange(0, 300001, 100)

J2 = J2e  # correct J2
answerJ2, info = ODEint(deriv, X0, time, full_output=True)

J2 = 10*J2e # 10x larger J2
answer10xJ2, info = ODEint(deriv, X0, time, full_output=True)

if True:
    plt.figure()
    x, y = answerJ2.T[:2]
    plt.plot(x, y, '-b')
    x, y = answer10xJ2.T[:2]
    plt.plot(x, y, '-r')
    plt.plot([0], [0], 'or')
    plt.gca().set_aspect('equal')
    plt.show()