Земная долгота/широта под спутником (декартовы координаты) в определенную эпоху

Сценарий, который я хочу разработать, использует декартовы координаты (XYZ) со спутника, и в сочетании с диапазоном, высотой и азимутом из местоположения я затем беру информацию об орбите спутника и получаю долготу/широту земли под этим спутником. в данное время.

Еще один шаг от этого: представьте себе сигнал от спутника, пронзающего атмосферу на высоте ровно 300 км над уровнем моря. В этой конкретной точке, когда высота составляет 300 км, мне нужно рассчитать долготу/широту земли.

В модуле pyephem, по-видимому, уже есть метод (ephem.readtle), который может достичь этого, но только для данных TLE (двухстрочный элемент). Я хотел бы использовать декартовы координаты спутника, чтобы развить это. Есть ли уже такой метод? Или, возможно, кто-то с опытом в этой области может указать мне правильное направление.

Аналогичный вопрос уже существует со ссылкой на ECEF из Azimuth, Elevation, Range и Observer Lat,Lon,Alt , но это не та же проблема.

Вот что я уже разработал:

  • спутниковые декартовы координаты, XYZ
  • азимут, высота и дальность спутника от наземной станции
  • координаты наземной станции в широте, долготе, высоте над уровнем моря

Вот что мне нужно: долгота/широта земли под спутником в определенную эпоху и, в частности, где точка проникновения в атмосферу (точка, через которую сигнал со спутника проходит через атмосферу) находится на высоте 300 км.


Итак, я еще не решил проблему с тем, как разрешить наземные пути для высоты 300 км, но я считаю, что написанный мной метод преобразования XYZ в эллипсоид завершен:

 def cartesian_to_ellipsoidal(self):
    x = 4433469.9438
    y = 362672.7267
    z = 4556211.6409
    r = np.sqrt(x**2 + y**2 + z**2)

    # WGS-84 PARAMETERS, semimajor and semiminor axis
    a = 6378137.0
    b = 6356752.314 

    # Eccentricity
    e_squared = (a**2 - b**2) / a**2

    # Auxiliary quantities
    p = np.sqrt(x**2 + y**2)

    # Latitude (phi) & Longitude (lam)
    phi = np.rad2deg(np.arctan(z / ((1- e_squared) * p)))
    lam = np.rad2deg(np.arctan(y/x))

    # Radius of curvature in prime vertical               
    N = a / np.sqrt(1 - e_squared * (np.sin(np.deg2rad(phi)))**2)

    # Altitude
    h = (p / np.cos(np.deg2rad(phi))) - N

    return lam, phi, h

Координаты XYZ взяты в качестве образца из этого примера работы Matlab Пример работы Matlab . Результаты с точностью, которой я доволен. Чего я не понимаю и возможно тупой вопрос, но когда вместе с высотой рассчитывается наземный трек, то почему высота не нулевая? Можно было бы ожидать, что, поскольку наземный трек отображается на поверхности земли, высота должна быть равна нулю.

И последнее замечание: желаемый наземный трек был там, где линия между спутником и наземной станцией пронзает атмосферный воздух на высоте 300 км над землей. Учитывая расстояния в 20 000 км (радиус 26 000 км), будет ли корректировка моего кода - просто для компенсации желаемого сценария высоты 300 км - иметь большое значение для результата? Если нет, данных наземного пути может быть достаточно.

