precision-guidance-155mm: The Artillery Simulator That Treats Uncertainty as the Real Battlefield
A Python 6-DOF shell model, a reduced-order guidance loop, and a hard-edged lesson: steering hardware matters less than the quality of the map you feed it.
- The repo’s sharpest claim is that precision guidance is limited by uncertainty in the environment model, not just by actuator authority.
- Its architecture pairs a 6-DOF ground-truth simulator with a reduced-order guidance model so it can compare reality against onboard decision-making.
- The ESTIMATES register turns model uncertainty into enforced metadata, which is unusual for an open-source physics codebase.
- The project reads like a characterization platform, not a demo, because validation, provenance, and Monte Carlo sensitivity are built into the workflow.
The obvious pitch is easy: this repository simulates a guided 155mm shell. The better pitch is harder and more useful. It argues that precision is a knowledge problem before it is a control problem, and that weather, provenance, and uncertainty can matter more than the hardware that moves the fins.
That framing changes how you read the code. Instead of a toy ballistics demo, you get a simulator that keeps asking a blunt question: what happens when the map is wrong?
The punchline is not precision. It is uncertainty.
The project’s most interesting result is not that a canard kit can steer a shell. It is that the system’s ceiling is set by the quality of the atmospheric and state estimate feeding it. If the MET message is noisy or stale, more authority does not buy you proportionally better aim.
That makes the repo feel unusually honest. It does not hide uncertainty inside a pretty chart. It promotes uncertainty to a first-class engineering object.
Hanwha Aerospace has surpassed Poongsan to proceed with the Course Correction Fuze program for 155mm artillery shells in partnership with DAPA. This is a significant mini-game changer for the artillery industry, as it will bring about major changes in industrial, logistical, http
What this repo actually simulates
The repository is split around two models that serve different jobs. The first is a 6-degree-of-freedom rigid-body simulator, which acts as the ground truth. The second is a reduced-order Modified Point Mass Model, or MPMM, based on STANAG 4355, which stands in for what the onboard logic can realistically compute.
| Layer | 6-DOF truth model | MPMM guidance model |
|---|---|---|
| Purpose | Validate physics and trajectory behavior | Predict impact quickly enough for control |
| State detail | Full rigid-body dynamics plus nose states | Reduced-order ballistic propagation |
| Speed | Heavier, more exacting | Lighter, tuned for onboard use |
| Role in the repo | Reference simulator | Decision engine for the guidance loop |
| Failure mode | Computational cost | Approximation error |
That duality is the whole architecture. The repo is not choosing between accuracy and usability. It is making both explicit, then wiring them together so the gaps stay visible.
The despun-nose trick
The shell model extends a standard projectile into a guided one by adding despun nose dynamics on top of a core rigid-body state. The first 13 equations stay intact. The guided projectile adds two more states for the nose, giving the simulator a 15-state structure that preserves the original body motion while layering control on top.
# Conceptual state layout
state = [
x, y, z, # position
u, v, w, # velocity
q0, q1, q2, q3, # quaternion attitude
p, q, r, # angular rates
theta_nose, omega_nose # despun nose states
]
# The body equations remain the baseline.
# The nose introduces an internal torque balance on top.
The clean part is not that the model is complicated. It is that the complexity is quarantined. The body dynamics remain stable and reusable, while the nose dynamics are added as a well-defined extension rather than a rewrite.
That matters because the repo behaves like a physics library, not a one-off script. You can see the discipline in the derivative function design, which is kept pure so it can drop into Monte Carlo runs or hardware-in-the-loop style workflows without hidden state.
How the guidance loop thinks
The guidance loop is predictive, not reactive. It propagates the MPMM forward, estimates where the projectile will land, and then inverts the reachable set to choose a canard deflection that moves the impact point toward the target.
That is a much stronger pattern than simple proportional steering. Instead of asking, “which way should I nudge now,” it asks, “given the current state and constraints, what outcomes are still reachable, and which command gets me closest?”
| Reactive steering | This repo's loop |
|---|---|
| Responds to observed miss after the fact | Predicts impact before choosing a command |
| Treats control as a local correction | Treats control as an inverse problem |
| Uses the present error vector | Uses reachable-set geometry |
| Works best when uncertainty is low | Explicitly tracks uncertainty as part of the decision |
That is why the article’s core metaphor is a map, not a motor. The shell still needs actuation, but the actual problem is choosing from a set of possible futures when the future itself is noisy.
Why the model is honest about what it does not know
This is where the repository gets rare. In `sim/canards.py`, the project draws a bright line between measured body aerodynamics and estimated canard aerodynamics. It does not pretend the estimates are ground truth. It registers them.
The `ESTIMATES` machinery makes those assumptions machine-readable. New tunables cannot quietly enter the system without declaring their source and accuracy. The tests enforce that discipline.
# Conceptual pattern from the repo
ESTIMATES = {
"canard_drag": {
"source": "estimated",
"accuracy": "declared",
"notes": "must be documented before use"
}
}
# If a new tunable is added without provenance,
# the tests are expected to fail.
That is a serious design choice. Most codebases bury uncertainty in comments or README caveats. This one promotes uncertainty into the interface. It turns provenance into a build-time obligation, not a postscript.
The result is a simulator that behaves like a disciplined lab notebook. It knows which numbers are measurements, which are estimates, and which claims still need evidence.
The real benchmark is not hit rate. It is sensitivity.
The analysis layer pushes the project past a single trajectory. Monte Carlo runs, CEP calculations, and sensitivity studies isolate where variance comes from. That matters because a good guidance system is not just one that lands near the target once. It is one that explains why it misses when it misses.
The strongest implication is that meteorology dominates the error budget. Better actuation helps, but better environmental knowledge helps more. In a model like this, the map is not a nice-to-have. It is the bottleneck.
| Question | Naive reading | What the repo measures |
|---|---|---|
| What causes miss distance? | Mostly steering error | A mix of atmosphere, state uncertainty, and authority limits |
| What improves performance most? | More aggressive control | Better MET and better provenance |
| What is the output of analysis? | A hit chart | A sensitivity map of error sources |
| What is the engineering target? | Point accuracy | Reduced uncertainty across the chain |
Why this feels like a professional tool, not a hobby project
The repository has the shape of a real characterization environment. There is a validation ladder, a large test suite, a setter dashboard, and a docs trail that preserves the paper evidence behind the model. That is not casual software.
It also reads like a system designed for auditability. A simulation that touches sensitive physics needs traceability, and this repo makes provenance a visible part of the workflow rather than a hidden social contract.
The result is a project that feels less like a demo and more like an internal research instrument that escaped into the open.