-
Notifications
You must be signed in to change notification settings - Fork 0
Gemini docs #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Gemini docs #36
Changes from 1 commit
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
a60d03f
Gemini docs
ChristopherRabotin 3658d01
More gemini docs!
ChristopherRabotin 38f4e13
Add llms.txt to the website.
google-labs-jules[bot] dfd9008
Update llms.txt with documentation structure.
google-labs-jules[bot] ec1fe79
Merge pull request #37 from nyx-space/jules/add-llms-txt-108813584524…
ChristopherRabotin ccb5524
Update docs/anise/reference/orbit.md
ChristopherRabotin 12a605e
Enhance Almanac documentation with additional data types
ChristopherRabotin a8a2d7c
Enhance serialization details and add visibility arcs report
ChristopherRabotin 3018218
Enhance frame safety documentation in ANISE
ChristopherRabotin 2e4e471
Update validation section for accuracy description
ChristopherRabotin 4297eef
Update why-anise.md
ChristopherRabotin c6ccffe
Enhance Almanac reference documentation
ChristopherRabotin 24fa509
Remove expressions sections from analysis-api.md
ChristopherRabotin a8b6327
Rename 'mu' to 'mu_km3_s2' in frame metadata
ChristopherRabotin 741e7e7
Enhance Orbit initialization documentation
ChristopherRabotin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # The Almanac and the Context Pattern | ||
|
|
||
| In most legacy astrodynamics toolkits, loading "kernels" (data files) is a global operation. When you load a file, it enters a global memory pool accessible by any function in your program. This "Global State" pattern makes it extremely difficult to write concurrent code or to manage different scenarios in a single application. | ||
|
|
||
| ## The Almanac as a Container | ||
|
|
||
| ANISE replaces the global pool with the `Almanac`. An `Almanac` is a self-contained object that stores: | ||
| - Ephemeris data (SPK) | ||
| - Orientation data (BPC, PCK) | ||
| - Frame relationship data (FK) | ||
| - Mathematical constants (TPC) | ||
|
|
||
| ```rust | ||
| // In ANISE, you manage your own context | ||
| let mut almanac = Almanac::default(); | ||
| almanac.load("de440.bsp")?; | ||
| ``` | ||
|
|
||
| Because the `Almanac` is an object, you can have as many as you want. One thread can work with a high-fidelity Earth model stored in `almanac_A`, while another thread performs long-term trajectory analysis using a simplified model in `almanac_B`. | ||
|
|
||
| ## Immutable Sharing and Cheap Clones | ||
|
|
||
| A common concern with moving away from global state is the overhead of passing around a large context object. ANISE solves this through its memory management: | ||
|
|
||
| 1. **Zero-Copy**: When you load a kernel into an `Almanac`, the data is typically memory-mapped. | ||
| 2. **Shared Data**: Internally, the `Almanac` uses reference-counting or shared buffers. | ||
| 3. **Cheap Clones**: Cloning an `Almanac` does not copy the gigabytes of ephemeris data; it simply creates a new handle to the same underlying memory. | ||
|
|
||
| This allows you to pass the `Almanac` into parallel loops (e.g., using `rayon` in Rust) with near-zero overhead. | ||
|
|
||
| ## The Search Engine | ||
|
|
||
| The `Almanac` acts as a search engine for your data. When you ask for the position of Mars relative to Earth, the `Almanac`: | ||
| 1. Looks up the IDs for Earth and Mars. | ||
| 2. Traverses the ephemeris tree to find a common ancestor. | ||
| 3. Chains together the necessary translations from the loaded SPK segments. | ||
| 4. Returns the result as a high-precision state vector. | ||
|
|
||
| By centralizing this logic in a thread-safe object, ANISE provides a clean API that hides the complexity of multi-segment, multi-file lookups. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # Frame Safety and Graph Lookups | ||
|
|
||
| In space mission design, one of the most common sources of error is the misuse of reference frames. Forgetting to rotate from a body-fixed frame to an inertial frame, or confusing two different inertial frames (like J2000 and EME2000), can lead to mission-critical failures. | ||
|
|
||
| ANISE introduces the concept of **Frame Safety** to eliminate these errors. | ||
|
|
||
| ## Frames are Not Just IDs | ||
|
|
||
| In the SPICE toolkit, frames are often referred to by integer IDs. While ANISE maintains compatibility with NAIF IDs, it treats Frames as rich objects. | ||
|
|
||
| Every Frame in ANISE has a type and a relationship to other frames: | ||
| - **Celestial**: Inertial frames like J2000 / ICRF. | ||
| - **Planetocentric**: Body-fixed frames like ITRF93 (Earth) or IAU_MOON. | ||
| - **Topocentric**: Frames defined at a specific location on a body's surface (e.g., SEZ frame at a tracking station). | ||
|
|
||
| ## Validation Before Computation | ||
|
|
||
| When you request a transformation in ANISE, the toolkit doesn't just blindly multiply matrices. It performs a **Frame Check**. | ||
|
|
||
| Before any computation: | ||
| 1. ANISE checks that the target and observer frames are part of the same "graph" (they have a path between them). | ||
| 2. It ensures the transformation is physically valid (e.g., you aren't trying to rotate between two frames that don't have a defined orientation relationship). | ||
| 3. It identifies the "Common Ancestor"—the point in the frame tree where the paths from the two frames meet. | ||
|
|
||
| ## Tree Traversal and Path Finding | ||
|
|
||
| ANISE represents the relationship between frames as a directed acyclic graph (DAG), but for most practical purposes, it behaves like a tree. | ||
|
|
||
| When transforming from Frame A to Frame B: | ||
| - **Translation Path**: Finds the common ephemeris ancestor (e.g., the Solar System Barycenter) and sums the vectors along the branches. | ||
| - **Rotation Path**: Finds the common orientation ancestor and composes the Direction Cosine Matrices (DCMs) or Quaternions. | ||
|
|
||
| If a path cannot be found (e.g., you haven't loaded the necessary FK or PCK files), ANISE returns a clear error at the start of the query, rather than producing junk data or crashing with a segfault. | ||
|
|
||
| ## The `Frame` Object | ||
|
|
||
| In the ANISE API, a `Frame` object carries its metadata with it. When you build an `Orbit`, it is attached to a specific `Frame`. When you transform that `Orbit` to a new frame, ANISE uses the metadata to ensure the transformation is accurate, including handling the necessary time conversions for body-fixed rotations. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,10 @@ | ||
| > Explanation is a discusive treatment of a subject, that permits reflection. Explanation is **understanding-oriented**. | ||
| -- [_Diataxis_](https://www.diataxis.fr/tutorials/) | ||
|
|
||
| This section delves into the design of ANISE, how it is validated, and how its results may very minutely differ from those of the SPICE toolkit but why you should actually trust ANISE instead. | ||
| This section delves into the design of ANISE, its architecture, and the core concepts that make it a modern alternative to legacy toolkits. | ||
|
|
||
| - **[Why ANISE?](why-anise.md)**: A high-level overview of why ANISE was created and its advantages over toolkits like SPICE. | ||
| - **[The Almanac Pattern](almanac-and-context.md)**: Understanding the shift from global state to context-based data management. | ||
| - **[Frame Safety](frame-safety.md)**: Exploring how ANISE ensures physical validity through its frame graph and type system. | ||
| - **[Time Systems](time.md)**: How `hifitime` provides nanosecond precision without rounding errors. | ||
| - **[Validation](validation.md)**: How we ensure ANISE matches (or exceeds) the accuracy of the SPICE toolkit. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| # Why ANISE? | ||
|
|
||
| ANISE (Attitude, Navigation, Instrument, Spacecraft, Ephemeris) was born out of a need for a modern, high-performance, and thread-safe toolkit for space mission design and operations. While the NAIF SPICE toolkit has been the industry standard for decades, its architecture was designed for an era of single-threaded, procedural programming. | ||
|
|
||
| ## Designed for Modern Hardware | ||
|
|
||
| Modern computing environments, from high-performance workstations to cloud-based clusters, rely on multi-core processors. Legacy toolkits often struggle in these environments due to: | ||
|
|
||
| - **Global State**: SPICE uses a global kernel pool. This means you cannot easily load different sets of kernels for different threads or perform concurrent queries without complex locking mechanisms (mutexes) that severely bottleneck performance. | ||
| - **Thread Safety**: Because of its global state and internal cache mechanisms, SPICE is inherently NOT thread-safe. | ||
|
|
||
| **ANISE is thread-safe by design.** It eliminates global state by using the `Almanac` as a first-class object. You can create multiple `Almanac` instances, each with its own set of loaded kernels, and share them across threads safely. | ||
|
|
||
| ## Safety through Rust | ||
|
|
||
| By building on Rust, ANISE leverages a powerful type system and ownership model to provide guarantees that other toolkits cannot: | ||
|
|
||
| - **Memory Safety**: Rust prevents common bugs like null pointer dereferences, buffer overflows, and data races at compile time. | ||
| - **Frame Safety**: ANISE doesn't just treat frames as integer IDs. It understands the relationship between frames. It validates that any transformation (rotation or translation) you request is physically possible before even attempting the math. No more mixing up J2000 and ITRF93 by accident. | ||
|
|
||
| ## Precision and Performance | ||
|
|
||
| ANISE matches SPICE's mathematical precision—and in many cases, exceeds it. | ||
|
|
||
| - **Integer-based Time**: By using the `hifitime` library, ANISE avoids the rounding errors inherent in floating-point time representations (used by SPICE). This is particularly critical for high-fidelity planetary rotations where a few microseconds of error can accumulate over years. | ||
| - **Zero-copy Parsing**: ANISE uses memory-mapped files and zero-copy parsing techniques to load and query large kernel files (like DE440) with minimal memory overhead and maximum speed. | ||
|
|
||
| ## Multi-language from the Core | ||
|
|
||
| ANISE is an ecosystem. While the core engine is written in Rust for maximum performance, it is designed to be easily accessible from other languages. | ||
| - **Rust**: Native performance and type safety. | ||
| - **Python**: A pythonic API (`anise-py`) that feels familiar to users of `SpiceyPy` but offers the performance and safety of the Rust core. | ||
| - **CLI/GUI**: Tools for quick inspection and visualization that work cross-platform. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| # Almanac Reference | ||
|
|
||
| The `Almanac` is the primary interface for ANISE. It serves as the context for all ephemeris, orientation, and physical constant lookups. | ||
|
|
||
| ## Key Concepts | ||
|
|
||
| - **Thread Safety**: The `Almanac` is `Send + Sync`, meaning it can be safely shared across threads. | ||
| - **Data Encapsulation**: It stores loaded kernel data internally; there is no global pool. | ||
| - **Method Chaining**: Loading methods often use a builder pattern or return a new handle for easy initialization. | ||
|
|
||
| ## Loading Data | ||
|
|
||
| The `Almanac` supports loading various kernel types. You can load files directly or allow ANISE to "guess" the file type. | ||
|
|
||
| ### `load` | ||
| Loads any supported ANISE or SPICE file. | ||
| - **Rust**: `almanac.load("path/to/file")?` | ||
| - **Python**: `almanac.load("path/to/file")` | ||
|
|
||
| ### Specialized Loaders | ||
| If you know the file type, you can use specialized loaders for better performance or specific configuration: | ||
| - `with_spk(spk)`: Add SPK (ephemeris) data. | ||
| - `with_bpc(bpc)`: Add BPC (high-precision orientation) data. | ||
| - `with_planetary_data(pck)`: Add PCK/TPC data (constants and low-fidelity orientation). | ||
|
|
||
| ## Coordinate Transformations | ||
|
|
||
| The most common use of the `Almanac` is to transform positions and velocities between frames. | ||
|
|
||
| ### `transform_to` | ||
| Transforms an `Orbit` (state vector) into a different frame at its own epoch. | ||
| - **Parameters**: `orbit`, `target_frame`, `aberration`. | ||
| - **Returns**: A new `Orbit` in the target frame. | ||
|
|
||
| ### `translate` | ||
| Calculates the relative position and velocity between two frames. | ||
| - **Parameters**: `target`, `observer`, `epoch`, `aberration`. | ||
| - **Returns**: A `StateVector` (Position + Velocity). | ||
|
|
||
| ### `rotate` | ||
| Calculates the rotation (DCM) from one orientation frame to another. | ||
| - **Parameters**: `target`, `observer`, `epoch`. | ||
| - **Returns**: A 3x3 Direction Cosine Matrix. | ||
|
|
||
| ## Physical Constants | ||
|
|
||
| The `Almanac` also stores physical data for bodies defined in the kernels. | ||
|
|
||
| ### `frame_info` | ||
| Retrieves a `Frame` object containing metadata for a given NAIF ID. | ||
| - **Includes**: Gravitational parameter ($\mu$), body radii, and frame type. | ||
|
|
||
| ### `angular_velocity` | ||
| Calculates the angular velocity of a frame relative to an inertial reference (usually J2000) at a specific epoch. | ||
|
|
||
| ## Built-in Constants | ||
|
|
||
| ANISE provides a set of common NAIF IDs and frames in the `constants` module for ease of use (e.g., `EARTH_J2000`, `SUN_J2000`, `MOON_J2000`). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # API Documentation | ||
|
|
||
| ANISE is available as a Rust crate and a Python package. Both share the same high-performance core but provide language-specific interfaces. | ||
|
|
||
| ## [Rust API](https://docs.rs/anise/latest/anise/) | ||
|
|
||
| The Rust API provides the most complete and performant access to ANISE. It includes full type safety for frames and epochs. | ||
|
|
||
| - [Almanac](https://docs.rs/anise/latest/anise/struct.Almanac.html) | ||
| - [Orbit](https://docs.rs/anise/latest/anise/struct.Orbit.html) | ||
| - [Epoch](https://docs.rs/anise/latest/anise/time/index.html) | ||
|
|
||
| ## Python API | ||
|
|
||
| The Python API (`anise-py`) is designed to be familiar to users of `SpiceyPy` and `MONTE`, while offering the performance of Rust. | ||
|
|
||
| - [Python Module Overview](python/index.md) (Internal documentation) | ||
| - [Examples and Jupyter Notebooks](https://github.com/nyx-space/anise/tree/main/anise-py/examples) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # Frame Reference | ||
|
|
||
| Frames define the coordinate systems used for all calculations in ANISE. Every position, velocity, and rotation is defined with respect to a specific Frame. | ||
|
|
||
| ## Frame Types | ||
|
|
||
| ANISE categorizes frames into several types, which determines how transformations are calculated: | ||
|
|
||
| ### 1. Celestial (Inertial) | ||
| These frames are fixed relative to distant stars. They do not rotate over time (or rotate very slowly). | ||
| - **Example**: `J2000`, `ICRF`, `EME2000`. | ||
| - **NAIF IDs**: Usually 1, 10, etc. | ||
|
|
||
| ### 2. Planetocentric (Body-Fixed) | ||
| These frames are attached to a celestial body and rotate with it. | ||
| - **Example**: `ITRF93` (Earth), `IAU_MOON`, `IAU_MARS`. | ||
| - **NAIF IDs**: Usually 10xxx or 13xxx. | ||
| - **Computation**: Requires a BPC or PCK kernel to determine the rotation at a specific epoch. | ||
|
|
||
| ### 3. Topocentric | ||
| These are frames defined at a specific point on the surface of a body. | ||
| - **Example**: `SEZ` (South-East-Zenith), `NED` (North-East-Down). | ||
| - **Computation**: Requires the location (latitude, longitude, altitude) and the orientation of the parent body. | ||
|
|
||
| ## Frame Identification | ||
|
|
||
| ANISE is compatible with the standard NAIF ID system. You can refer to frames using: | ||
| 1. **Integer IDs**: e.g., `399` for Earth. | ||
| 2. **Predefined Constants**: e.g., `anise::constants::frames::EARTH_J2000`. | ||
| 3. **Names**: In some interfaces (like Python), strings can be used if they have been registered in the `Almanac`. | ||
|
|
||
| ## Frame Safety | ||
|
|
||
| The `Frame` object in ANISE is more than just an ID; it's a validated descriptor. When you create an `Orbit`, it is "tagged" with a `Frame`. | ||
|
|
||
| ```rust | ||
| let frame = almanac.frame_info(EARTH_J2000)?; | ||
| let orbit = Orbit::cartesian(x, y, z, vx, vy, vz, epoch, frame); | ||
| ``` | ||
|
|
||
| If you attempt to perform a math operation between two orbits in different frames, ANISE will either: | ||
| - **Automatic Transform**: Some APIs will automatically transform the state to a common frame if the `Almanac` is provided. | ||
| - **Error**: If no `Almanac` is provided to resolve the relationship, ANISE will refuse to perform the operation to prevent physical errors. | ||
|
|
||
| ## Metadata | ||
| A `Frame` object retrieved via `almanac.frame_info()` contains data retrieved from the loaded datasets (SPK, PCK, BPC): | ||
|
|
||
| - **`mu`**: The gravitational parameter ($GM$) of the center body in $km^3/s^2$. | ||
| - **`shape`**: A tri-axial `Ellipsoid` defining the body's semi-major, semi-minor, and polar radii. It provides methods for surface intersection testing and calculating lighting angles (emission, solar incidence). | ||
| - **`ephemeris_id`**: The NAIF ID used for translation and trajectory lookups. | ||
| - **`orientation_id`**: The NAIF ID used for rotation lookups. | ||
|
|
||
| ### Orientation and Phase Angles | ||
| For planetocentric (body-fixed) frames, ANISE uses the loaded PCK or BPC data to determine the body's orientation. This is defined by three key phase angles: | ||
| 1. **Right Ascension (RA)** of the body's north pole. | ||
| 2. **Declination (Dec)** of the body's north pole. | ||
| 3. **Prime Meridian (W)** location at the given epoch. | ||
|
|
||
| These angles are often modeled as polynomials in time (e.g., $RA = RA_0 + RA_1 \Delta t + RA_2 \Delta t^2 \dots$). ANISE evaluates these to compute the exact rotation matrix between inertial and body-fixed frames. | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| # Orbit and State Reference | ||
|
|
||
| In ANISE, an `Orbit` represents the full state of an object at a specific time within a specific coordinate frame. | ||
|
|
||
| ## The `Orbit` Struct | ||
|
|
||
| An `Orbit` consists of: | ||
| - **State Vector**: Position and Velocity ($\mathbf{r}, \mathbf{v}$). | ||
| - **Epoch**: The time at which the state is defined (using `hifitime`). | ||
| - **Frame**: The reference frame in which the vectors are expressed. | ||
|
|
||
| ## Initialization | ||
|
|
||
| You can initialize an `Orbit` from various representations: | ||
|
|
||
| ### Cartesian | ||
| `Orbit::cartesian(x, y, z, vx, vy, vz, epoch, frame)` | ||
| Directly sets the position and velocity in km and km/s. | ||
|
|
||
| ### Keplerian | ||
| `Orbit::keplerian(a, e, i, raan, argp, nu, epoch, frame)` | ||
| Calculates the state from classical orbital elements. | ||
| - **Note**: Requires the frame to have a defined gravitational parameter ($\mu$). | ||
|
|
||
| ### Geodetic / LatLongAlt | ||
| `Orbit::try_latlongalt(lat, lon, alt, epoch, frame)` | ||
| Defines a state relative to a body's surface. Useful for ground stations. | ||
|
|
||
| ## Common Operations | ||
|
|
||
| ### `transform_to` | ||
| `almanac.transform_to(orbit, target_frame, aberration)` | ||
| Returns a new `Orbit` expressed in the `target_frame`. This accounts for sowohl translation as well as rotation of the frames. | ||
ChristopherRabotin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ### Orbital Elements | ||
| You can extract orbital elements from an `Orbit` object: | ||
| - `sma_km()`, `ecc()`, `inc_deg()`, `raan_deg()`, `aop_deg()`, `ta_deg()` | ||
| - **Other Anomalies**: `ma_deg()` (Mean Anomaly), `ea_deg()` (Eccentric Anomaly). | ||
| - **Other Parameters**: `periapsis_km()`, `apoapsis_km()`, `hmag()` (Specific Angular Momentum). | ||
| - **Python**: Accessible as methods (e.g., `orbit.sma_km()`). | ||
|
|
||
|
|
||
| ### Propagation (Two-Body) | ||
| ANISE provides basic two-body propagation for quick estimates: | ||
| - `at_epoch(new_epoch)`: Propagates the orbit to a new time using Keplerian motion. | ||
| - **Warning**: For high-fidelity propagation including J2, solar radiation pressure, etc., use a dedicated propagator like those found in the `Nyx` library. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.