workspace: initialize workspace with all layer crates

This commit is contained in:
ApsisRS contributors 2026-09-26 12:53:13 +08:00
commit 539f29c7b5
93 changed files with 1613 additions and 0 deletions

31
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,31 @@
name: CI
on:
push:
pull_request:
env:
CARGO_TERM_COLOR: always
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Format
run: cargo fmt --all --check
- name: Check
run: cargo check --workspace --all-targets
- name: Clippy
run: cargo clippy --workspace --all-targets -- -D warnings
- name: Test
run: cargo test --workspace
- name: Verify dependency freedom
run: |
if cargo tree --workspace --edges normal,build 2>/dev/null | grep -v '^apsis' | grep -q '('; then
echo "unexpected external dependency detected" >&2
exit 1
fi

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

209
Cargo.lock generated Normal file
View File

@ -0,0 +1,209 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "apsis-access"
version = "0.1.0"
[[package]]
name = "apsis-antenna"
version = "0.1.0"
[[package]]
name = "apsis-atmosphere"
version = "0.1.0"
[[package]]
name = "apsis-conflict"
version = "0.1.0"
[[package]]
name = "apsis-constellation"
version = "0.1.0"
[[package]]
name = "apsis-coord"
version = "0.1.0"
[[package]]
name = "apsis-core"
version = "0.1.0"
[[package]]
name = "apsis-coverage"
version = "0.1.0"
[[package]]
name = "apsis-doppler"
version = "0.1.0"
[[package]]
name = "apsis-ephemeris"
version = "0.1.0"
[[package]]
name = "apsis-event"
version = "0.1.0"
[[package]]
name = "apsis-frames"
version = "0.1.0"
[[package]]
name = "apsis-geodesy"
version = "0.1.0"
[[package]]
name = "apsis-handover"
version = "0.1.0"
[[package]]
name = "apsis-interference"
version = "0.1.0"
[[package]]
name = "apsis-isl"
version = "0.1.0"
[[package]]
name = "apsis-kepler"
version = "0.1.0"
[[package]]
name = "apsis-leap"
version = "0.1.0"
[[package]]
name = "apsis-link"
version = "0.1.0"
[[package]]
name = "apsis-macros"
version = "0.1.0"
[[package]]
name = "apsis-maneuver"
version = "0.1.0"
[[package]]
name = "apsis-math"
version = "0.1.0"
[[package]]
name = "apsis-mesh"
version = "0.1.0"
[[package]]
name = "apsis-noise"
version = "0.1.0"
[[package]]
name = "apsis-orbit"
version = "0.1.0"
[[package]]
name = "apsis-output"
version = "0.1.0"
[[package]]
name = "apsis-resource"
version = "0.1.0"
[[package]]
name = "apsis-rf"
version = "0.1.0"
[[package]]
name = "apsis-routing"
version = "0.1.0"
[[package]]
name = "apsis-rs"
version = "0.1.0"
dependencies = [
"apsis-access",
"apsis-antenna",
"apsis-atmosphere",
"apsis-conflict",
"apsis-constellation",
"apsis-coord",
"apsis-core",
"apsis-coverage",
"apsis-doppler",
"apsis-ephemeris",
"apsis-event",
"apsis-frames",
"apsis-geodesy",
"apsis-handover",
"apsis-interference",
"apsis-isl",
"apsis-kepler",
"apsis-leap",
"apsis-link",
"apsis-macros",
"apsis-maneuver",
"apsis-math",
"apsis-mesh",
"apsis-noise",
"apsis-orbit",
"apsis-output",
"apsis-resource",
"apsis-rf",
"apsis-routing",
"apsis-scenario",
"apsis-schedule",
"apsis-scheduler",
"apsis-sgp4",
"apsis-sim",
"apsis-sim-engine",
"apsis-task",
"apsis-time",
"apsis-tle",
"apsis-topology",
"apsis-units",
]
[[package]]
name = "apsis-scenario"
version = "0.1.0"
[[package]]
name = "apsis-schedule"
version = "0.1.0"
[[package]]
name = "apsis-scheduler"
version = "0.1.0"
[[package]]
name = "apsis-sgp4"
version = "0.1.0"
[[package]]
name = "apsis-sim"
version = "0.1.0"
[[package]]
name = "apsis-sim-engine"
version = "0.1.0"
[[package]]
name = "apsis-task"
version = "0.1.0"
[[package]]
name = "apsis-time"
version = "0.1.0"
[[package]]
name = "apsis-tle"
version = "0.1.0"
[[package]]
name = "apsis-topology"
version = "0.1.0"
[[package]]
name = "apsis-units"
version = "0.1.0"

