Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OrbitSimulator.jl

CI

Standalone, dependency-light satellite-constellation emulator: synthesizes per-target overpasses of an idealized sun-synchronous constellation and the full per-look observation geometry (WGS84 view geometry, solar geometry, Earth–Sun distance, two-leg line-of-sight Doppler), without a literal satellite inventory or repeat-cycle simulation.

Developed for the Google-RT satellite emulator campaign, but deliberately grid-agnostic and I/O-free so it can serve any use case that needs "when and how would an SSO instrument see this point on this day": targets are plain TargetCells (lat, lon, land flag, opaque indices); atmospheric-state sampling, land masks, and file formats live behind strategy seams implemented by the host application.

Dependencies: Dates, LinearAlgebra, StaticArrays. Nothing else.

The virtual constellation

The emulator represents an effectively unlimited constellation of identical satellites (default: 600 km circular, 11:30 LTAN, ascending) as a virtual construction. For each requested local calendar day and each target it synthesizes the one ascending overpass whose ground track crosses the target, from the exact sun-synchronous identity

LMST(u) = LTAN + Δα(u)/15°·hour,   Δα(u) = atan2(cos i · sin u, cos u)

(under the J₂ secular model the sub-satellite local mean solar time depends only on latitude). The retrograde inclination (≈97.8°) is derived from the J₂ nodal-precession condition, never hard-coded; the ground-track latitude limit (≈82.2° geocentric) classifies poleward cells as orbit_unreachable — there is no polar surrogate.

Off-nadir looks of the cross-track scan pattern (default −6°…+6°, five angles, 12° FOV) all terminate at the same target cell center: each look's platform is a different virtual satellite displaced cross-track, solved on the real WGS84 ellipsoid (validated against the spherical reference: 6° scan from 600 km ⇒ ≈6.57° surface VZA, ≈63 km displacement). The signed displacement is stored per look as virtual_geometry_offset_m.

Quick start

using OrbitSimulator, Dates

cells = [TargetCell((idx, idy, face), lat_deg, lon_deg, is_land), ...]
em    = SatelliteEmulator(InMemoryCellSelector(cells))   # v1 defaults

plan = plan_day(em, Date(2019, 9, 3))
coverage_summary(plan)   # observed / ocean / orbit_unreachable / not_sunlit

for obs in observations(plan)
    obs.utc                      # shared bundle time (all five looks)
    obs.solar.sza_deg            # solar geometry at the overpass
    [l.surface_vza_deg for l in obs.looks]
    [l.relative_azimuth_deg for l in obs.looks]
    [k.combined_solar_to_satellite_factor for k in obs.kinematics]
end

Every strategy is replaceable through its abstract type — orbit model, pass direction, coverage/reachability/illumination policy, scan pattern, Earth model, solar ephemeris, cell selector, state sampler, Doppler and velocity model — by defining a new concrete type + methods for the behavioral interface (overpass_state, is_reachable, is_observable, look_states, solar_state, spectral_kinematics, select_cells, sample_state). The planner never branches on strings.

Conventions (stable output contract)

  • Azimuths: degrees clockwise from geodetic north at the target. Relative azimuth is mod(view_az − solar_az, 360) (the vSmartMOM Δφ = φ_view − φ_sun convention). At exact nadir the along-track vertical plane is the deterministic reference (view azimuth = ground track heading).
  • Range rates: positive = increasing emitter–receiver separation; Doppler factor D = √((1−β)/(1+β)) < 1 for receding (redshift). Wavenumber scales like frequency (ν_out = D·ν_in); wavelength is reciprocal. Two legs: Sun-rest → rotating column frame (D_solar), column frame → satellite (D_view, computed per look — cross-track Doppler is calculated, not forced to zero).
  • Earth–Sun distance: ratio in semi-major-axis units and metres via the exact IAU au (149 597 870 700 m); the range rate is the analytic derivative of the ephemeris distance model.
  • "ECI" is the instantaneous inertial frame coincident with ECEF at the observation epoch (r_eci = r_ecef, v_eci = v_ecef + ω⃗_E×r); all Doppler projections are invariant under this choice.
  • Altitude: platforms sit exactly altitude_m above the WGS84 ellipsoid along the geodetic normal; orbital rates use the semi-major axis equatorial_radius + altitude_m. (A geocentric-circular orbit cannot also hold constant ellipsoidal height; this resolution is part of the virtual construction.)

Solar ephemeris

InsolationEphemeris reimplements the analytic model of Insolation.jl v1.1.0 (mean → true anomaly by the O(e³) series, solar longitude, declination, ellipse distance, equation of time), with the ClimaParams default parameter values — reimplemented, with credit, to avoid the ClimaParams/artifact dependency and to expose the exact analytic Earth–Sun range rate. The azimuth adapter from Insolation's convention (0 = East, CCW) to compass is compass_from_east_ccw_deg and is covered by tests.

v1 exclusions (replaceable via the strategy seams, not baked in)

Polar surrogates; explicit satellite counts/IDs/spacing/repeat cycles; finite-footprint/PSF integration; clouds and terrain elevation; real TLE/attitude propagation; atmospheric-wind Doppler; solar gravitational or convective line shifts; full barycentric corrections; Doppler resampling of spectra; a physical solar irradiance model.

About

Dependency-light satellite constellation and observation-geometry simulator for remote sensing

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages