天体 AltAz 返回的距离差异

问题描述 投票:0回答:1

我正在编写一些处理飞机相对于地面观察者的位置的代码,并且我发现直接根据观察者和飞机的地心笛卡尔坐标计算出的距离与天文学中 AltAz 返回的距离之间存在差异。以下最小可重现代码说明了飞机在观察者上方 1000 m 处的问题。

#Problem calculating distance to object in the sky
#worse when close to observer. Negligible if distance > 100 km
from astropy.time import Time
from astropy import units as u
from astropy.coordinates import EarthLocation, AltAz
obs_lon = 0*u.deg
obs_lat = 0*u.deg
obs_alt = 0*u.m
aircraft_lon = 0*u.deg
aircraft_lat = 0*u.deg
aircraft_alt = 1000*u.m
obs_time = Time ('2000-01-01T00:00:00.000')
obs_location = EarthLocation.from_geodetic (obs_lon,obs_lat, obs_alt)
aircraft_location = EarthLocation.from_geodetic(aircraft_lon, aircraft_lat, \
                                                aircraft_alt)
aircraft_altaz = aircraft_location.get_gcrs(obstime=obs_time). \
    transform_to(AltAz(location=obs_location, obstime=obs_time))
dist = ((aircraft_location.x - obs_location.x)**2 + \
        (aircraft_location.y - obs_location.y)**2 + \
            (aircraft_location.z - obs_location.z)**2)**0.5
print("distance calculated from xyz", dist) # this gives 1000 m, as expected
print("distance returned from AltAz", aircraft_altaz.distance) # 1189.4 m ?

我本来期望获得类似的结果,但结果却截然不同。与远处物体相比,近距离物体的差异更大。它还强烈依赖于时间(尤其是一天中的时间而不是日期,因此问题看起来与地球自转有关)。与纬度的相关性似乎很小。用 itrs 替换 gcrs 会产生相同的行为。

python coordinates astropy astronomy
1个回答
0
投票

我终于找到了解决办法。我发布它只是为了将来对其他人有用:显然这个问题与天体如何处理恒星像差校正有关。对于近地天体,不应包含此校正,这可以使用地心 ITRS 框架来实现。点击此链接后,要遵循的步骤是:

  • 获取物体和天文台的笛卡尔表示 在 ITRS 框架中
  • 减去前两个向量(即得到物体相对于天文台的相对位置)。
  • 将此相对坐标传递给 ITRS,这提供了 以地心 ITRS 物体的位置
  • 从以地为中心的 ITRS 转变为 AltAz。

代码:

#Problem calculating distance to object in the sky
#worse when close to observer. Negligible if distance > 100 km
from astropy.time import Time
from astropy import units as u
from astropy.coordinates import EarthLocation, AltAz, ITRS
obs_lon = 0*u.deg
obs_lat = 0*u.deg
obs_alt = 0*u.m
aircraft_lon = 0*u.deg
aircraft_lat = 0*u.deg
aircraft_alt = 1000*u.m
obs_time = Time ('2000-01-01T00:00:00.000')
obs_location = EarthLocation.from_geodetic (obs_lon,obs_lat, obs_alt)
aircraft_location = EarthLocation.from_geodetic(aircraft_lon, aircraft_lat, \
                                                aircraft_alt)
aircraft_altaz_old = aircraft_location.get_gcrs(obstime=obs_time). \
    transform_to(AltAz(location=obs_location, obstime=obs_time))
dist = ((aircraft_location.x - obs_location.x)**2 + \
        (aircraft_location.y - obs_location.y)**2 + \
            (aircraft_location.z - obs_location.z)**2)**0.5
#New block of code solving the issue:
aircraft_itrs = aircraft_location.get_itrs(obstime = obs_time)
obs_itrs = obs_location.get_itrs(obstime = obs_time)
aircraft_itrs_relative = aircraft_itrs.cartesian.without_differentials() - \
    obs_itrs.cartesian
aircraft_topo = ITRS(aircraft_itrs_relative, obstime = obs_time, \
                     location = obs_location)
aircraft_altaz = aircraft_topo.transform_to(AltAz(obstime = obs_time, \
                                                  location=obs_location))
print("dist calculated from xyz", dist) # this gives 1000 m, as expected
print("dist returned from AltAz (old)", aircraft_altaz_old.distance) # 1189.6 m
print("dist returned from AltAz (new)", aircraft_altaz.distance) # 10000 m
print("az, alt ",aircraft_altaz.az.to_value(), aircraft_altaz.alt.to_value())
#now distance, az and alt are OK
© www.soinside.com 2019 - 2024. All rights reserved.