Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

# -*- 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 

} 

 

 

# HELPER FUNCTIONS 

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()] 

 

 

def propellant_gas_energy(charge_weight_in_grains, firearm_code, muzzle_velocity_in_fps): 

"""calculates the energy for a given load and 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 

""" 

return charge_weight_in_grains * propellant_gas_velocity_multiplier(firearm_code) * muzzle_velocity_in_fps 

 

 

# Primary Functions 

def approximate_free_recoil_energy(firearm_code, firearm_weight_in_lbs, ejecta_weight_in_grains, 

charge_weight_in_grains, muzzle_velocity_in_fps, decimal_places=0): 

"""Provides the approximate free recoil energy for a given load and firearm type combination 

 

Parameters 

---------- 

firearm_code : str 

Argument to use for the :func:`~ballistics.extras.propellant_gas_velocity_multiplier` function. 

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. 

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 

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. 

""" 

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, firearm_code, muzzle_velocity_in_fps) 

velocity = pow((ejecta_energy + propellant_energy) / firearm_weight_in_grains, 2) 

if decimal_places: 

return round(mass * velocity, decimal_places) 

return int(round(mass * velocity)) 

 

 

def approximate_recoil_velocity(firearm_code, firearm_weight_in_lbs, ejecta_weight_in_grains, muzzle_velocity_in_fps, 

charge_weight_in_grains, decimal_places=0): 

"""Provides the approximate recoil velocity for a given load and firearm type combination 

 

Parameters 

---------- 

firearm_code : str 

Argument to use for the :func:`~ballistics.extras.propellant_gas_velocity_multiplier` function. 

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. 

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 

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. 

""" 

ejecta_energy = float(ejecta_weight_in_grains) * muzzle_velocity_in_fps 

firearm_weight_in_grains = firearm_weight_in_lbs * 7000 

propellant_energy = propellant_gas_energy(charge_weight_in_grains, firearm_code, muzzle_velocity_in_fps) 

velocity = (ejecta_energy + propellant_energy) / firearm_weight_in_grains 

if decimal_places: 

return round(velocity, decimal_places) 

return int(round(velocity))