From The Dreadnought Project
Jump to: navigation, search

Simulating Ballistics

My simulation requires ballistics to be fairly realistic and, as important, systematic, as the design of simulated gunsights must match the ballistics closely. You can find a sample range table creating using my process here.

What is a Range Table?

A range table is a series of rows sorted by range in 100 yard or 100 metre intervals detailing the performance of a given gun firing a given shell with a given powder charge under given conditions. The columns of each row contain different characteristics of a firing of the shell to the given range, such as the angle of elevation required to reach that range, and the time of flight of the shell. These parameters are all functions of the range for the gun/shell/powder system being described as it is exercised through ranges up to its maximum range.

In different eras, different nations used different formats for range tables. Apart from variations in choice of unit to be be employed (e.g.: yards or metres), as time passed more columns would be added in the name of completeness or to suit some new need.

I created virtual range tables to permit me to judge the accuracy of how I simulated a shell's passage through the air, as I am interested in simulation games and the players of such games get downright uneasy if you cannot demonstrate the exact nature of how your pretend weapons work, and they get argumentative if you cannot illustrate the data you selected as its basis in reality. Consequently, I decided to center on range tables as a means of illustrating in quantitative terms how my simulation performs so that intelligent challenges can be made to its accuracy and suggestions for improvement can be rationally considered. In the best case, having a number of virtual range tables which differ only slightly from tables created for the real weapon system might serve as a basis for judging the accuracy of those simulated weapon systems for which no real world range table has been located for comparison. Ideally, when sufficient confidence in the simulation logic has been established, questions of the accuracy of any simulated system model can be confined to the real world data chosen as inputs in creating its virtual analog.

Finding Input Data

It may sound like cheating, but the best source for input data is a real world range table for the weapon system being modeled. A historical range table is a primary source document that is hard to impeach even if it may lack some desirable information. Having a complete table on hand also provides the modeler with a nice template for creating his program's output, and a complete master document against which his results can be compared.

Input data from a real-world range table

Here are the portions of the historical range table I used as the basis for my simulation of the weapon system shown in my example table. In all, these are the data I required:

  1. diameter of shell
  2. weight of shell
  3. muzzle velocity
  4. the most extreme range/elevation pair available
  5. lateral drift for a long range shot (optional)

Additionally, if I am running the "high fidelity" simulation:

  1. radius of curvature of the shell's head
  2. total length of the shell

All other data in the range table can be inferred by using physical simulation. The simulation must be sufficiently "true" for this to work, but the good news is that the historical range table itself can serve as a nice check of the end result — how closely do the simulated data entries agree with those in the range table?


Blammo! is a web application I created that uses my ballistics simulation code to create range tables. You can run it here (requires a web plug-in from a very reputable company).

Equipped with only data above, Blammo! systematically infers all other values in the table with a high degree of accuracy. The simulated test firings used to calculate this occur in three phases.

Phase 1: Match Drag Characteristics to Historical Performance