126
Cargo.toml Normal file
View File

@ -0,0 +1,126 @@
# ApsisRS Rust workspace root.
#
# The workspace resolves without any external dependency so that the
# numerical kernels stay self-contained and auditable. Every member crate
# is unpublished.
[workspace]
resolver = "2"
members = [
# foundation
"crates/foundation/apsis-core",
"crates/foundation/apsis-units",
"crates/foundation/apsis-math",
"crates/foundation/apsis-macros",
# physics
"crates/physics/apsis-time",
"crates/physics/apsis-leap",
"crates/physics/apsis-coord",
"crates/physics/apsis-geodesy",
"crates/physics/apsis-frames",
# orbit
"crates/orbit/apsis-tle",
"crates/orbit/apsis-sgp4",
"crates/orbit/apsis-kepler",
"crates/orbit/apsis-ephemeris",
"crates/orbit/apsis-maneuver",
"crates/orbit/apsis-orbit",
# rf
"crates/rf/apsis-rf",
"crates/rf/apsis-antenna",
"crates/rf/apsis-doppler",
"crates/rf/apsis-atmosphere",
"crates/rf/apsis-noise",
"crates/rf/apsis-interference",
"crates/rf/apsis-link",
# network
"crates/network/apsis-constellation",
"crates/network/apsis-coverage",
"crates/network/apsis-access",
"crates/network/apsis-topology",
"crates/network/apsis-isl",
"crates/network/apsis-routing",
"crates/network/apsis-handover",
"crates/network/apsis-mesh",
# ops
"crates/ops/apsis-resource",
"crates/ops/apsis-task",
"crates/ops/apsis-scheduler",
"crates/ops/apsis-conflict",
"crates/ops/apsis-schedule",
# sim
"crates/sim/apsis-sim-engine",
"crates/sim/apsis-scenario",
"crates/sim/apsis-event",
"crates/sim/apsis-output",
"crates/sim/apsis-sim",
# facade
"crates/apsis-rs",
]
[workspace.package]
version = "0.1.0"
edition = "2024"
rust-version = "1.85"
license = "MIT OR Apache-2.0"
authors = ["ApsisRS contributors"]
[workspace.lints.rust]
unsafe_code = "forbid"
missing_docs = "deny"
[workspace.dependencies]
apsis-core = { path = "crates/foundation/apsis-core" }
apsis-units = { path = "crates/foundation/apsis-units" }
apsis-math = { path = "crates/foundation/apsis-math" }
apsis-macros = { path = "crates/foundation/apsis-macros" }
apsis-time = { path = "crates/physics/apsis-time" }
apsis-leap = { path = "crates/physics/apsis-leap" }
apsis-coord = { path = "crates/physics/apsis-coord" }
apsis-geodesy = { path = "crates/physics/apsis-geodesy" }
apsis-frames = { path = "crates/physics/apsis-frames" }
apsis-tle = { path = "crates/orbit/apsis-tle" }
apsis-sgp4 = { path = "crates/orbit/apsis-sgp4" }
apsis-kepler = { path = "crates/orbit/apsis-kepler" }
apsis-ephemeris = { path = "crates/orbit/apsis-ephemeris" }
apsis-maneuver = { path = "crates/orbit/apsis-maneuver" }
apsis-orbit = { path = "crates/orbit/apsis-orbit" }
apsis-rf = { path = "crates/rf/apsis-rf" }
apsis-antenna = { path = "crates/rf/apsis-antenna" }
apsis-doppler = { path = "crates/rf/apsis-doppler" }
apsis-atmosphere = { path = "crates/rf/apsis-atmosphere" }
apsis-noise = { path = "crates/rf/apsis-noise" }
apsis-interference = { path = "crates/rf/apsis-interference" }
apsis-link = { path = "crates/rf/apsis-link" }
apsis-constellation = { path = "crates/network/apsis-constellation" }
apsis-coverage = { path = "crates/network/apsis-coverage" }
apsis-access = { path = "crates/network/apsis-access" }
apsis-topology = { path = "crates/network/apsis-topology" }
apsis-isl = { path = "crates/network/apsis-isl" }
apsis-routing = { path = "crates/network/apsis-routing" }
apsis-handover = { path = "crates/network/apsis-handover" }
apsis-mesh = { path = "crates/network/apsis-mesh" }
apsis-resource = { path = "crates/ops/apsis-resource" }
apsis-task = { path = "crates/ops/apsis-task" }
apsis-scheduler = { path = "crates/ops/apsis-scheduler" }
apsis-conflict = { path = "crates/ops/apsis-conflict" }
apsis-schedule = { path = "crates/ops/apsis-schedule" }
apsis-sim-engine = { path = "crates/sim/apsis-sim-engine" }
apsis-scenario = { path = "crates/sim/apsis-scenario" }
apsis-event = { path = "crates/sim/apsis-event" }
apsis-output = { path = "crates/sim/apsis-output" }
apsis-sim = { path = "crates/sim/apsis-sim" }

