Source code for ballistics.extras

# -*- coding: utf-8 -*-
"""
This module contains useful or interesting functions that are related to ballistics but don't fit well anywhere else.
"""

# CONSTANTS
PROPELLANT_GAS_VELOCITY_CONSTANTS = {
    'HighPoweredRifle': 1.75,
    'AverageLengthShotgun': 1.50,
    'LongBarrelShotgun': 1.25,
    'PistolAndRevolver': 1.50
}

GENERIC_PROPELLANT_GAS_VELOCITY = 5000.0


# HELPER FUNCTIONS
[docs]def propellant_gas_velocity_multiplier(firearm_code): """Provides the Propellant Gas Velocity multiplier for a given firearm_code. Parameters ---------- firearm_code : {'HPR', 'ALS', 'LBS', 'PAR'} * HPR = High Powered Rifle * ALS = Average Length Shotgun * LBS = Long Barrel Shotgun * PAR = Pistol And Revolver Returns ------- float Propellant Gas Velocity multiplier for a given firearm type Notes ----- Refer to http://www.saami.org/PubResources/GunRecoilFormulae.pdf The PROPELLANT_GAS_VELOCITY_CONSTANTS were sourced from the SAAMI GunRecoilFormulae document and were originally derived from "extensive experiments by the British, published in "British Text Book of Small Arms" published in 1929 and confirmed by later work in [the United States]". """ pgvcs = { 'HPR': PROPELLANT_GAS_VELOCITY_CONSTANTS['HighPoweredRifle'], 'ALS': PROPELLANT_GAS_VELOCITY_CONSTANTS['AverageLengthShotgun'], 'LBS': PROPELLANT_GAS_VELOCITY_CONSTANTS['LongBarrelShotgun'], 'PAR': PROPELLANT_GAS_VELOCITY_CONSTANTS['PistolAndRevolver'] } return pgvcs[firearm_code.upper()]
[docs]def propellant_gas_energy(charge_weight_in_grains, muzzle_velocity_in_fps, firearm_code=None): """Calculates the propellant gas energy for a given load and (optionally) firearm type. Parameters ---------- charge_weight_in_grains : float Weight in grains of the powder charge. firearm_code : str Argument to use for the :func:`~ballistics.extras.propellant_gas_velocity_multiplier` function. muzzle_velocity_in_fps : int Muzzle velocity for this load (field measurement or from loading manual reference table). Returns ------- float Propellant gas energy generated for a given load/firearm combination """ if firearm_code: result = charge_weight_in_grains * propellant_gas_velocity_multiplier(firearm_code) * muzzle_velocity_in_fps else: result = charge_weight_in_grains * GENERIC_PROPELLANT_GAS_VELOCITY return result
# Primary Functions
[docs]def approximate_free_recoil_energy(firearm_weight_in_lbs, ejecta_weight_in_grains, charge_weight_in_grains, muzzle_velocity_in_fps, firearm_code=None, decimal_places=0): """Calculates the approximate free recoil energy for a given load. Parameters ---------- firearm_weight_in_lbs : float Weight in lbs of the firearm plus any accessories. ejecta_weight_in_grains : float Weight in grains of the projectile plus wad (if fired from a shotgun). muzzle_velocity_in_fps : int Muzzle velocity for this load (field measurement or from loading manual reference table). charge_weight_in_grains : float Weight in grains of the powder charge. firearm_code : str, optional Argument passed to :func:`~ballistics.extras.propellant_gas_velocity_multiplier` function, default is ``None`` decimal_places : int, optional How many decimal places to return, (default value is 0 which returns the floor of the result). Returns ------- int or float Energy in foot-pounds of recoil (ft.lbf) generated by the input parameters. By default ``decimal_places`` is 0 which will return the nearest integer value. If a value greater than 0 is passed in, the function will return a float value rounded to ``decimal_places``. Notes ----- Refer to http://www.saami.org/PubResources/GunRecoilFormulae.pdf The accuracy of the value returned from this function is directly related to the accuracy of the charge weight and projectile velocity. If a ``firearm_code`` is not passed in, a generic value is used and will result in decreased accuracy of the returned result. """ mass = firearm_weight_in_lbs / 64.34 firearm_weight_in_grains = firearm_weight_in_lbs * 7000.0 ejecta_energy = float(ejecta_weight_in_grains) * muzzle_velocity_in_fps propellant_energy = propellant_gas_energy(charge_weight_in_grains, muzzle_velocity_in_fps, firearm_code) velocity = pow((ejecta_energy + propellant_energy) / firearm_weight_in_grains, 2) return round(mass * velocity, decimal_places)
[docs]def approximate_recoil_velocity(firearm_weight_in_lbs, ejecta_weight_in_grains, muzzle_velocity_in_fps, charge_weight_in_grains, firearm_code=None, decimal_places=0): """Calculates the approximate recoil velocity for a given load. Parameters ---------- firearm_weight_in_lbs : float Weight in lbs of the firearm plus any accessories. ejecta_weight_in_grains : float Weight in grains of the projectile plus wad (if fired from a shotgun). muzzle_velocity_in_fps : int Muzzle velocity for this load (field measurement or from loading manual reference table). charge_weight_in_grains : float Weight in grains of the powder charge. firearm_code : str, optional Argument passed to :func:`~ballistics.extras.propellant_gas_velocity_multiplier` function, default is ``None`` decimal_places : int, optional How many decimal places to return, (default value is 0 which returns the floor of the result). Returns ------- int or float Velocity in feet per second (fps) generated by the input parameters. By default ``decimal_places`` is 0 which will return the nearest integer value. If a value greater than 0 is passed in, the function will return a float value rounded to ``decimal_places``. Notes ----- The accuracy of the value returned from this function is directly related to the accuracy of the charge weight and projectile velocity. If a ``firearm_code`` is not passed in, a generic value is used and will result in decreased accuracy of the returned result. """ ejecta_energy = float(ejecta_weight_in_grains) * muzzle_velocity_in_fps firearm_weight_in_grains = firearm_weight_in_lbs * 7000.0 propellant_energy = propellant_gas_energy(charge_weight_in_grains, muzzle_velocity_in_fps, firearm_code) velocity = (ejecta_energy + propellant_energy) / firearm_weight_in_grains return round(velocity, decimal_places)
[docs]def approximate_recoil_impulse(ejecta_weight_in_grains, muzzle_velocity_in_fps, charge_weight_in_grains, firearm_code=None, decimal_places=0): """Calculates the approximate recoil impulse for a given load. Parameters ---------- ejecta_weight_in_grains : float Weight in grains of the projectile plus wad (if fired from a shotgun). muzzle_velocity_in_fps : int Muzzle velocity for this load (field measurement or from loading manual reference table). charge_weight_in_grains : float Weight in grains of the powder charge. firearm_code : str, optional Argument passed to :func:`~ballistics.extras.propellant_gas_velocity_multiplier` function, default is ``None`` decimal_places : int, optional How many decimal places to return, (default value is 0 which returns the floor of the result). Returns ------- int or float Impulse in pounds per second (lbs.sec) generated by the input parameters. By default ``decimal_places`` is 0 which will return the nearest integer value. If a value greater than 0 is passed in, the function will return a float value rounded to ``decimal_places``. Notes ----- The accuracy of the value returned from this function is directly related to the accuracy of the charge weight and projectile velocity. If a ``firearm_code`` is not passed in, a generic value is used and will result in decreased accuracy of the returned result. """ ejecta_weight_in_kgs = ejecta_weight_in_grains * 0.0000648 # 1gr == 0.0000648kg charge_weight_in_kgs = charge_weight_in_grains * 0.0000648 # 1gr == 0.0000648kg muzzle_velocity_in_meters_per_second = muzzle_velocity_in_fps * 0.3048037 # 1ft == 0.30480370641307 meter ejecta_energy = ejecta_weight_in_kgs * muzzle_velocity_in_meters_per_second if firearm_code: gas_velocity = propellant_gas_velocity_multiplier(firearm_code) * muzzle_velocity_in_fps charge_energy = charge_weight_in_kgs * gas_velocity * 0.3048037 else: charge_energy = charge_weight_in_kgs * GENERIC_PROPELLANT_GAS_VELOCITY * 0.3048037 return round((ejecta_energy + charge_energy) * 0.224809, decimal_places) # 1 newton == 0.224809 pound force