Native C++17 port of Orekit 13.1.6's Draper Semi-analytical Satellite Theory
(DSST) package, centered on dsst::DSSTPropagator.
This project is intended to run independently of Orekit Java at application runtime. The Java Orekit checkout is only used by the regression tooling that generates comparison fixtures.
- Scalar and field-style DSST propagator shells.
- Native equinoctial orbit and spacecraft-state data adapters.
- DSST force models for Newtonian attraction, J2-squared, zonal, tesseral, third body, solar radiation pressure, and atmospheric drag.
- DSST utilities, Hansen helpers, short-period terms, interpolation grids, mapper conversion, STM/Jacobian helpers, and selected-coefficient plumbing.
- CTest coverage plus optional Orekit Java fixture comparison tests.
The port uses lightweight C++ data records instead of Orekit's Java Orbit,
SpacecraftState, AbsoluteDate, Frame, body, atmosphere, and shape classes.
That keeps runtime use standalone, but it also means this is not a drop-in
replacement for every surrounding Orekit API.
- CMake 3.18 or newer
- A C++17 compiler
- A build system supported by CMake, such as Visual Studio/MSBuild or Ninja
No Java runtime is required to build or use the native C++ library. Java and Maven are only needed when regenerating Orekit comparison fixtures.
From this directory:
cmake -S . -B build
cmake --build build --config Release
ctest --test-dir build -C Release --output-on-failureDebug builds are also supported:
cmake --build build --config Debug
ctest --test-dir build -C Debug --output-on-failureThe project builds a dsst_cpp target. In a larger CMake project, add this
repository as a subdirectory and link to that target:
add_subdirectory(external/DSST-cpp)
add_executable(my_propagator main.cpp)
target_link_libraries(my_propagator PRIVATE dsst_cpp)Headers are under include/dsst.
Use SI units: meters, seconds, radians, kilograms, and m^3/s^2.
#include <dsst/DSSTPropagator.hpp>
#include <dsst/runtime.hpp>
#include <dsst/utilities/AuxiliaryElements.hpp>
#include <any>
#include <cmath>
#include <iostream>
#include <string>
int main() {
constexpr double mu = 398600.4418e9;
constexpr double a = 7000000.0;
const double n = std::sqrt(mu / a) / a;
dsst::utilities::EquinoctialOrbitData orbit;
orbit.date = 0.0;
orbit.frame = std::string{"GCRF"};
orbit.mu = mu;
orbit.a = a;
orbit.equinoctialEx = 0.01;
orbit.equinoctialEy = -0.017;
orbit.e = std::hypot(orbit.equinoctialEx, orbit.equinoctialEy);
orbit.hx = 0.001;
orbit.hy = -0.002;
orbit.lm = 0.25;
orbit.lv = 0.25;
orbit.le = 0.25;
orbit.keplerianMeanMotion = n;
orbit.keplerianPeriod = 2.0 * std::acos(-1.0) / n;
dsst::SimpleSpacecraftState state;
state.date = orbit.date;
state.orbit = orbit;
state.mass = 900.0;
state.hasMass = true;
dsst::DSSTPropagator propagator;
propagator.setMu(mu);
propagator.setInitialState(state, "MEAN");
const auto propagated = propagator.propagateState(600.0, 60.0);
const auto propagatedOrbit =
std::any_cast<dsst::utilities::EquinoctialOrbitData>(propagated.orbit);
std::cout << "date = " << std::any_cast<double>(propagated.date) << "\n";
std::cout << "lm = " << propagatedOrbit.lm << "\n";
}setMu(mu) adds the central Newtonian attraction model. You can also add it
explicitly with std::make_shared<dsst::forces::DSSTNewtonianAttraction>(mu).
Force models are added as std::shared_ptr<dsst::ported_orekit_class>.
Most force calculations use dsst::utilities::AuxiliaryElements, which wrap an
equinoctial orbit and the retrograde factor (1 for normal prograde DSST use).
#include <dsst/DSSTPropagator.hpp>
#include <dsst/forces/DSSTAtmosphericDrag.hpp>
#include <dsst/forces/DSSTSolarRadiationPressure.hpp>
#include <dsst/forces/DSSTThirdBody.hpp>
#include <dsst/utilities/AuxiliaryElements.hpp>
#include <any>
#include <array>
#include <map>
#include <memory>
#include <vector>
dsst::utilities::AuxiliaryElements auxiliary{orbit, 1};
dsst::forces::CelestialBodyData<> moon{
std::array<double, 3>{384400000.0, 1000000.0, -2000000.0},
"Moon",
4.9048695e12,
};
auto drag = std::make_shared<dsst::forces::DSSTAtmosphericDrag>(
std::any{dsst::forces::AtmosphereData{2.0e-12}},
2.2,
12.5,
mu);
auto srp = std::make_shared<dsst::forces::DSSTSolarRadiationPressure>(
1.2,
10.0,
std::array<double, 3>{dsst::forces::DSSTSolarRadiationPressure::D_REF, 0.0, 0.0},
6378137.0,
mu);
dsst::DSSTPropagator propagator;
propagator.setMu(mu);
propagator.addForceModel(std::make_shared<dsst::forces::DSSTThirdBody>(moon, mu));
propagator.addForceModel(drag);
propagator.addForceModel(srp);
std::map<std::string, std::any> mapState{
{"date", orbit.date},
{"orbit", orbit},
{"mass", 1200.0},
};
const auto rates = propagator.computeDerivatives(mapState, auxiliary);For gravity harmonics, use dsst::forces::SphericalHarmonicsProviderData with
DSSTZonal, DSSTTesseral, or DSSTJ2SquaredClosedForm.
Create the propagator with "OSCULATING" when you want short-period terms
applied to propagated output.
dsst::DSSTPropagator propagator{std::any{}, "OSCULATING"};
propagator.setMu(mu);
propagator.setInitialState(state, "MEAN");
const auto osculating = propagator.propagateState(600.0, 60.0);Useful methods:
computeOsculatingState(meanState)computeMeanState(osculatingState)setInterpolationGridToFixedNumberOfPoints(points)setInterpolationGridToMaxTimeGap(maxGap)setSelectedCoefficients({"DSST-SRP-c[12]"})
The C++ port accepts several lightweight shapes:
dsst::SimpleSpacecraftStatedsst::utilities::EquinoctialOrbitDatastd::map<std::string, std::any>with keys such asdate,orbit,mass,auxiliary,additionalData, andadditional_data- Date adapters that provide
toAbsoluteDate()ordurationFrom(...)through the provided lightweight field-date data structures
Map-state mass values may be numeric strings such as "900.0"; they are
normalized to doubles when mapped or propagated.
Run the native and fixture-backed suite:
ctest --test-dir build -C Release --output-on-failure
ctest --test-dir build -C Debug --output-on-failureCurrent verification baseline:
- Release:
26/26 passed - Debug:
26/26 passed - No Java runtime is required for normal library use.
- Java, Maven, and the Orekit checkout are only needed when regenerating
Orekit comparison fixtures under
regression/.
include/dsst/ Public C++ headers
include/dsst/forces/ DSST force models and force contexts
include/dsst/utilities/ DSST utility and coefficient helpers
include/dsst/utilities/hansen/
Hansen recurrence helpers
src/ Translation units for the dsst_cpp library
tests/ CTest unit, functionality, and Orekit fixture tests
regression/ Optional Orekit Java reference fixture generation
PORTING_MANIFEST.json Java source to C++ source map
PROGRESS.md Porting ledger and verification history
Applications linking dsst_cpp do not call Java, JNI, Maven, or Orekit. The
native code contains the implemented DSST formulas and lightweight adapter types
directly. Keep the Orekit source tree only if you want to audit provenance or
regenerate reference fixtures.
- This is a DSST-focused native port, not the full Orekit ecosystem.
- High-fidelity production use should validate inputs, force configuration, and propagation horizons against mission-specific truth data.
- External frames, time scales, celestial ephemerides, body shapes, atmosphere models, and spacecraft models should be supplied through the lightweight data adapters or through application-specific wrapper objects.
The project follows the Apache-2.0 licensing declared by the port metadata.
Source provenance for every ported Orekit DSST class is recorded in
PORTING_MANIFEST.json and in class-level status() metadata.