Когда вы говорите декартово, вы имеете в виду инерциальные координаты, центрированные на Земле? И вы хотите найти широту/долготу прямо под спутником? Просто проведя линию от центра земли до спутника, узнать, где линия пересекает поверхность (и 300 км над поверхностью)? Если XYZ исходит от TLE, для чего нужна наземная станция?
Ответьте на вопросы о Skyfield здесь и здесь, а также на веб- сайте . Это легко использовать!
@uhoh, да, ECEF. Я хотел бы найти наземный трек спутника в кадре долгота/широта, а не сам спутник, точку, где линия от спутника до приемника пересекается на высоте 300 км над Землей. XYZ исходит не от TLE, а от моего собственного скрипта Python посредством спутниковых эфемерид.
О, теперь я понял - где линия от спутника до наземной станции пробивает высоту 300км. Таким образом, XYZ спутника находится в фиксированных координатах Земли по центру Земли (ECEF = вращающийся) или в инерциальных координатах по центру Земли (ECI = не вращающийся)?
ЕСЕФ. у меня уже есть XYZ-координата спутника, а также высота, азимут и дальность. Я полагаю, что для получения желаемого результата потребуется некоторый триггер.
Что-то вроде +/- 10 км точности в порядке (сферическая Земля) или вам нужно учитывать сжатие - разница около 20 км от полюса до экватора. Математика становится немного сложнее, когда линии широты и долготы находятся на сплюснутой сфере. Вы также можете найти действительно полезные материалы на http://gis.stackexchange.com/ — осмотритесь там.
@uhoh, пожалуйста, смотрите мой измененный вопрос выше.
Можете ли вы попытаться превратить это в более четко (узко) определенный и короткий вопрос, на который можно дать четкий ответ? Здесь может быть слишком много всего, чтобы соответствовать формату вопросов и ответов stackexchange. По крайней мере мне это больше похоже на "мысли вслух",
Координаты спутника (sv) даны в XYZ, а радиус от Земли примерно 26000 км. Наземные треки рассчитываются по XYZ спутника. Теперь представьте линию от св до земли. Вместо того, чтобы спутник находился на расстоянии примерно 20 000 (26 000 минус земной радиус) километров по этой линии, давайте предположим, что спутник находится на той же линии, но на высоте 300 км (назовем это точкой прокола атмосферы). Это означает, что дальность полета sv составляет (300 / sin e) км, где «e» — угол места. Что я хотел бы знать, так это наземный трек этого спутника, расположенного на этом расстоянии (300 км над Землей).

Ответы (1)

С того момента, как вы находитесь, вам необходимо:

  1. Рассчитайте координаты XYZ вашей наземной станции
  2. Найдите линию в пространстве между спутником и наземной станцией
  3. Найдите координаты XYZ точки на пересечении этой линии с эллипсоидом, определяемым всеми точками с высотами 300 км.
  4. Найдите широту и долготу этой точки.

Для (1) вы можете использовать эту функцию Matlab:

function [X,Y,Z] = ll2xyz(lat,lon,alt)
    b=6356752.3141;
    a=6378137.0;
    lat=lat*pi/180;
    %transformation between geografic and geocentric latitude
    gclat=atan(b^2*tan(lat)/a^2);
    lon=lon*pi/180;
    R=sqrt(1./(tan(gclat).^2/b^2 + 1/a^2));
    Z=R.*tan(gclat);
    Z=Z+alt.*sin(lat);
    R=R+alt.*cos(lat);
    X=R.*cos(lon);
    Y=R.*sin(lon);

Для (2) и (3) эта функция поможет

function [X Y Z] = rectaxelip(x1,x2,y1,y2,z1,z2,alt)
%rectaxelip calculates the point XYZ were a straight line that pass by points P1
%and P2, intersects a ellipsoid alt meters bigger than WGS84 
%ellispsoid (on each axis)

%The director cosines of the line are 
    d=sqrt((x1-x2).^2.*(y1-y2).^2.*(z1-z2).^2);
    L=(x1-x2)./d;
    M=(y1-y2)./d;
    N=(z1-z2)./d;
    %its parametric  for is
    %x = x1 + L * t
    %y = y1 + M * t
    %z = z1 + N * t
    %Now we look for the intersection
    %the ellipsoid would have axes bp and ap

    b=6356752.3141; 
    a=6378137.0;
    bp=b+alt; 
    ap=a+alt;

    %The equation of such ellipsod would be
    %  x^2/ap^2+y^2/ap^2+z^2/bp^2=1
    %subtituting and reorganizng you get a quadratic equation like
    %   A x^2 + B x + C = 0
    %with
    A=(L./ap).^2+(M./ap).^2+(N./bp).^2;
    B=2*((x1.*L./(ap.^2))+(y1.*M./(ap.^2))+(z1.*N./(bp.^2)));
    C=((x1./ap).^2+(y1./ap).^2+(z1./bp).^2)-1;
    ta=(-B+sqrt(B.^2 - (4*A.*C)))./(2*A);
    tb=(-B-sqrt(B.^2 - (4*A.*C)))./(2*A);

    %then
    x1a = x1 + L .* ta;
    y1a = y1 + M .* ta;
    z1a = z1 + N .* ta;
    x1b = x1 + L .* tb;
    y1b = y1 + M .* tb;
    z1b = z1 + N .* tb;
    %Now the distance from each point to the satellite is
    da=sqrt((x1a-x2).^2+(y1a-y2).^2+(z1a-z2).^2);
    db=sqrt((x1b-x2).^2+(y1b-y2).^2+(z1b-z2).^2);
    ESta=da<db;
    t=ta.*ESta+tb.*(~ESta);

    %then
    X = x1 + L .* t;
    Y = y1 + M .* t;
    Z = z1 + N .* t;

