Metadata-Version: 2.4
Name: gri-trajectory
Version: 0.1.0
Summary: Platform motion trajectories: stationary, linear, turns, great-circle, orbits, SGP4, waypoint/Hermite splines, and segmented composition
Project-URL: Homepage, https://geosolresearch.com
Project-URL: Repository, https://gitlab.com/geosol-foss/python/gri-trajectory
Project-URL: Issues, https://gitlab.com/geosol-foss/python/gri-trajectory/-/issues
Project-URL: Changelog, https://gitlab.com/geosol-foss/python/gri-trajectory/-/releases
Author-email: GeoSol Research Inc <contact@geosolresearch.com>
License-Expression: MIT
License-File: LICENSE
Keywords: SGP4,geodetic,motion,orbit,simulation,trajectory
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: GIS
Requires-Python: >=3.12
Requires-Dist: gri-nsepoch>=0.2.2
Requires-Dist: gri-pos>=0.2.0
Requires-Dist: gri-utils>=0.3.3
Requires-Dist: numpy>=2.3.3
Requires-Dist: scipy>=1.16.2
Requires-Dist: sgp4>=2.23
Description-Content-Type: text/markdown

# gri-trajectory

Platform and emitter motion models for geolocation simulation. A trajectory
defines how an entity moves through space over time; all trajectories implement a
common `Trajectory` protocol providing position, velocity, and combined state
queries at any time instant.

This package was factored out of `gri-geosim` so the motion models can be reused
without pulling in the full simulation stack (it depends only on gri-nsepoch,
gri-pos, and gri-utils, plus numpy/scipy/sgp4).

## Install

```bash
uv add gri-trajectory
```

## Import and use

```python
from gri_trajectory import StationaryTrajectory, Sgp4Trajectory, WaypointTrajectory
from gri_pos import Pos

traj = StationaryTrajectory(Pos.LLA(38.0, -77.0, 100.0))
pos = traj.position_at(time)    # always the same Pos
vel = traj.velocity_at(time)    # [0, 0, 0]
```

## Available trajectories

| Trajectory | Description |
| --- | --- |
| `StationaryTrajectory` | Fixed position, zero velocity |
| `LinearTrajectory` | Constant ECEF velocity from an initial `Vel` |
| `CoordinatedTurnTrajectory` | Constant-rate level/climbing turn (local ENU tangent) |
| `GreatCircleTrajectory` | Great-circle motion fixed in ECEF (aircraft, vehicles) |
| `CircularOrbitTrajectory` | Circular orbit fixed in ECI (satellite approximation) |
| `KeplerianTrajectory` | Two-body orbital mechanics (gri-utils backend) |
| `Sgp4Trajectory` | SGP4/SDP4 TLE propagation (python-sgp4 backend) |
| `WaypointTrajectory` | Interpolated path through waypoints (linear or cubic spline) |
| `HermiteTrajectory` | Hermite spline interpolation through state vectors |
| `SegmentedTrajectory` | Piecewise composition of sub-trajectories (C0-continuous) |

## Composing segmented paths

The `legs` submodule builds a `SegmentedTrajectory` from kinematic primitives
(`Straight`, `Turn`, `Climb`, `Hold`):

```python
from gri_trajectory import SegmentedTrajectory
from gri_trajectory.legs import Straight, Turn
from gri_pos import Vel

start = Vel.LLA(38.0, -77.0, 0.0, 10.0, 0.0, 0.0)   # east at 10 m/s
racetrack = SegmentedTrajectory.from_legs(
    start,
    [Straight(20.0), Turn(180.0, radius_m=50.0),
     Straight(20.0), Turn(180.0, radius_m=50.0)],
)
```

The `placement` submodule provides builders for positioning a point over a ground
origin by look angle (`sky_point`, by slant range or target altitude) -- compose
with the orbit constructors for an overhead collector.

## Trajectory protocol

```python
def position_at(time: Time) -> Pos
def velocity_at(time: Time) -> NDArray[np.floating]   # shape (3,), ECEF m/s
def state_at(time: Time) -> tuple[Pos, NDArray[np.floating]]
```

`state_at()` returns position and velocity in one call, which is more efficient
than separate queries for some trajectory types.

## Notes

- All positions are ECEF (XYZ) in meters; velocities are ECEF m/s, shape (3,).
- `Sgp4Trajectory` converts TEME to ECEF internally.
- `KeplerianTrajectory` is a two-body approximation (no J2, drag, or third-body);
  for high fidelity use `Sgp4Trajectory` with real TLE data.
- Downstream, `gri-geosim`'s `Platform` and `Emitter` accept a `Pos` directly and
  wrap it in a `StationaryTrajectory` internally.

## License

MIT -- see [LICENSE](LICENSE).