202
LICENSE-APACHE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

21
LICENSE-MIT Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 ApsisRS contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

78
README.md Normal file
View File

@ -0,0 +1,78 @@
# ApsisRS / 拱点
商业航天与卫星互联网领域的 Rust 计算内核。
## 定位
- 纯 Rust、`std`、零第三方 crate 依赖
- 领域边界清晰,按层单向依赖
- 对外门面 crate 名为 `apsis-rs`,库名为 `apsis`
- 当前阶段所有 crate 均 `publish = false`,不执行发布
## 分层
```text
foundation -> physics -> orbit -> rf -> network -> ops -> sim -> apsis-rs
```
约束:
- 依赖只能从左向右
- 禁止跨层跳跃,例如 `orbit` 不得直接依赖 `network`
- 禁止同层平级依赖
各层内容:
| 层 | 职责 | crates |
| --- | --- | --- |
| foundation | 基础类型、单位、数学、宏 | `apsis-core`、`apsis-units`、`apsis-math`、`apsis-macros` |
| physics | 时间、闰秒、坐标、大地基准 | `apsis-time`、`apsis-leap`、`apsis-coord`、`apsis-geodesy`、`apsis-frames` |
| orbit | TLE、SGP4、二体、星历、机动 | `apsis-tle`、`apsis-sgp4`、`apsis-kepler`、`apsis-ephemeris`、`apsis-maneuver`、`apsis-orbit` |
| rf | 射频、天线、链路预算 | `apsis-rf`、`apsis-antenna`、`apsis-doppler`、`apsis-atmosphere`、`apsis-noise`、`apsis-interference`、`apsis-link` |
| network | 星座、覆盖、接入、拓扑、路由 | `apsis-constellation`、`apsis-coverage`、`apsis-access`、`apsis-topology`、`apsis-isl`、`apsis-routing`、`apsis-handover`、`apsis-mesh` |
| ops | 资源、任务、调度、冲突、计划 | `apsis-resource`、`apsis-task`、`apsis-scheduler`、`apsis-conflict`、`apsis-schedule` |
| sim | 仿真引擎、场景、事件、输出 | `apsis-sim-engine`、`apsis-scenario`、`apsis-event`、`apsis-output`、`apsis-sim` |
| facade | 对外门面 | `apsis-rs` |
## 构建
所有 Rust 命令在仓库根目录执行:
```bash
cargo check --workspace
cargo test -p apsis-core -p apsis-units -p apsis-math
```
`apsis-rs` 门面通过 feature 选择需要的层,例如:
```toml
[dependencies]
apsis-rs = { path = "...", features = ["orbit"] }
```
可选 feature:`foundation`、`physics`、`orbit`、`rf`、`network`、`ops`、`sim`、`full`。
每个层 feature 自动启用其下层。`full` 启用全部层(含 `sim`);`ops` 等价于除
`sim` 以外的所有层,适合不运行仿真的项目。
## 约定
- toolchain:`stable`,`edition 2024`,`rust-version 1.85`
- 默认禁止任何第三方 crate,包括开发依赖与 `build.rs`
- 库代码不使用 `unwrap()` / `expect()` / `panic!` / `unsafe`
- 公共 API 必须有文档注释,注释自包含
## 目录
```text
apsis-rs/
├── Cargo.toml
├── crates/ # Rust 工作区成员
├── tests/ # 集成测试
├── benches/ # 基准测试
├── validation/ # Python 对拍验证
└── docs/design/ # 设计文档
```
## 许可
MIT OR Apache-2.0,见 `LICENSE-MIT` 与 `LICENSE-APACHE`。

