ballistic-solver
Coordinate-residual solver · Native C++ core · Stable C ABI · Python/PyPI · Unity/C# · Godot
ballistic-solver is a deployable intercept solver for moving targets under gravity and
quadratic drag, with optional wind. Its current default path minimizes a physical-space
closest-approach residual; the paper-backed auxiliary residual remains available through solve_aux.
Problem and Current Method
- Projectile dynamics include quadratic drag, optional wind, and fixed-step RK4 integration.
- The target model supports relative motion, including an extended constant-acceleration target API.
- The default solver minimizes the coordinate-space closest-approach miss vector.
- A vacuum-lead warm start and analytic vacuum Jacobian precondition the first correction.
- Gauss–Newton iterations use Broyden rank-1 Jacobian updates, line search, and multistart fallback.
- Every solve returns an explicit status, diagnostic message, and best result found.
Architecture
What I Built
- Compiled native C++ core with a modern
bs::API for direct C++ use. - Stable C ABI with plain-C data layout for language and runtime bindings.
- Python package with presets, utilities, and prebuilt binaries distributed through PyPI.
- Unity/C# and Godot integration paths backed by the same native implementation.
- Explicit diagnostics for invalid input, numerical failure, rejection, and iteration limits.
- Research compatibility through
solve_aux, which retains the auxiliary-solution-induced residual method.
Package Benchmarks
Current repository benchmark on a local Windows release build over 500 generated linear-target cases:
| Preset | Median Solve Time | P95 Solve Time | P95 Miss |
|---|---|---|---|
| fast | 0.031 ms | 0.131 ms | 2.810e-02 m |
| balanced | 0.057 ms | 0.261 ms | 7.053e-03 m |
| precise | 0.087 ms | 0.356 ms | 5.596e-06 m |
10,000-Case Default-Path Benchmark
| Scenario | Success | Median Runtime | P95 Runtime | P95 Miss |
|---|---|---|---|---|
| Low arc, moving target | 10,000/10,000 | 0.089 ms | 0.266 ms | 6.450e-03 m |
| High arc, stationary target | 10,000/10,000 | 0.408 ms | 0.846 ms | 8.018e-03 m |
| High arc, moving target | 10,000/10,000 | 0.607 ms | 1.264 ms | 8.341e-03 m |
Research Result
The ICROS 2026 manuscript evaluates the auxiliary residual now retained in solve_aux.
Under identical outer-iteration settings on 10,000 stationary high-arc cases:
| Method | Failure Rate | Mean Runtime | P95 Miss |
|---|---|---|---|
| Direct line-of-sight residual | 50.25% | 6.791 ms | 8.498e+02 m |
| Auxiliary-solution-induced residual | 0.00% | 3.748 ms | 8.128e-03 m |
Real-Device Validation
The same native solver was integrated into an edge fire-control prototype to verify that the library works beyond desktop benchmarks and game-engine bindings.
- Rock 5B ARM64 runtime using the native solver library.
- 4K camera at 60 fps with AprilTag-based relative-position tracking.
- Solver output converted into pitch/yaw commands for an STM32G431 motion controller.
- 200 Hz encoder closed-loop control on the embedded controller.
- Measured tracking and calculation path of approximately 35.8 ms.
Known Limits
- The consuming runtime must match the solver's physics and integration assumptions.
- Strongly nonlinear cases remain numerical problems, so convergence depends on conditioning and solver settings.
- Non-converged cases return explicit statuses and the best result found for caller-side handling.