Нахождение геоцентрических координат перицентра

В настоящее время я пишу программу, которая принимает вектор состояния, вычисляет соответствующий кеплеровский эллипс, а затем рисует эллипс.

Но я застрял в следующем моменте. В настоящее время мне нужно какое-то значение, чтобы сообщить программе, насколько нужно повернуть орбитальный эллипс. Для этого мне нужно значение угла от оси x (координаты ECI) до перицентра.

Проблема в том, что аргумент перицентра мне не помогает, если орбита не наклонена.

Есть ли способ вычислить этот угол или вычислить координаты перицентра, чтобы я мог этого добиться?

Прямо сейчас я рисую орбиту, используя функцию добавления эллипса matplotlib (python), которая требует некоторого угла, на который должен быть повернут эллипс, rotation_deg- это угол, который я ищу.

orbit = patches.Ellipse((Cx,Cy), major, minor, rotation_deg, 
                        facecolor="none", edgecolor="k", linestyle="--")

В приведенном ниже примере я тщательно выбрал вектор начального состояния с Икс "=" перицентр , у "=" 0 , г "=" 0 так что угол равен нулю, но мне нужно обобщить для любого произвольного вектора состояния в пределах заданной орбиты.

r = np.array([r_earth+500000,      0,   0])
v = np.array([             0,   9000,   0])

пример графика эллиптической орбиты

Вот мой код:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches

G = 6.67e-11
M_earth = 5.972e24
mu_earth = G*M_earth
r_earth = 6.3781e6

def plot_setup_earth():
    global f, ax

    f, ax = plt.subplots()
    circle = plt.Circle((0,0),r_earth,color = "b")

    ax.set_aspect("equal", "box")
    ax.add_artist(circle)
    ax.set_title("Vehicle Orbit (ECI Coordinates)")
    ax.set_xlabel("X (meters)")
    ax.set_ylabel("Y (meters)")

def elements_from_vectors(r,v,radius,mu):
    global apoapsis, periapsis, a, b, e

    K = np.array([0,0,1])

    h_vec = np.cross(r,v) #momentum vector 
    n_vec = np.cross(K,h_vec) #line of nodes vector
    e_vec = (1/mu)* np.cross(v,h_vec) - (r/np.linalg.norm(r)) #eccentricity vector
    E = ((np.linalg.norm(v)**2)/2) - (mu/np.linalg.norm(r)) #orbital energy

    e = np.linalg.norm(e_vec) #eccentricity
    a = (-1)*(mu/(2*E)) #semimajor axis
    b = a*np.sqrt(1-(e**2))
    p = ((np.linalg.norm(h_vec)**2)/mu) #????

    i = np.arccos(np.dot((h_vec/np.linalg.norm(h_vec)),K)) #Inclination (rad)
    i_deg = np.degrees(i) #Inclination (deg)

    #Right ascension of the ascending node
    if i == 0:
        raan = 0
    elif n_vec[1] >= 0:
        raan = np.arccos(n_vec[0]/np.linalg.norm(n_vec))
    elif n_vec[1] <0: 
        raan = (2*np.pi) - np.arccos(n_vec[0]/np.linalg.norm(n_vec))

    #Argument of periapsis
    if i == 0: 
        w = 0
    elif e_vec[2] >= 0:
        w = np.arccos(np.dot(n_vec,e_vec)/(np.linalg.norm(n_vec)*np.linalg.norm(e_vec)))
    elif e_vec[2] < 0: 
        w = (2*np.pi)-np.arccos(np.dot(n_vec,e_vec)/(np.linalg.norm(n_vec)*np.linalg.norm(e_vec)))

    #True anomoly
    if np.dot(r,v) >= 0:
        f = np.arccos(np.dot(r,e_vec)/(np.linalg.norm(r)*np.linalg.norm(e_vec)))
    if np.dot(r,v) < 0:
        f = (2*pi)-np.arccos(np.dot(r,e_vec)/(np.linalg.norm(r)*np.linalg.norm(e_vec)))

    periapsis = a*(1-e)
    apoapsis = a*(1+e)

def plot_orbit(apoapsis, periapsis, semimajor, semiminor, eccentricity):
    major = 2*semimajor #Aka major axis
    minor = 2*semiminor #Aka minor axis

    ae = semimajor*eccentricity #Focus to center distance (where focus 1 is center of body being orbited)
    rotation_deg = 0
    rotation_rad = np.radians(rotation_deg)

    Px = periapsis*np.cos(rotation_rad)
    Py = periapsis*np.sin(rotation_rad)

    Ax = (-1)*apoapsis*np.cos((-1)*rotation_rad)
    Ay = apoapsis*np.sin((-1)*rotation_rad)

    Cx = 0 - ae*np.cos(-1*rotation_rad)
    Cy = 0 + ae*np.sin(-1*rotation_rad)

    orbit = patches.Ellipse((Cx,Cy), major, minor, rotation_deg, facecolor = "none", edgecolor = "k", linestyle = "--")
    ax.add_artist(orbit)

    plt.scatter(Px,Py, color = "r",marker = "+")
    plt.annotate("Periapsis %f km" %round((periapsis-r_earth)/1000,1), (Px,Py), fontsize = 9)
    plt.scatter(Ax,Ay,color = "b", marker = "+")
    plt.annotate("Apoapsis %f km" %round((apoapsis-r_earth)/1000,1),(Ax,Ay), fontsize = 9)

r = np.array([r_earth+500000,0,0])
v = np.array([0,9000,0])

plot_setup_earth()
elements_from_vectors(r,v,r_earth,mu_earth)
plot_orbit(apoapsis, periapsis, a, b, e)

plt.xlim(-1.5*apoapsis,4*periapsis)
plt.ylim(-1*(b*2),1*((b*2)))

plt.show()
Если у вас есть правильные векторы состояния , вы просто рисуете их, и это ваша орбита. Вы действительно имеете в виду, что у вас есть таблица Икс , у , г , в Икс , в у , в г ценности? Может быть, вы могли бы показать пример того, что вам нужно построить, чтобы было легче понять, почему вам все еще нужна дополнительная информация.
То, как я это делаю, - это преобразование векторов в элементы орбиты и построение эллипса из этих значений. Я использую библиотеку matplotlib для python, чтобы сделать этот график. Я не уверен, как бы я просто построил вектор и увидел орбиту.
Я не думаю, что мы можем обсуждать дальше, если вы не покажете образец того, что у вас есть. График орбиты на самом деле представляет собой серию отрезков, соединяющих последовательность Икс , у , г точки. См. этот ответ , например. Эта орбита представляет собой последовательность из 201 вектора состояния с Икс , у , г построена часть векторов состояния.
Я обновил свой ответ, если хотите, вы можете взглянуть на мой код, чтобы узнать, что вы думаете.
Большое спасибо за обновление и скрипт! Я немного изменил формулировку и добавил форматирование. Теперь я вижу, что каждая орбита состоит из одного вектора начального состояния , а не из векторов состояния (во множественном числе). Можете ли вы уточнить, нужно ли вам, чтобы это работало для любого произвольного вектора начального состояния, включая все RAAN и наклоны? Прямо сейчас есть ответ , который кажется полезным, но я не уверен, что он охватывает ваш случай. Было бы здорово, если бы вы могли оставить комментарий для этого автора прямо под его ответом. Спасибо!

Ответы (2)

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

Вы могли бы начать с этого объяснения долготы перицентра для примера набора орбитальных элементов, которые не страдают от неправильного поведения, когда наклонение приближается к нулю.

И/или вы могли бы использовать формулы для отношений между векторами состояния и орбитальными элементами, данные в Бейт, Мюллер и Уайт (1971) Основы астродинамики , ...

или, например, в AE Roy, Orbital Motion (или погуглите другие источники с таким же названием).

Вы также можете найти некоторые формулы, полезные в методе предварительного определения орбиты, не имеющем копланарной сингулярности, авторы RML Baker and NH Jacoby, Celestial Mechanics 15 (1977) 137-160.

Надеюсь, это поможет.