А для (4) вам просто нужна функция, которая вычисляет координаты широты и долготы из позиций XYZ, и это сделает это:

function [lat,lon,alt] = xyz2ll(x,y,z1)
%For some reason the error spikes at +-45
a=6356752.3141; 
b=6378137.0;

signos=sign(z1);
z1=-abs(z1);

lon=atan2(y,x)*180/pi; %Longitude
d1=sqrt(x.^2+y.^2);
z2=-sqrt(1./((1/(a^2))+(1./(b^2*(z1./d1).^2))));
d2=z2./(z1./d1);
p2=-a*d2./(b^2*sqrt(1-(d2.^2/(b^2)))); %slope of the tangent to the ellipse in the point
for i=1:5
    %points in the palne
    dp=(z1-z2-(d1./p2)+(p2.*d2))./(p2-(1./p2));
    zp=(p2.*dp)+z2-(p2.*d2);
    %points in the ellipse
    z2=-sqrt(1./((1/(a^2))+(1./(b^2*(zp./dp).^2))));
    d2=z2./(zp./dp);
    p2=-a*d2./(b^2*sqrt(1-(d2.^2/(b^2))));
end
lat=-90-(atan(p2)*180/pi);   %geographic latitude
lat=abs(lat).*signos;
ecuador=find(abs(z1)<0.001);
lat(ecuador)=0;
alt=sqrt(d1.^2+z1.^2)-sqrt(d2.^2+z2.^2);
alt(ecuador)=d1(ecuador)-a;

И тогда вы готовы, и у вас есть наземное положение точки, где сигнал GPS, достигающий базовой станции, пересекает высоту 300 км.

Я сам написал эти функции и тщательно их протестировал, поэтому знаю, что они работают, но имейте в виду, что последняя функция, несмотря на то, что она имеет очень хорошую точность, по причине, по которой я мало исследовал, похоже, дает большие ошибки на широтах. +-45°.

Последнее, что нужно отметить. Если вы хотите большей точности и не рассчитываете координаты XYZ спутников GPS, вы можете использовать файлы эфемерид sp3. Их легко скачать отсюда . Существует один файл в день, и в каждом файле координаты XYZ каждого спутника заносятся в таблицу каждые 15 минут. Для получения позиций в любое время сплайн-интерполяция дает очень хорошее решение, почти такое же, как рекомендуемая полиномиальная интерполяция Невилла.

Когда вы говорите «эллипсоид, определяемый всеми точками с высотами 300 км», как вы «выращиваете» эллипсоид WGS84 на 300 км по высоте? Что мне любопытно, так это то, движется ли каждая точка на WGS84 по локальной нормали к эллипсоиду, или радиально от центра Земли, или по локальному гравитационному градиенту («вверх»)? Кроме того, если вы хотите добавить ответ на вопрос, что такое эллипсоид Меркурия Фишера 1960 года и почему он так называется? с исторической точки зрения, это было бы здорово! Мне нравятся ваши ответы, и ее история довольно интересна!
@uhoh Как вы можете видеть в коде, он просто добавит 300 км к большой и малой полуосям, которые определяют опорный эллипсоид. И я думаю, что полученный эллипсоид эквивалентен поверхности, определяемой всеми точками на высоте 300 км эллипсоида относительно первого эллипсоида. Эллипсоидальные возвышения, в свою очередь, измеряются перпендикулярно поверхности эллипсоида (т. е. минимальное расстояние), НЕ радиально от центра эллипсоида НИ каким-либо образом с учетом гравитационных градиентов. Интересный вопрос вы задали! Но я воздержусь от ответа на этот раз просто из-за отсутствия свободного времени, чтобы сделать это. Ваше здоровье
Ах! Наконец-то я понял, что меня в этом смущает. "...с эллипсоидом, определяемым..." Результирующая поверхность не является эллипсоидом. При небольших изменениях он, наверное, выглядел бы как один, но таковым его назвать нельзя. Самый быстрый способ проверить - взять эталонный эллипсоид, добавить 300 км к большому и малому радиусам, рассчитать форму правильного эллипсоида с этими радиусами, а затем сравнить разницу. Наверное, всего несколько десятков метров. Все-таки лучше не называть его эллипсоидом, если он им не является.