8个不稳定版本 (3个破坏性更新)

0.4.2 2024年7月14日
0.4.1 2024年7月11日
0.4.0 2024年6月28日
0.3.2 2024年5月22日
0.1.0 2023年11月16日

#17 in 地理空间

Download history 221/week @ 2024-04-25 113/week @ 2024-05-02 132/week @ 2024-05-09 221/week @ 2024-05-16 222/week @ 2024-05-23 362/week @ 2024-05-30 275/week @ 2024-06-06 192/week @ 2024-06-13 210/week @ 2024-06-20 334/week @ 2024-06-27 204/week @ 2024-07-04 471/week @ 2024-07-11 325/week @ 2024-07-18 309/week @ 2024-07-25 324/week @ 2024-08-01 192/week @ 2024-08-08

1,187 每月下载量
2 crate中使用

MPL-2.0 许可证

630KB
13K SLoC

ANISE (姿态、导航、仪器、航天器、星历)

ANISE是对NAIF SPICE工具包核心功能的重写,具有增强的性能、易于使用,同时利用Rust的安全性和速度。

请填写我们的用户调查

简介

在太空探索、导航和天体物理学领域,精确和高效地计算航天器的位置、姿态和时间至关重要。ANISE(代表“姿态、导航、仪器、航天器、星历”)提供了一种Rust原生方法来解决这些挑战。此工具包提供了一系列功能,包括但不限于

  • 加载SPK、BPC、PCK、FK和TPC文件。
  • 高精度的平移、旋转及其组合(刚体变换)。
  • 使用hifitime库进行全面的时系统转换(包括TT、TAI、ET、TDB、UTC、GPS时间等)。

ANISE经过验证与传统的SPICE工具包相匹配,确保准确性和可靠性,平移达到机器精度(2e-16)且旋转误差最小(旋转轴指向小于两弧秒,绕此旋转轴的角度小于一弧秒)。

特性

  • 高精度:在平移上与SPICE匹配到机器精度,在旋转上误差最小。
  • 时系统转换:广泛支持在天体动力学中至关重要的各种时系统。
  • Rust效率:利用Rust的速度和安全性能进行空间计算。
  • 多线程:是的!忘掉你在SPICE中常用的互斥锁和竞态条件吧,ANISE 保证 你不会有任何竞态条件。
  • 框架安全:ANISE在执行任何计算之前,甚至内部计算,都会检查所有框架的平移或旋转是否在物理上有效。
  • 自动下载功能:ANISE通过自动下载最新的地球定向参数,或任何其他来自远程位置的SPICE或ANISE文件,简化了你的工作流程,无缝地将它们集成到Almanac中以供即时使用。

使用方法

通过将其添加到Rust项目开始使用它

cargo add anise

轨道帧转换

ANISE提供创建笛卡尔状态(也简称为Orbit)的能力,以无错误的方式从它们中计算轨道元素(可能失败的运算返回Result类型),并且通过加载的上下文(称为Almanac),将这些状态转换到其他框架,其中存储了您需要的所有SPICE和ANISE文件。

use anise::prelude::*;
// ANISE provides pre-built frames, but examples below show how to build them from their NAIF IDs.
use anise::constants::frames::{EARTH_ITRF93, EARTH_J2000};

// Initialize an empty Almanac
let ctx = Almanac::default();

// Load a SPK/BSP file
let spk = SPK::load("../data/de440.bsp").unwrap();
// Load the high precision ITRF93 kernel
let bpc = BPC::load("../data/earth_latest_high_prec.bpc").unwrap();
// Build the planetary constants file, which includes the gravitational parameters and the IAU low fidelity rotations
use anise::naif::kpl::parser::convert_tpc;
// Note that the PCK variable can also be serialized to disk to avoid having to rebuild it next time.
let pck = convert_tpc("../data/pck00008.tpc", "../data/gm_de431.tpc").unwrap();

// And add all of these to the Almanac context
let almanac = ctx
    .with_spk(spk)
    .unwrap()
    .with_bpc(bpc)
    .unwrap()
    .with_planetary_data(pck);

// Let's build an orbit
// Start by grabbing a copy of the frame.
let eme2k = almanac.frame_from_uid(EARTH_J2000).unwrap();

// Define an epoch, in TDB, but you may specify UTC, TT, TAI, GPST, and more.
let epoch = Epoch::from_str("2021-10-29 12:34:56 TDB").unwrap();

// Define the orbit from its Keplerian orbital elements.
// Note that we must specify the frame of this orbit: ANISE checks all frames are valid before any translation or rotation, even internally.
let orig_state = Orbit::keplerian(
    8_191.93, 1e-6, 12.85, 306.614, 314.19, 99.887_7, epoch, eme2k,
);

// Transform that orbit into another frame.
let state_itrf93 = almanac
    .transform_to(orig_state, EARTH_ITRF93, None)
    .unwrap();