Это начало отличного ответа, но ответ находится в ссылках, а не здесь, что делает этот ответ в основном только ссылкой , что обычно не рекомендуется в Stack Exchange. Если/когда ссылки сгниют, здесь нет ответа для будущих читателей. Можете ли вы взять блок — довольно небольшой отрывок или уравнение или два — и обобщить ответы здесь, в своем посте? Спасибо!
Вы, конечно, уже писали довольно подробные ответы !
@uhoh: я понимаю, что «ответ только по ссылке» - это тот, который дает URL-адрес без указания того, к чему он должен обращаться. Здесь я дал ссылки на публикации по названию, автору и т. д., так что даже если ссылки сами по себе «гниют», цитируемые ссылки все равно можно идентифицировать и искать. Поэтому я считаю, что на самом деле это не ответ только по ссылке. Трудность выбора формул для спрашивающего заключается в том, что о проблеме сказано так мало, что неясно, какие вычислительные операции будут наиболее актуальными.
Если вопрос слишком общий, чтобы на него можно было ответить, добавьте комментарий к вопросу с просьбой пояснить. Я почти уверен, что термин «только для ссылок» также включает только цитирование, дело в том, что ответ находится не здесь, в ответе, а где-то еще за пределами Stack Exchange. Я изменил ваше предисловие, а затем добавил комментарий к вопросу с просьбой разъяснить.

В ситуации, когда орбита не наклонена, соглашение обычно заключается в том, что аргумент периапсиса представляет собой угол от опорного направления (в вашем случае оси x) к периапсису.

Код, который у вас есть, предполагает, что аргумент периапсиса всегда равен нулю, если наклон равен нулю, что неверно. Вот как я бы переписал ваш раздел «Аргумент о периапсисе».

    #Argument of periapsis

    if i != 0 and e!= 0: # Orbit is inclined and eccentric
        w = np.arccos(np.dot(n_vec,e_vec)/(np.linalg.norm(n_vec)*np.linalg.norm(e_vec)))
        if e_vec[2] < 0:
            w = (2*np.pi) - w
    elif e != 0: # Orbit is not inclined, but is eccentric
        w = numpy.arctan2(e_vec[1], e_vec[0])
    else: #Orbit is circular.
        w = 0.0

Таким образом, как упоминалось выше, вы можете затем использовать свой аргумент значения перицентра, чтобы rotation_deg=wповернуть свой эллипс желаемым образом, если ваша орбита экваториальна и прямолинейна (наклон = 0), а точка обзора находится над осью Z.

Я добавил немного форматирования здесь. Взгляните на вопрос, он был обновлен полным сценарием и некоторыми уточнениями в формулировках. Там же есть и дополнительные комментарии. Интересно, можете ли вы расширить это, включив также наклонность? Спасибо!
Благодарю за разъяснение. Разве использование аргумента перицентра в качестве значения поворота не предполагает, что линия узлов проходит вдоль оси x? Я просто пытаюсь понять, почему аргумент перицентра работает как угол поворота.
Аргумент периапсиса - это угол в плоскости орбиты, измеренный от прямого восхождения Восходящего узла через центр тела, обращающегося по орбите, до периапсиса в направлении движения по орбите. Итак, если ваша орбита экваториальна и направлена ​​вперед (i = 0), то raan = 0, и, таким образом, аргумент периапсиса — это угол, который вам нужен.
Потрясающий! Спасибо вам за разъяснение. И это даже работает с координатами ECI, которые я использую для графика? Мне не нужно строить график орбиты с точки зрения, перпендикулярной плоскости орбиты?
@GriffinJ, к сожалению, использование только аргумента перицентра работает только для ненаклонной орбиты, рассматриваемой в перпендикулярном случае, о чем, как я думал, вы спрашивали. Извинения. Я лично не знаком с matplotlib, поэтому я не могу дать хорошую рекомендацию о том, как справиться с тем, чтобы нарисовать эллиптическую орбиту с произвольной точки зрения.
Все в порядке. Я в основном использую это для другой программы, которую я пишу, которая обобщает орбиты как ненаклонные. Так что для моего текущего использования это просто отлично! Вероятно, в какой-то момент я захочу разобраться с другими вещами, но пока я реализовал ваше предложение, и оно работает.