140
crates/apsis-rs/Cargo.toml Normal file
View File

@ -0,0 +1,140 @@
[package]
name = "apsis-rs"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Public facade for the ApsisRS computational kernels."
publish = false
[lib]
name = "apsis"
path = "src/lib.rs"
[lints]
workspace = true
[features]
default = []
# Enabling a layer also enables the layers it is allowed to depend on.
foundation = [
"dep:apsis-core",
"dep:apsis-units",
"dep:apsis-math",
"dep:apsis-macros",
]
physics = [
"foundation",
"dep:apsis-time",
"dep:apsis-leap",
"dep:apsis-coord",
"dep:apsis-geodesy",
"dep:apsis-frames",
]
orbit = [
"physics",
"dep:apsis-tle",
"dep:apsis-sgp4",
"dep:apsis-kepler",
"dep:apsis-ephemeris",
"dep:apsis-maneuver",
"dep:apsis-orbit",
]
rf = [
"orbit",
"dep:apsis-rf",
"dep:apsis-antenna",
"dep:apsis-doppler",
"dep:apsis-atmosphere",
"dep:apsis-noise",
"dep:apsis-interference",
"dep:apsis-link",
]
network = [
"rf",
"dep:apsis-constellation",
"dep:apsis-coverage",
"dep:apsis-access",
"dep:apsis-topology",
"dep:apsis-isl",
"dep:apsis-routing",
"dep:apsis-handover",
"dep:apsis-mesh",
]
ops = [
"network",
"dep:apsis-resource",
"dep:apsis-task",
"dep:apsis-scheduler",
"dep:apsis-conflict",
"dep:apsis-schedule",
]
# The simulation layer aggregates every other layer, so it enables `ops`.
# Enable `ops` instead of `full` when the simulation layer is not needed.
sim = [
"ops",
"dep:apsis-sim-engine",
"dep:apsis-scenario",
"dep:apsis-event",
"dep:apsis-output",
"dep:apsis-sim",
]
# Every layer, including `sim`. Enabling `sim` pulls in `ops` and, through
# it, every lower layer.
full = ["sim"]
[dependencies]
apsis-core = { workspace = true, optional = true }
apsis-units = { workspace = true, optional = true }
apsis-math = { workspace = true, optional = true }
apsis-macros = { workspace = true, optional = true }
apsis-time = { workspace = true, optional = true }
apsis-leap = { workspace = true, optional = true }
apsis-coord = { workspace = true, optional = true }
apsis-geodesy = { workspace = true, optional = true }
apsis-frames = { workspace = true, optional = true }
apsis-tle = { workspace = true, optional = true }
apsis-sgp4 = { workspace = true, optional = true }
apsis-kepler = { workspace = true, optional = true }
apsis-ephemeris = { workspace = true, optional = true }
apsis-maneuver = { workspace = true, optional = true }
apsis-orbit = { workspace = true, optional = true }
apsis-rf = { workspace = true, optional = true }
apsis-antenna = { workspace = true, optional = true }
apsis-doppler = { workspace = true, optional = true }
apsis-atmosphere = { workspace = true, optional = true }
apsis-noise = { workspace = true, optional = true }
apsis-interference = { workspace = true, optional = true }
apsis-link = { workspace = true, optional = true }
apsis-constellation = { workspace = true, optional = true }
apsis-coverage = { workspace = true, optional = true }
apsis-access = { workspace = true, optional = true }
apsis-topology = { workspace = true, optional = true }
apsis-isl = { workspace = true, optional = true }
apsis-routing = { workspace = true, optional = true }
apsis-handover = { workspace = true, optional = true }
apsis-mesh = { workspace = true, optional = true }
apsis-resource = { workspace = true, optional = true }
apsis-task = { workspace = true, optional = true }
apsis-scheduler = { workspace = true, optional = true }
apsis-conflict = { workspace = true, optional = true }
apsis-schedule = { workspace = true, optional = true }
apsis-sim-engine = { workspace = true, optional = true }
apsis-scenario = { workspace = true, optional = true }
apsis-event = { workspace = true, optional = true }
apsis-output = { workspace = true, optional = true }
apsis-sim = { workspace = true, optional = true }

