ballistic-solver
Auxiliary residual method · C/C++ core · Stable C ABI · Python/PyPI · Unity/C# · Godot/.NET
ballistic-solver is a deployable intercept solver for moving targets under gravity and quadratic drag, with optional wind. The core method uses an auxiliary-solution-induced residual: drag-inclusive trajectory error is transformed through an auxiliary vacuum ballistic response before the nonlinear correction step.
Problem
In drag-inclusive ballistic interception, the error is measured as a closest-approach miss vector in physical space, while the correction variables are launch angles. A direct line-of-sight residual can give weak correction information when those spaces are misaligned, especially in high-arc or strongly nonlinear cases.
Method
- Projectile dynamics include quadratic drag, optional wind, and fixed-step RK4 integration.
- The hit condition is solved against a moving target, with an extended API for constant-acceleration targets.
- A vacuum ballistic auxiliary solver converts drag-inclusive miss vectors into launch-angle residuals for the outer iteration.
- The nonlinear correction loop combines Levenberg-Marquardt damping, line search, and Broyden-style Jacobian refinement.
- The solver returns explicit status codes, diagnostic messages, and the best result found even when convergence is imperfect.
Architecture
Interactive Solver
Enter a relative position, relative velocity, and muzzle speed to compute low/high-arc launch angles in the browser, then watch the trajectories. The request hits the same model as the package: RK4 drag/wind integration, closest-approach residual, and an LM solve.
waiting for input
waiting for input
ready
What I Built
- Auxiliary-solution-induced residual method for nonlinear correction when residual space and correction-variable space are not directly aligned.
- Header-only C++ core focused on solver logic, with separate bindings for runtime integration.
- Stable C ABI with plain-C data layout and fixed-size arrays for FFI-safe integration.
- Python package with presets, utility helpers, and prebuilt binaries through PyPI.
- Unity/C#, .NET, and Godot paths so the same native solver can be used in game/runtime contexts.
- Failure handling through explicit status codes such as invalid input, Jacobian failure, line-search rejection, and max-iteration exhaustion.
Result
- Built a deployable nonlinear interception solver with explicit physics assumptions and status outputs.
- Packaged the same core through a C ABI, Python/PyPI, Unity/C#, .NET, and Godot integration paths.
- Benchmarked the auxiliary residual method against direct line-of-sight residual correction in the ICROS 2026 manuscript.
Research Result
In the ICROS 2026 manuscript, the auxiliary residual was compared against direct line-of-sight residual correction under identical outer-iteration settings on 10,000 stationary high-arc interception 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 |
Package Benchmarks
From the repository README benchmark on a local Windows release build over 500 generated linear-target cases:
| Preset | Median Solve Time | p95 Solve Time | p95 Miss |
|---|---|---|---|
| fast | 0.094 ms | 0.228 ms | 3.834e-02 m |
| balanced | 0.182 ms | 0.452 ms | 5.351e-03 m |
| precise | 0.199 ms | 0.569 ms | 5.742e-06 m |
High-Arc Update
After adding the v0.6 moving-target convergence defaults, high-arc generated cases improved substantially in the repository benchmark.
| Configuration | Success | Median Runtime | P95 Runtime | P95 Miss |
|---|---|---|---|---|
| Previous core path | 382/500 | 4.301 ms | 27.124 ms | 3.227e+02 m |
| v0.6.0 defaults | 490/500 | 1.845 ms | 2.535 ms | 8.809e-03 m |
Known Limits
- The runtime using the solver must match the same physics and integration assumptions; different timesteps or integrators can invalidate the hit.
- Strongly nonlinear cases are handled numerically, so convergence quality depends on solver settings and problem conditioning.
- Non-converged cases return explicit status codes and the best result found, so callers can decide how to handle difficult shots.