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

Inputsrelative target motion, speed, drag, solver params
SimulationRK4 projectile integration with drag and wind
Auxiliary Residualvacuum ballistic response maps miss into launch-angle correction
SolveLevenberg-Marquardt + line search + Broyden-style Jacobian refinement
DeployC ABI, Python package, Unity/C#, .NET, and Godot interop

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.

relative position [m]
relative velocity [m/s]
conditions
wind [m/s]
numerics

Coordinates: x forward, y right, z up. The HTTP API uses RK4 drag/wind + closest-approach residual + LM solver.

low arc -

waiting for input

high arc -

waiting for input

solve status

ready

low arc high arc target

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
fast0.094 ms0.228 ms3.834e-02 m
balanced0.182 ms0.452 ms5.351e-03 m
precise0.199 ms0.569 ms5.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 path382/5004.301 ms27.124 ms3.227e+02 m
v0.6.0 defaults490/5001.845 ms2.535 ms8.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.