#space #spice #kernel #nasa #naif #api-bindings

rust-spice

哇!NASA/NAIF Spice工具包的完整实现现在可以在Rust上使用

28个版本

0.7.8 2023年12月18日
0.7.6 2023年10月18日
0.7.4 2022年11月19日
0.7.1 2021年10月24日
0.4.1 2021年3月31日

#142算法

Download history 100/week @ 2024-04-22 14/week @ 2024-04-29 248/week @ 2024-05-20 203/week @ 2024-05-27 402/week @ 2024-06-03 73/week @ 2024-06-10 32/week @ 2024-06-17 204/week @ 2024-06-24 75/week @ 2024-07-01 134/week @ 2024-07-08 18/week @ 2024-07-15 225/week @ 2024-07-29 198/week @ 2024-08-05

489 每月下载量
用于 4 crates

Apache-2.0LGPL-3.0

1MB
606

rust-spice

logo image

crate badge doc badge license badge pre-commit badge coverage doc badge coverage test badge

哇!NASA/NAIF Spice工具包的完整实现现在可以在Rust上使用


简介 | 需求 | 使用 | 实战 | 开发中 | 多线程使用 | 路线图 | 贡献者 | 许可证


简介

SPICE空间科学任务观测几何系统。访问他们的 网站

需求

  1. 为您所在的平台安装 CSPICE库
  2. 设置环境变量 CSPICE_DIR 为您的CSPICE安装文件夹(其中包含CSPICE子文件夹 includelib。您可以在 Cargo配置 中这样做)。
  3. 在Unix系统的 cspice/lib 文件夹中,您可能需要将静态库重命名为符合标准: cspice.a -> libcspice.a

请参阅 cspice-sys 库的其它需求,该库提供了对CSPICE的不安全绑定。

使用

将依赖项 rust-spice 添加到您的 Cargo.toml

[dependencies]
rust-spice = "*" # replace * by the latest version of the crate

cspice-sys 库依赖于Clang,它可能不在您的系统中可用。在这种情况下,您可以使用功能 noclang

[dependencies]
rust-spice = {version = "*", default-features = false, features = ["noclang"] }

来启用 lock 功能(见 ## 多线程使用)。

[dependencies]
rust-spice = {version = "*", features = ["lock"] }

实战

Spice的一个优雅且符合习惯的接口,

use spice;

let mut kernel = spice::furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");

let et = spice::str2et("2027-MAR-23 16:00:00");
let (position, light_time) = spice::spkpos("DIMORPHOS", et, "J2000", "NONE", "SUN");

// position -> 18.62640405424448, 21.054373008357004, -7.136291402940499
// light time -> 0.00009674257074746383

spice::kclear();

您可以在 核心测试 中寻找一些灵感。

这个用作示例的数据集可以从 这里 下载。

开发中

在Rust中为Spice开发惯用界面需要时间,并且并非所有功能都尚未实现。在在线文档中,一个完整的指南详细说明了哪些功能可用。如果你的不是,你始终可以使用包含所有cspice函数的不安全API。

例如,使用不安全API,上面的示例将是:

use spice;
use std::ffi::CString;

unsafe {
    let kernel = CString::new("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm").unwrap().into_raw();
    spice::c::furnsh_c(kernel);

    let mut et = 0.0;
    let date = CString::new("2027-MAR-23 16:00:00").unwrap().into_raw();
    spice::c::str2et_c(date, &mut et);

    let target_c = CString::new("DIMORPHOS").unwrap().into_raw();
    let frame_c = CString::new("J2000").unwrap().into_raw();
    let abcorr_c = CString::new("NONE").unwrap().into_raw();
    let observer_c = CString::new("SUN").unwrap().into_raw();
    let mut light_time = 0.0;
    let mut position = [0.0, 0.0, 0.0];
    spice::c::spkpos_c(
        target_c,
        et,
        frame_c,
        abcorr_c,
        observer_c,
        &mut position[0],
        &mut light_time,
    );

    spice::c::kclear_c();
}

不那么友好..但是它是可用的。我非常希望有人能帮忙完成惯用开发。你可以提出一个问题或提出一个特定功能的实现pull request。

多线程使用

CSPICE本身包含大量的共享可变状态,因此不是线程安全的 - 对任何SPICE函数的并发调用几乎总是会导致崩溃。为了避免这种情况,如果您需要从多个线程调用SPICE函数,此crate提供了一个具有lock功能的线程安全API。启用时,API以在guard singleton SpiceLock上的关联函数的形式暴露,它是!Sync + Send。然后您只能通过一个Mutex共享此singleton及其提供的方法,从而防止并发API使用。

锁公开了可用的neat版本的函数,以及其余的raw版本。对于既没有neat版本也没有raw版本的函数,您必须使用不安全(且未受保护)的直接C绑定。只需确保在调用它们之前有锁即可。

# #[cfg(feature = "lock")]
# {
use spice::SpiceLock;

// `try_acquire` will return `Err` if a lock already exists
let sl = SpiceLock::try_acquire().unwrap();

// SPICE functions are now associated functions of the lock with a `&self` arg
let mut kernel = sl.furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");

let et = sl.str2et("2027-MAR-23 16:00:00");
let (position, light_time) = sl.spkpos("DIMORPHOS", et, "J2000", "NONE", "SUN");

sl.kclear();
# }

路线图

  • 提供测试资源的打包
  • 完成最常用的API
  • 完成整个API
  • 过程宏的重构
  • Cell的重构

贡献者

名人堂

对他们的贡献表示衷心的感谢!!

许可证

根据Apache License, Version 2.0许可。

依赖项

~6–15MB
~194K SLoC