// The `:x` prints this orbit's Keplerian elements
println!("{orig_state:x}");
// The `:X` prints the prints the range, altitude, latitude, and longitude with respect to the planetocentric frame in floating point with units if frame is celestial,
println!("{state_itrf93:X}");

// Convert back
let from_state_itrf93_to_eme2k = almanac
    .transform_to(state_itrf93, EARTH_J2000, Aberration::NONE)
    .unwrap();

println!("{from_state_itrf93_to_eme2k}");

// Check that our return data matches the original one exactly
assert_eq!(orig_state, from_state_itrf93_to_eme2k);

加载和查询PCK/BPC文件(高精度旋转)

use anise::prelude::*;
use anise::constants::frames::{EARTH_ITRF93, EME2000};

let pck = "../data/earth_latest_high_prec.bpc";

let bpc = BPC::load(pck).unwrap();
let almanac = Almanac::from_bpc(bpc).unwrap();

// Load the useful frame constants
use anise::constants::frames::*;

// Define an Epoch in the dynamical barycentric time scale
let epoch = Epoch::from_str("2020-11-15 12:34:56.789 TDB").unwrap();

// Query for the DCM
let dcm = almanac.rotate_from_to(EARTH_ITRF93, EME2000, epoch).unwrap();

println!("{dcm}");

加载和查询文本PCK/KPL文件(低精度旋转)

use anise::prelude::*;
// Load the TPC converter, which will create the ANISE representation too, in ASN1 format, that you may reuse.
use anise::naif::kpl::parser::convert_tpc;

// Note that the ASN1 ANISE format for planetary data also stores the gravity parameters, so we must convert both at once into a single ANISE file.
let planetary_data = convert_tpc("../data/pck00008.tpc", "../data/gm_de431.tpc").unwrap();

let almanac = Almanac {
    planetary_data,
    ..Default::default()
};

// Load the useful frame constants
use anise::constants::frames::*;

// Define an Epoch in the dynamical barycentric time scale
let epoch = Epoch::from_str("2020-11-15 12:34:56.789 TDB").unwrap();

// Query for the DCM to the immediate parent
let dcm = almanac.rotation_to_parent(IAU_VENUS_FRAME, epoch).unwrap();

println!("{dcm}");

加载和查询SPK/BSP文件(星历)

use anise::prelude::*;
use anise::constants::frames::*;

let spk = SPK::load("../data/de440s.bsp").unwrap();
let ctx = Almanac::from_spk(spk).unwrap();

// Define an Epoch in the dynamical barycentric time scale
let epoch = Epoch::from_str("2020-11-15 12:34:56.789 TDB").unwrap();

let state = ctx
    .translate(
        VENUS_J2000, // Target
        EARTH_MOON_BARYCENTER_J2000, // Observer
        epoch,
        None,
    )
    .unwrap();

println!("{state}");

验证

ANISE Validation

ANISE通过在上面的验证步骤中,以ANISE和SPICE(单线程)运行相同的查询进行验证。此工作流程验证了DE440.BSP文件中的101,000个BSP查询,以及在PCK08文件中的每帧7305个查询(20年每天),以及来自地球高精度BPC文件数千个旋转。

注意: PCK数据来自IAU报告,该报告发布角、角速率和角加速度数据,这些数据以J2000参考历元之前的世纪为单位表示。ANISE使用Hifitime进行时间转换。Hifitime仅对所有时间计算依赖整数,消除了舍入误差的风险。相比之下,SPICE使用浮点值,这会在计算如J2000之前的世纪这样的运算中引入舍入误差。因此,您可能会观察到SPICE和ANISE之间旋转角度的最大1毫弧度差异。然而,这种差异是ANISE卓越精度的证明。

资源/资产

为了方便起见,Nyx Space在公共存储桶中提供了一些重要的SPICE文件

您可以使用load()快捷方式加载以下内容,该快捷方式会在加载时确定文件类型,例如:let almanac = Almanac::new("pck08.pca").unwrap();或Python中的almanac = Almanac("pck08.pca")。要自动下载远程资产,例如从Nyx Cloud或其他地方,请使用MetaAlmanac:almanac = MetaAlmanac("ci_config.dhall").process()(Python)。

贡献

欢迎为ANISE做出贡献!无论是以功能请求、错误报告、代码贡献或文档改进的形式,每一份帮助都备受感激。

许可证

ANISE遵循Mozilla公共许可证2.0(MPL-2.0)分发,它以平衡的方式开放源代码,允许在开源和专有软件中使用源代码。MPL-2.0要求对受保护代码的修改必须以相同许可证发布,从而确保改进保持开源。然而,它允许将受保护软件与专有部分结合,为学术和商业集成提供灵活性。

更多详细信息,请参阅许可证全文或阅读GitHub的摘要

致谢

ANISE深受NAIF SPICE工具包及其优秀文档的启发。

联系方式

如有任何询问、反馈或讨论,请在此处提交问题或联系维护者[email protected]

依赖关系

~18–34MB
~547K SLoC