A series of shots are simulated at the elevation given for the range/elevation datum provided (data #4 above). A binary search is undertaken to find a drag coefficient that makes the shell fly to exactly the datum range (see below, for discussion of High Fidelity and Low Fidelity simulation modes).

Phase 2: Simulate Firing at Various Elevations

Historically, range table data were the result of a process much like this phase: the guns were taken to a well-surveyed proving ground and fired 8-20 times at different elevations and the time of flight and point of impact for each shot was noted. A series of corrections were then applied to offset any difference between actual firing conditions (e.g., barometric pressure, humidity, temperature) and the nominal standard conditions for the service, and mathematical methods were then used to create data for angles of impact and "culminating point" (the trajectory's apogee). In our virtual equivalent, we are blessed with perfect weather conditions and rely less on fancy mathematics and more on "actual" test firings. Since it is unlikely that we'll ever fire one of these guns again and the only "weapon" we'll ever create a sighting mechanism for will be a virtual one incorporating the same code we're using, this is ideal.

In the Phase 2 test firing series, the program fires the virtual gun at a number of different elevations to demonstrate the entire envelope I'd like to characterize in a range table. It starts with an elevation of 1/8 of a degree with the shell just above ground level and fires the simulated shot. Another shot is taken at 1/4 degree, and 1/2 degree, and one degree. Then at 1 degree intervals until we reach (say) 10 degrees, and a series at 2 degree intervals upwards from there and maybe even 3 degree intervals if I want to support very high elevation mountings. One could clearly get a nice range table indeed if one fired thousands of shots, but the truth is that only around 10 or 20 are needed to get a pretty accurate range table because you are going to perform spline-based interpolation between the data you measure from this relatively small number of firings.

For each test shot, we measure and record the range, elevation, time of flight, angle of fall, culmination point (apogee), and impact velocity for the shell -- all the fundamental data we'd like to feature in the columns of the real range table that was our primary source. Then, we "spline" the values from these columns taken at this series of elevations. As background, a spline is a series of N-1 third-order polynomials that can be used to approximate a curve defined by N sampling points -- the nice quality of this representation is that the curve is continuous and passes through all the sample points and flows smoothly. In this way, even though the relationships are subtle and difficult to characterize symbolically, splining them provides us a flexible description of their nuance that is continuous through 2 derivatives.

I compute the following splines using the data above:

  • range to elevation (column 2)
  • range to time of flight (column 3)
  • range to culminating height (column 4)
  • range to culminating distance (column 5)
  • range to angle of descent (column 6)
  • range to remaining velocity (column 7)

Column 8 in the table shown (Danger space in yards for a 30 foot target) is merely 10/tangent(column 6) . Curiously, I note that the historical table has an incorrect value for this -- it should be 25 yards at the angle of descent cited.

Coming up with a value for Column 9 – Variation in Range corresponding to a change in muzzle velocity – requires a third phase of test firings.

Phase 3: Reduce the Muzzle Velocity and Test Fire

The muzzle velocity is reduced by an increment (in the case of this table, 10 feet per second) and the elevation ladder from Phase 2 is repeated. The loss in range reached is splined and values read off this are the grist for column 9. At this point, the columns of the range table are fully represented by smooth splines relating their value to range. All that remains in this application is to print out a range table in a format similar to the historical document.

Printing an HTML Range Table

The range table printing portion of the application simply has a boilerplate form for an HTML web page. It reads the name of the weapon, the dimensions of the shell, etc, from the range table data structure, and prints the column headers. Range is iterated between 100 and 20,000 yards in 100 yard increments, and the range table's spline functions are queried to supply the necessary data for each column, converting each value into the desired units. Presto -- a nice range table which should very nearly approximate the real weapon system (see discussion of errors below) and very accurately match the performance of the simulated shells (if one wanted to use the same physical modeling logic in a simulation game, for instance).

Other Features of the Ballistic Simulation

The sim approximates ballistic drift (the better the data on hand, the better will be the simulation, though it is not as strictly physics-based as are the above behaviors). It is also capable of fudging in "50% Errors" for the weapon. These too are not elegantly simulated, but the end result is the same, statistically – each shot will have a random error in range and direction conforming to the researched data, and the result is obtained by adding velocity to the shell to deliver the correct behaviour. Drift and these varied sources of imprecision are very difficult to characterize mathematically and so this is why I instead chose a data-fed method for introducing these effects. I am fairly confident that the physical simulation of projectiles in this package is faithful enough to the important details of performance that few interesting questions would be answered incorrectly by regarding its results as authoritative (subject only to the quality of input data provided, of course).

Missing Features in the Ballistic Simulation

  • Wind, when used, is considered to be uniform at all altitudes.
  • The shell's drag coefficient to the wind does not consider yaw.
  • Coriolis effect is not modeled.
  • Shells never yaw or become unstable in flight.
  • Effects of humidity are ignored.
  • Barometric pressure is treated simply.
  • Atmospheric modeling could use a real expert's help.
  • My data model allows each researched datum to be cited, but Blammo! in its present form does not prompt the user to provide this data.



As to methodology, I'll offer just one thought: how closely do splines track these dissimilar relationships? The litmus test for this question would be to conduct virtual test firings and see how they compare to the corresponding lines in the simulated table. I've not done such a test yet. One remedy, of course, would be to conduct vastly more test firings and create a range table where each row recorded a specific virtual test firing. This would take advantage of the fact that it costs very little indeed to fire a virtual gun!

High Fidelity versus Low Fidelity Modes

A given projectile's drag coefficient changes as it passes through the air as a function of the speed of sound. I support this in my "High Fidelity" simulation, using an updated C# version of R. L. McCoy's McDrag (December, 1974) and McGyro (April, 1986) programs to calculate a drag/Mach relationship for the shell.

In my "Low Fidelity" simulation, I model the drag of the shells in flight as a drag coefficient applied to their drag area as they move through an atmosphere whose density conforms to a simple function of altitude.

When I conduct Phase 1 above in creating a range table, the binary search directly seeks the simple drag coefficient in "Low Fidelity" mode, and seeks a scaling factor to apply to the drag-coefficient-versus-Mach function given by McDrag that makes the shell's flight match the range/elevation datum provided as input.

The present version of Blammo! only works in the high fidelity model, using a scaling factor of about 0.9 in one test case (which indicates some confidence in McDrag's accuracy). I hope to soon alter it so that the extra inputs (nose shape, shell total length) required by the high fidelity model are optional, and that low fidelity mode would be used when they're absent.


N.B.: this section is dated, and based on an earlier version of my code.

You will see that my range table does not perfectly match the historical one. Some of these errors seem tolerably small, and others start to threaten to be too large. What is up with that?

Some of the errors are in the original tables consulted. The tables themselves were based on a series of just 10-15 test shots being taken on a range. The intermediate rows on the table were entirely a product of mathematical interpolation techniques which might, in some cases, have been approximations less reliable than my physical simulation technique (at least, when it is sufficiently advanced).

Additional experimental errors applicable to the real world gun system but not my virtual one are that the gun might not have been fired under conditions exactly matching the standard Royal Navy atmospheric conditions, and hence the very first step would be an imperfect but well-chosen correction step which amounted to a series of rules of thumb and tables being consulted. The real weapons engineers presumably had no real means at all to guess at the culmination height and distance save a sound mathematical formula (this is not such a big deal, however, as the culmination point is nearly trivia). Lastly, it bears mention that materiel was sometimes wanting in the Royal Navy, particularly early in the 20th century. A good example of this was that shell weights varied significantly from the norm, and I don't know whether all early test firings had the individual shells weighed. Even if they were, the rules of thumb to neutralize their deviations from the norm may have introduced errors. 50% error zones, as measured in breadth and length, were probably based on a statistically insignificant number of sample shots intended to gather this information.

For other errors, let's focus on the entry for 20,000 yards, as this is where the differences are most profound given the extent of simulation shells have undergone by the time they reach that range. In the following, I have converted all angular measures into pure degrees.

Time of Flight
Culminating Distance
Culminating Height
Angle of Descent
Remaining Velocity
feet per sec
Variation of Range
Real Table
My Table

Don't be TOO impressed by the accuracy in elevation at 20,000 yards -- recall that this range is the one I coerced the system to match in Phase 1 of the calibration process. A fairer metric for this might be to look midway into the table, where my elevation was .035 degrees less than the historic table's (0.62%). I am at a loss to explain the Variation of Range discrepancy -- it is shockingly large and I did not used to get this error in older versions of the code. All remaining errors I think I am fairly comfortable with, but improvement is apt to be found in creating a fuller atmospheric model. I hope that I find knowledgeable persons to help me in that quest, as I am not eager to learn about humidity and such, but if someone can fortify my code in this area without altering the design of the logic too grossly, I'd be keen to hear from them.

I look forward to creating a more accurate system and then pushing on to see what else this can be applied toward. More range tables for different weapons are a sure thing, and I invite you to share any such data you may have. I personally have extensive RN tables for 1910 through 1918 and can pretty much do them all.

See Also

Tone August, 2014