Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ jobs:
- run: cargo clippy --all-targets --all-features -- -D warnings
- run: cargo check --no-default-features
- run: cargo check --no-default-features --features alloc
- run: cargo check --no-default-features --features serde
- run: cargo check --no-default-features --features alloc,serde

test:
name: Test
Expand Down
62 changes: 52 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,73 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Unreleased]

### Added

- `MeanAnomaly`, `TrueAnomaly`, `EccentricAnomaly`, `HyperbolicAnomaly`,
`ParabolicAnomaly` typed anomaly newtypes; all anomaly solver functions now
accept and return these typed values instead of raw `Radians` or `f64`.
- `AnomalyOptions::try_new(max_iter, tol)` fallible constructor; fields are now
private; `max_iter()` and `tol()` accessors added.
- `AnomalyError::InvalidOptions` variant for invalid solver configuration.
- `ConicRegime` and `EccentricityError` moved to `eccentricity` module;
`elements::ConicRegime` is a re-export for backwards compatibility.
- `Eccentricity::try_new`, `new_elliptic`, `new_hyperbolic`, `parabolic`,
`classify` constructors.
- `parabolic_from_mean`, `true_from_parabolic`, `parabolic_from_true` parabolic
anomaly helpers (replaces the old `kepler_parabolic` raw-f64 function).
- `KeplerianElements::try_to_cartesian` fallible Cartesian conversion (replaces
infallible `to_cartesian`).
- `ConversionError::IncoherentRegime` — returned when the semi-major axis sign
is inconsistent with the eccentricity regime.
- `a`/`e` coherence check in `KeplerianElements::new`: elliptic requires `a > 0`;
hyperbolic requires `a < 0`.
- `TransferError` enum for fallible transfer helpers.
- `try_orbital_period`, `try_hohmann_delta_v`, `try_vis_viva_speed`,
`try_escape_speed` fallible variants of transfer functions.
- `prelude` module re-exporting the most commonly used public items.
- `#![cfg_attr(not(feature = "std"), no_std)]` — crate is now no-std capable
with `alloc` feature for heap-using APIs.
- `Clone` derive on `LambertError`; `PartialEq` and serde derives on
`LambertDiagnostics`, `LambertBranch`, `NRevBranch`, `TypedLambertSolution`.
- CI: additional checks for `--features serde` and `--features alloc,serde`
no-default-features combinations.

### Changed

- `KeplerProblem.mu` field is now private; use `mu()` accessor.
- `TransferCandidate.total_dv` renamed to `endpoint_speed_sum`.
- `kepler_parabolic` renamed to `parabolic_from_mean`; accepts and returns
`ParabolicAnomaly` instead of raw `f64`.

### Removed

- Infallible `KeplerianElements::to_cartesian`; replaced by
`try_to_cartesian`.
- `AnomalyOptions` struct literal construction (fields privatised); use
`AnomalyOptions::try_new`.

## [0.1.0] - 2026-05-22

### Added

- `Eccentricity` newtype with `new_unchecked`, `new_elliptic`, `new_hyperbolic`,
and `classify` constructors; compile-time validation enforced.
- `AnomalyOptions` control struct (max iterations, tolerance) and
`AnomalyError` (non-convergence) for all iterative solvers.
- `Eccentricity` newtype with `new_unchecked` constructor; compile-time
validation enforced.
- `AnomalyOptions` control struct and `AnomalyError` for all iterative solvers.
- Elliptic anomaly solvers: `eccentric_from_mean`, `true_from_eccentric`,
`eccentric_from_true`, `mean_from_eccentric`.
- Parabolic anomaly solver: `kepler_parabolic` (Barker's equation).
- Hyperbolic anomaly solvers: `hyperbolic_from_mean`, `true_from_hyperbolic`.
- `KeplerianElements<F>` — six classical elements typed over an `affn` frame;
conversions `to_cartesian` / `from_cartesian`.
conversions `from_cartesian`.
- `KeplerProblem<C, F>` — two-body IVP solver; `new` + `propagate`.
- Lambert boundary-value solver (`lambert`, `lambert_n_rev`) with multi-rev
support.
- Transfer invariants: `specific_orbital_energy`, `specific_angular_momentum`,
`vis_viva_speed`, `orbital_period`, `escape_speed`, `hohmann_delta_v`.
- `OrbitalState` and `StateDerivative` Cartesian state types.
- `CartesianState` Cartesian state type.
- `KeplerError` crate-level error family.
- `alloc`-gated `search` module: Lambert transfer-search grids.
- Optional `serde` feature for all public data types.
- CI workflow with fmt, Clippy (default + all features), no-std/alloc checks,
tests (default + all features), and doc-test jobs.
- Optional `serde` feature for public data types.
- CI workflow with fmt, Clippy, no-std/alloc checks, tests, and doc-test jobs.
- Audit, deny, coverage (llvm-cov ≥ 90 % line rate), and Miri jobs.
- Publish workflow triggered on `v*.*.*` tags.

Expand Down
24 changes: 12 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions examples/anomaly_solve.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
//! Example binary for elliptic Kepler solves.
#![allow(clippy::print_stdout)]

use keplerian::anomaly::{kepler_elliptic, AnomalyOptions};
use keplerian::anomaly::{kepler_elliptic, AnomalyOptions, MeanAnomaly};
use keplerian::Eccentricity;
use qtty::angular::Radians;

fn main() {
let ecc = Eccentricity::new(0.2).unwrap();
for m in [0.0, 0.5, 1.0, 1.5] {
let e = kepler_elliptic(Radians::new(m), ecc, AnomalyOptions::default()).unwrap();
let e =
kepler_elliptic(MeanAnomaly::from_value(m), ecc, AnomalyOptions::default()).unwrap();
println!("M = {m:.3} rad -> E = {:.6} rad", e.value());
}
}
2 changes: 1 addition & 1 deletion examples/state_elements_roundtrip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fn main() {
Velocity::<Frame, KmPerSecond>::new(0.0, 7.2, 1.0),
);
let elements = KeplerianElements::from_cartesian(&state, mu).unwrap();
let back = elements.to_cartesian::<Center>(mu);
let back = elements.try_to_cartesian::<Center>(mu).unwrap();
assert!((back.position().x().value() - state.position().x().value()).abs() < 1e-8);
println!(
"a = {:.3} km, e = {:.6}",
Expand Down
Loading
Loading