160
crates/apsis-rs/src/lib.rs Normal file
View File

@ -0,0 +1,160 @@
//! ApsisRS: computational kernels for commercial spaceflight and satellite
//! internet systems.
//!
//! The workspace is organized into dependency-ordered layers:
//!
//! ```text
//! foundation -> physics -> orbit -> rf -> network -> ops -> sim
//! ```
//!
//! Dependencies flow in one direction only. A layer may use the layers to
//! its left but never the layers to its right.
//!
//! This crate is the public facade named `apsis-rs`. Downstream projects
//! depend on it directly and enable the feature that matches the layers they
//! need. Each feature re-exports the crates of one layer and pulls in the
//! features of the layers below it. For example, the `orbit` feature enables
//! `physics` and re-exports [`apsis_orbit`], [`apsis_tle`], [`apsis_sgp4`],
//! [`apsis_kepler`], and [`apsis_ephemeris`].
//!
//! The `full` feature enables every layer, including `sim`. Because `sim`
//! aggregates all other layers and is only needed by simulation workloads,
//! projects that do not run simulations can enable `ops` instead, which
//! enables every layer except `sim`.
#![forbid(unsafe_code)]
#![deny(missing_docs)]
// foundation
#[cfg(feature = "foundation")]
pub use apsis_core;
#[cfg(feature = "foundation")]
pub use apsis_macros;
#[cfg(feature = "foundation")]
pub use apsis_math;
#[cfg(feature = "foundation")]
pub use apsis_units;
// physics
#[cfg(feature = "physics")]
pub use apsis_coord;
#[cfg(feature = "physics")]
pub use apsis_frames;
#[cfg(feature = "physics")]
pub use apsis_geodesy;
#[cfg(feature = "physics")]
pub use apsis_leap;
#[cfg(feature = "physics")]
pub use apsis_time;
// orbit
#[cfg(feature = "orbit")]
pub use apsis_ephemeris;
#[cfg(feature = "orbit")]
pub use apsis_kepler;
#[cfg(feature = "orbit")]
pub use apsis_maneuver;
#[cfg(feature = "orbit")]
pub use apsis_orbit;
#[cfg(feature = "orbit")]
pub use apsis_sgp4;
#[cfg(feature = "orbit")]
pub use apsis_tle;
// rf
#[cfg(feature = "rf")]
pub use apsis_antenna;
#[cfg(feature = "rf")]
pub use apsis_atmosphere;
#[cfg(feature = "rf")]
pub use apsis_doppler;
#[cfg(feature = "rf")]
pub use apsis_interference;
#[cfg(feature = "rf")]
pub use apsis_link;
#[cfg(feature = "rf")]
pub use apsis_noise;
#[cfg(feature = "rf")]
pub use apsis_rf;
// network
#[cfg(feature = "network")]
pub use apsis_access;
#[cfg(feature = "network")]
pub use apsis_constellation;
#[cfg(feature = "network")]
pub use apsis_coverage;
#[cfg(feature = "network")]
pub use apsis_handover;
#[cfg(feature = "network")]
pub use apsis_isl;
#[cfg(feature = "network")]
pub use apsis_mesh;
#[cfg(feature = "network")]
pub use apsis_routing;
#[cfg(feature = "network")]
pub use apsis_topology;
// ops
#[cfg(feature = "ops")]
pub use apsis_conflict;
#[cfg(feature = "ops")]
pub use apsis_resource;
#[cfg(feature = "ops")]
pub use apsis_schedule;
#[cfg(feature = "ops")]
pub use apsis_scheduler;
#[cfg(feature = "ops")]
pub use apsis_task;
// sim
#[cfg(feature = "sim")]
pub use apsis_event;
#[cfg(feature = "sim")]
pub use apsis_output;
#[cfg(feature = "sim")]
pub use apsis_scenario;
#[cfg(feature = "sim")]
pub use apsis_sim;
#[cfg(feature = "sim")]
pub use apsis_sim_engine;

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-core"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Shared foundation types for the ApsisRS workspace: error traits, result aliases, and common physical constants."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Shared foundation types for the ApsisRS workspace: error traits, result aliases, and common physical constants.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-macros"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Macros that support the ApsisRS workspace."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Macros that support the ApsisRS workspace.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-math"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Dependency-free vector, quaternion, and matrix types used across the ApsisRS workspace."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Dependency-free vector, quaternion, and matrix types used across the ApsisRS workspace.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-units"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Strongly typed newtypes for physical quantities such as meters, seconds, hertz, radians, and degrees."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Strongly typed newtypes for physical quantities such as meters, seconds, hertz, radians, and degrees.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-access"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Ground station to satellite access window computation."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Ground station to satellite access window computation.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-constellation"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Constellation definition and instantiation."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Constellation definition and instantiation.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-coverage"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Ground and regional coverage analysis."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Ground and regional coverage analysis.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-handover"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Handover decision logic for mobile terminals."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Handover decision logic for mobile terminals.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-isl"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Inter-satellite link modeling."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Inter-satellite link modeling.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-mesh"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Mesh connectivity abstractions."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Mesh connectivity abstractions.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-routing"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Routing over time-varying satellite topologies."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Routing over time-varying satellite topologies.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-topology"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Time-varying network topology modeling."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Time-varying network topology modeling.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-conflict"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Resource and time conflict detection."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Resource and time conflict detection.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-resource"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Resource modeling for satellite operations."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Resource modeling for satellite operations.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-schedule"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Schedule representation and evaluation."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Schedule representation and evaluation.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-scheduler"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Scheduling algorithms for satellite task planning."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Scheduling algorithms for satellite task planning.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-task"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Task modeling for satellite operations."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Task modeling for satellite operations.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-ephemeris"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Ephemeris sampling and interpolation."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Ephemeris sampling and interpolation.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-kepler"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Keplerian orbital elements and two-body propagation."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Keplerian orbital elements and two-body propagation.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-maneuver"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Impulsive and finite orbital maneuver models."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Impulsive and finite orbital maneuver models.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-orbit"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Orbital state facade that integrates the orbit layer."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Orbital state facade that integrates the orbit layer.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-sgp4"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "SGP4/SDP4 analytical orbit propagator."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! SGP4/SDP4 analytical orbit propagator.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-tle"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Two-Line Element set parsing."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Two-Line Element set parsing.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-coord"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Coordinate frame markers and Earth-centered inertial, Earth-centered Earth-fixed, and geodetic transformations."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Coordinate frame markers and Earth-centered inertial, Earth-centered Earth-fixed, and geodetic transformations.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-frames"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Reference frame definitions and transformation primitives."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Reference frame definitions and transformation primitives.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-geodesy"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Reference ellipsoids and geodetic computations."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Reference ellipsoids and geodetic computations.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-leap"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Embedded leap second table and UTC/TAI time scale conversion."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Embedded leap second table and UTC/TAI time scale conversion.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-time"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Time scales, epochs, and Julian date conversions."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Time scales, epochs, and Julian date conversions.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-antenna"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Antenna radiation patterns and gain models."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Antenna radiation patterns and gain models.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-atmosphere"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Atmospheric attenuation and refraction models."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Atmospheric attenuation and refraction models.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-doppler"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Doppler shift computation."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Doppler shift computation.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-interference"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Interference and carrier-to-interference computation."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Interference and carrier-to-interference computation.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-link"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Link budget computation."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Link budget computation.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-noise"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Noise temperature and noise figure models."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Noise temperature and noise figure models.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-rf"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Core radio frequency primitives."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Core radio frequency primitives.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-event"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Simulation event types and event queue."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Simulation event types and event queue.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-output"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Simulation output recording."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Simulation output recording.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-scenario"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Scenario definition and loading."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Scenario definition and loading.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-sim-engine"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Discrete-event simulation engine."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Discrete-event simulation engine.

View File

@ -0,0 +1,13 @@
[package]
name = "apsis-sim"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Simulation facade that integrates the simulation layer."
publish = false
[lints]
workspace = true
[dependencies]

View File

@ -0,0 +1 @@
//! Simulation facade that integrates the simulation layer.

6
docs/design/README.md Normal file
View File

@ -0,0 +1,6 @@
# 设计文档
本目录记录 ApsisRS 的跨 crate 设计决策,例如坐标约定、单位约定、误差策略与
分层边界。单个 crate 的内部设计写在对应 crate 的模块文档中。
文档内容需自包含,仅引用本仓库内的代码或可公开访问的标准。

3
rust-toolchain.toml Normal file
View File

@ -0,0 +1,3 @@
[toolchain]
channel = "stable"
components = ["rustfmt", "clippy"]

57
validation/README.md Normal file
View File

@ -0,0 +1,57 @@
# 对拍验证
本目录用于 Rust 实现与公开参考实现的数值对拍。Python 侧仅作验证用途,
不属于 Rust 依赖。
## Python 环境
使用 [pixi](https://pixi.sh/) 管理。允许的库:
- `sgp4`:SGP4 传播对拍
- `astropy`:时间、坐标对拍
- `numpy`:数值计算
- `skyfield`:轨道、可见性对拍(可选)
引入新的 Python 库前需要评估并确认。
## 目录
```text
validation/
├── pixi.toml
├── python/
│ ├── orbit/ # SGP4、开普勒对拍
│ ├── time/ # 时间尺度、儒略日对拍
│ ├── coord/ # 坐标变换对拍
│ ├── link/ # 链路预算对拍
│ └── constellation/ # 星座覆盖对拍
└── data/
├── tle/ # 公开 TLE 样本
└── expected/ # Python 生成的参考值
```
## 流程
1. Rust 侧导出输入与输出,格式为简单 CSV 或 TXT,不使用 serde:
```bash
cargo run -p apsis-rs --example dump_orbit > validation/data/rust_output.csv
```
2. Python 侧读取同一输入并计算参考值:
```bash
pixi run python validation/python/orbit/check_sgp4.py
```
3. 比较误差:
| 量 | 容差 |
| --- | --- |
| 位置 | < 1e-3 km |
| 速度 | < 1e-6 km/s |
| 时间 | < 1e-6 s |
超差时修正 Rust 侧算法,不放宽容差,除非经确认。
每个脚本必须可独立离线运行,不访问网络。

19
validation/pixi.toml Normal file
View File

@ -0,0 +1,19 @@
[project]
name = "apsis-validation"
version = "0.1.0"
description = "Reference-implementation cross-checks for the ApsisRS numerical kernels."
channels = ["conda-forge"]
platforms = ["linux-64", "osx-arm64", "win-64"]
[dependencies]
python = "3.12.*"
# Reference implementations used only for cross-checking Rust output.
# These packages are not dependencies of any Rust crate.
[pypi-dependencies]
numpy = "*"
sgp4 = "*"
astropy = "*"
skyfield = "*"
[tasks]