ballistics-ng 0.1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +12 -0
- data/Rakefile +51 -0
- data/examples/table.rb +10 -0
- data/ext/ballistics/ext.c +136 -0
- data/ext/ballistics/extconf.rb +3 -0
- data/ext/ballistics/gnu_ballistics.h +577 -0
- data/lib/ballistics.rb +77 -0
- data/lib/ballistics/atmosphere.rb +110 -0
- data/lib/ballistics/cartridge.rb +177 -0
- data/lib/ballistics/cartridges/300_blk.yaml +159 -0
- data/lib/ballistics/gun.rb +123 -0
- data/lib/ballistics/guns/pistols.yaml +6 -0
- data/lib/ballistics/guns/rifles.yaml +34 -0
- data/lib/ballistics/guns/shotguns.yaml +6 -0
- data/lib/ballistics/problem.rb +102 -0
- data/lib/ballistics/projectile.rb +165 -0
- data/lib/ballistics/projectiles/300_blk.yaml +321 -0
- data/lib/ballistics/util.rb +67 -0
- data/lib/ballistics/yaml.rb +57 -0
- data/test/atmosphere.rb +26 -0
- data/test/ballistics.rb +31 -0
- data/test/cartridge.rb +121 -0
- data/test/gun.rb +85 -0
- data/test/problem.rb +137 -0
- data/test/projectile.rb +163 -0
- data/test/util.rb +28 -0
- metadata +102 -0
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'ballistics/yaml'
|
2
|
+
|
3
|
+
class Ballistics::Gun
|
4
|
+
class ChamberNotFound < KeyError; end
|
5
|
+
|
6
|
+
MANDATORY = {
|
7
|
+
"name" => :string,
|
8
|
+
"chamber" => :string,
|
9
|
+
"barrel_length" => :float,
|
10
|
+
"sight_height" => :float,
|
11
|
+
}
|
12
|
+
OPTIONAL = {
|
13
|
+
"zero_range" => :float,
|
14
|
+
}
|
15
|
+
|
16
|
+
# map a chamber name to a built-in cartridge YAML filename
|
17
|
+
CHAMBER_CARTRIDGE = {
|
18
|
+
'5.56' => '5_56',
|
19
|
+
'300 BLK' => '300_blk',
|
20
|
+
# TODO: create these cartridge yamls
|
21
|
+
# '.45 ACP' => '45_acp',
|
22
|
+
# '12ga' => '12ga',
|
23
|
+
}
|
24
|
+
|
25
|
+
# Load a built-in YAML file and instantiate gun objects
|
26
|
+
# Return a hash of gun objects keyed by gun id (per the YAML)
|
27
|
+
#
|
28
|
+
def self.find(short_name)
|
29
|
+
objects = {}
|
30
|
+
Ballistics::YAML.load_built_in('guns', short_name).each { |id, hsh|
|
31
|
+
obj = self.new(hsh)
|
32
|
+
if block_given?
|
33
|
+
objects[id] = obj if yield obj
|
34
|
+
else
|
35
|
+
objects[id] = obj
|
36
|
+
end
|
37
|
+
}
|
38
|
+
objects
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.find_id(id)
|
42
|
+
Ballistics::YAML::BUILT_IN.fetch('guns').each { |short_name|
|
43
|
+
object = self.find(short_name)[id]
|
44
|
+
return object if object
|
45
|
+
}
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.fetch_id(id)
|
50
|
+
self.find_id(id) or raise("id #{id} not found")
|
51
|
+
end
|
52
|
+
|
53
|
+
attr_reader(*MANDATORY.keys)
|
54
|
+
attr_reader(*OPTIONAL.keys)
|
55
|
+
attr_reader(:yaml_data, :extra)
|
56
|
+
|
57
|
+
def initialize(hsh)
|
58
|
+
@yaml_data = hsh
|
59
|
+
MANDATORY.each { |field, type|
|
60
|
+
val = hsh.fetch(field)
|
61
|
+
val = val.to_s if field == "chamber"
|
62
|
+
Ballistics::YAML.check_type!(val, type)
|
63
|
+
self.instance_variable_set("@#{field}", val)
|
64
|
+
}
|
65
|
+
|
66
|
+
OPTIONAL.each { |field, type|
|
67
|
+
if hsh.key?(field)
|
68
|
+
val = hsh[field]
|
69
|
+
Ballistics::YAML.check_type!(val, type)
|
70
|
+
self.instance_variable_set("@#{field}", val)
|
71
|
+
end
|
72
|
+
}
|
73
|
+
|
74
|
+
# Keep track of fields that we don't expect
|
75
|
+
@extra = {}
|
76
|
+
(hsh.keys - MANDATORY.keys - OPTIONAL.keys).each { |k|
|
77
|
+
@extra[k] = hsh[k]
|
78
|
+
}
|
79
|
+
@cartridges = []
|
80
|
+
end
|
81
|
+
|
82
|
+
def chamber=(new_chamber)
|
83
|
+
@cartridges = []
|
84
|
+
@chamber = new_chamber
|
85
|
+
end
|
86
|
+
|
87
|
+
def cartridge_file
|
88
|
+
CHAMBER_CARTRIDGE[@chamber] or raise(ChamberNotFound, @chamber)
|
89
|
+
end
|
90
|
+
|
91
|
+
# this will pull in cartridges and projectiles based on the gun chamber
|
92
|
+
def cartridges
|
93
|
+
if @cartridges.empty?
|
94
|
+
require 'ballistics/cartridge'
|
95
|
+
|
96
|
+
cartridge_file = CHAMBER_CARTRIDGE[@chamber] or
|
97
|
+
raise(ChamberNotFound, @chamber)
|
98
|
+
@cartridges =
|
99
|
+
Ballistics::Cartridge.find_with_projectiles(cartridge_file)
|
100
|
+
end
|
101
|
+
@cartridges
|
102
|
+
end
|
103
|
+
|
104
|
+
def params
|
105
|
+
params = { sight_height: @sight_height }
|
106
|
+
params[:zero_range] = @zero_range if @zero_range
|
107
|
+
params
|
108
|
+
end
|
109
|
+
|
110
|
+
def multiline
|
111
|
+
lines = ["GUN: #{name}", "==="]
|
112
|
+
fields = {
|
113
|
+
"Chamber" => @chamber,
|
114
|
+
"Barrel length" => @barrel_length,
|
115
|
+
"Sight height" => @sight_height,
|
116
|
+
}
|
117
|
+
fields["Zero Range"] = @zero_range if @zero_range
|
118
|
+
fields.each { |name, val|
|
119
|
+
lines << [name.rjust(13, ' ' ), val].join(': ')
|
120
|
+
}
|
121
|
+
lines.join("\n")
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
ar15_carbine:
|
2
|
+
name: Standard AR-15 carbine with 16 inch barrel (5.56)
|
3
|
+
sight_height: 2.6
|
4
|
+
barrel_length: 16
|
5
|
+
zero_range: 50
|
6
|
+
chamber: 5.56
|
7
|
+
|
8
|
+
m4:
|
9
|
+
name: Standard M4 carbine with 14.5 inch barrel (5.56)
|
10
|
+
sight_height: 2.6
|
11
|
+
barrel_length: 14.5
|
12
|
+
zero_range: 50
|
13
|
+
chamber: 5.56
|
14
|
+
|
15
|
+
m16:
|
16
|
+
name: Standard M16 rifle with 20 inch barrel (5.56)
|
17
|
+
sight_height: 2.6
|
18
|
+
barrel_length: 20
|
19
|
+
zero_range: 100
|
20
|
+
chamber: 5.56
|
21
|
+
|
22
|
+
ar15_sbr:
|
23
|
+
name: AR-15 SBR with 10.5 inch barrel (5.56)
|
24
|
+
sight_height: 2.6
|
25
|
+
barrel_length: 10.5
|
26
|
+
zero_range: 50
|
27
|
+
chamber: 5.56
|
28
|
+
|
29
|
+
ar15_300_blk:
|
30
|
+
name: AR-15 with 10.5 inch barrel (300 BLK)
|
31
|
+
sight_height: 2.6
|
32
|
+
barrel_length: 10.5
|
33
|
+
zero_range: 50
|
34
|
+
chamber: 300 BLK
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'ballistics'
|
2
|
+
require 'ballistics/projectile'
|
3
|
+
require 'ballistics/cartridge'
|
4
|
+
require 'ballistics/gun'
|
5
|
+
require 'ballistics/atmosphere'
|
6
|
+
|
7
|
+
class Ballistics::Problem
|
8
|
+
DEFAULTS = {
|
9
|
+
shooting_angle: 0, # degrees; downhill 0 to -90, uphill 0 to +90
|
10
|
+
wind_speed: 0, # mph
|
11
|
+
wind_angle: 90, # degrees; 0-360 clockwise; 90 right, 270 left
|
12
|
+
interval: 50, # yards
|
13
|
+
max_range: 500, # yards
|
14
|
+
y_intercept: 0, # inches; -2 means POI 2 inches below POA @ zero range
|
15
|
+
}
|
16
|
+
|
17
|
+
def self.simple(gun_id:, cart_id:, gun_family: nil)
|
18
|
+
if gun_family
|
19
|
+
gun = Ballistics::Gun.find(gun_family).fetch(gun_id)
|
20
|
+
else
|
21
|
+
gun = Ballistics::Gun.fetch_id(gun_id)
|
22
|
+
end
|
23
|
+
cart = gun.cartridges.fetch(cart_id)
|
24
|
+
self.new(projectile: cart.projectile,
|
25
|
+
cartridge: cart,
|
26
|
+
gun: gun)
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_accessor :projectile, :cartridge, :gun, :atmosphere
|
30
|
+
|
31
|
+
def initialize(projectile: nil,
|
32
|
+
cartridge: nil,
|
33
|
+
gun: nil,
|
34
|
+
atmosphere: nil)
|
35
|
+
@projectile = projectile
|
36
|
+
@cartridge = cartridge
|
37
|
+
@gun = gun
|
38
|
+
@atmosphere = atmosphere
|
39
|
+
end
|
40
|
+
|
41
|
+
# Given a hash of specified options / params
|
42
|
+
# Return a hash of params enriched by DEFAULTS as well as any inferred
|
43
|
+
# parameters from @projectile, @cartridge, @gun, and @atmosphere
|
44
|
+
#
|
45
|
+
def enrich(opts = {})
|
46
|
+
mine = {}
|
47
|
+
mine.merge!(@projectile.params) if @projectile
|
48
|
+
mine.merge!(@gun.params) if @gun
|
49
|
+
mine[:velocity] = @cartridge.mv(@gun.barrel_length) if @cartridge and @gun
|
50
|
+
|
51
|
+
# Set up the return hash
|
52
|
+
# opts overrides mine overrides DEFAULT
|
53
|
+
ret = DEFAULTS.merge(mine.merge(opts))
|
54
|
+
|
55
|
+
# validate drag function and replace with the numeral
|
56
|
+
if ret[:drag_function] and !ret[:drag_number]
|
57
|
+
ret[:drag_number] =
|
58
|
+
Ballistics::Projectile.drag_number(ret[:drag_function])
|
59
|
+
end
|
60
|
+
|
61
|
+
# apply atmospheric correction to ballistic coefficient
|
62
|
+
if ret[:ballistic_coefficient] and @atmosphere
|
63
|
+
ret[:ballistic_coefficient] =
|
64
|
+
@atmosphere.translate(ret[:ballistic_coefficient])
|
65
|
+
end
|
66
|
+
|
67
|
+
ret
|
68
|
+
end
|
69
|
+
|
70
|
+
# Return a multiline string showing each component of the problem
|
71
|
+
#
|
72
|
+
def report
|
73
|
+
lines = []
|
74
|
+
lines << @gun.multiline if @gun
|
75
|
+
lines << @cartridge.multiline if @cartridge
|
76
|
+
lines << @projectile.multiline if @projectile
|
77
|
+
lines << @atmosphere.multiline if @atmosphere
|
78
|
+
lines.join("\n\n")
|
79
|
+
end
|
80
|
+
|
81
|
+
# Given a zero range and basic ballistics parameters
|
82
|
+
# Return the angle between sight axis and bore axis necessary to achieve zero
|
83
|
+
#
|
84
|
+
def zero_angle(opts = {})
|
85
|
+
Ballistics.zero_angle self.enrich opts
|
86
|
+
end
|
87
|
+
|
88
|
+
# Return a data structure with trajectory data at every interval for the
|
89
|
+
# specified range
|
90
|
+
#
|
91
|
+
def trajectory(opts = {})
|
92
|
+
Ballistics.trajectory self.enrich opts
|
93
|
+
end
|
94
|
+
|
95
|
+
# Return a multiline string based on trajectory data
|
96
|
+
#
|
97
|
+
def table(trajectory: nil, fields: nil, opts: {})
|
98
|
+
Ballistics.table(trajectory: trajectory,
|
99
|
+
fields: fields,
|
100
|
+
opts: self.enrich(opts))
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'ballistics/yaml'
|
2
|
+
|
3
|
+
class Ballistics::Projectile
|
4
|
+
MANDATORY = {
|
5
|
+
"name" => :string,
|
6
|
+
"cal" => :float,
|
7
|
+
"grains" => :count,
|
8
|
+
}
|
9
|
+
# one of these fields is mandatory
|
10
|
+
BALLISTIC_COEFFICIENT = {
|
11
|
+
"g1" => :float,
|
12
|
+
"g7" => :float,
|
13
|
+
}
|
14
|
+
OPTIONAL = {
|
15
|
+
"sd" => :float,
|
16
|
+
"intended" => :string,
|
17
|
+
"base" => :string,
|
18
|
+
"desc" => :string,
|
19
|
+
}
|
20
|
+
DRAG_FUNCTION = {
|
21
|
+
"flat" => "g1",
|
22
|
+
"boat" => "g7",
|
23
|
+
}
|
24
|
+
DRAG_NUMBER = {
|
25
|
+
"g1" => 1,
|
26
|
+
"g7" => 7,
|
27
|
+
}
|
28
|
+
|
29
|
+
# Load a built-in YAML file and instantiate projectile objects
|
30
|
+
# Return a hash of projectile objects keyed by projectile id (per the YAML)
|
31
|
+
#
|
32
|
+
def self.find(short_name)
|
33
|
+
objects = {}
|
34
|
+
Ballistics::YAML.load_built_in('projectiles', short_name).each { |id, hsh|
|
35
|
+
obj = self.new(hsh)
|
36
|
+
if block_given?
|
37
|
+
objects[id] = obj if yield obj
|
38
|
+
else
|
39
|
+
objects[id] = obj
|
40
|
+
end
|
41
|
+
}
|
42
|
+
objects
|
43
|
+
end
|
44
|
+
|
45
|
+
# Normalize common flat-base and boat-tail terms to flat or boat
|
46
|
+
#
|
47
|
+
def self.base(candidate)
|
48
|
+
c = candidate.to_s.downcase.gsub(/[\-\_ ]/, '')
|
49
|
+
case c
|
50
|
+
when "boat", "boattail", "bt"
|
51
|
+
"boat"
|
52
|
+
when "flat", "flatbase", "fb"
|
53
|
+
"flat"
|
54
|
+
else
|
55
|
+
raise "unknown base: #{candidate}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Convert e.g. G1 to 1
|
60
|
+
#
|
61
|
+
def self.drag_number(drag_function)
|
62
|
+
DRAG_NUMBER.fetch(drag_function.to_s.downcase)
|
63
|
+
end
|
64
|
+
|
65
|
+
attr_reader(*MANDATORY.keys)
|
66
|
+
attr_reader(*BALLISTIC_COEFFICIENT.keys)
|
67
|
+
attr_reader(*OPTIONAL.keys)
|
68
|
+
attr_reader :ballistic_coefficient, :yaml_data, :extra
|
69
|
+
|
70
|
+
def initialize(hsh)
|
71
|
+
@yaml_data = hsh
|
72
|
+
MANDATORY.each { |field, type|
|
73
|
+
val = hsh.fetch(field)
|
74
|
+
Ballistics::YAML.check_type!(val, type)
|
75
|
+
self.instance_variable_set("@#{field}", val)
|
76
|
+
}
|
77
|
+
|
78
|
+
# Extract ballistic coefficients per drag model (e.g. G1)
|
79
|
+
# We need at least one
|
80
|
+
#
|
81
|
+
@ballistic_coefficient = {}
|
82
|
+
BALLISTIC_COEFFICIENT.each { |field, type|
|
83
|
+
if hsh.key?(field)
|
84
|
+
val = hsh[field]
|
85
|
+
Ballistics::YAML.check_type!(val, type)
|
86
|
+
self.instance_variable_set("@#{field}", val)
|
87
|
+
@ballistic_coefficient[field] = val
|
88
|
+
end
|
89
|
+
}
|
90
|
+
raise "no valid BC" if @ballistic_coefficient.empty?
|
91
|
+
|
92
|
+
OPTIONAL.each { |field, type|
|
93
|
+
if hsh.key?(field)
|
94
|
+
val = hsh[field]
|
95
|
+
Ballistics::YAML.check_type!(val, type)
|
96
|
+
if field == "base"
|
97
|
+
@base = self.class.base(val)
|
98
|
+
else
|
99
|
+
self.instance_variable_set("@#{field}", val)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
}
|
103
|
+
|
104
|
+
# Keep track of fields that we don't expect
|
105
|
+
@extra = {}
|
106
|
+
(hsh.keys -
|
107
|
+
MANDATORY.keys -
|
108
|
+
BALLISTIC_COEFFICIENT.keys -
|
109
|
+
OPTIONAL.keys).each { |k|
|
110
|
+
@extra[k] = hsh[k]
|
111
|
+
}
|
112
|
+
|
113
|
+
# Make sure @base and @drag_function are initialized so that
|
114
|
+
# self.drag_function works without warnings
|
115
|
+
#
|
116
|
+
@base ||= nil
|
117
|
+
@drag_function = nil
|
118
|
+
end
|
119
|
+
|
120
|
+
# Return the preferred drag function if there is a BC available
|
121
|
+
#
|
122
|
+
def drag_function
|
123
|
+
return @drag_function if @drag_function
|
124
|
+
@drag_function = @ballistic_coefficient.keys.first
|
125
|
+
if @base
|
126
|
+
preferred = DRAG_FUNCTION.fetch(@base)
|
127
|
+
if @ballistic_coefficient.key?(preferred)
|
128
|
+
@drag_function = preferred
|
129
|
+
end
|
130
|
+
end
|
131
|
+
@drag_function
|
132
|
+
end
|
133
|
+
|
134
|
+
# Return the BC for the preferred drag function
|
135
|
+
#
|
136
|
+
def bc
|
137
|
+
@ballistic_coefficient.fetch(self.drag_function)
|
138
|
+
end
|
139
|
+
|
140
|
+
# Return params that can be used by Ballistics::Problem
|
141
|
+
#
|
142
|
+
def params
|
143
|
+
{ drag_function: self.drag_function,
|
144
|
+
drag_number: self.class.drag_number(self.drag_function),
|
145
|
+
ballistic_coefficient: self.bc }
|
146
|
+
end
|
147
|
+
|
148
|
+
# Return lines of text separated by newlines
|
149
|
+
#
|
150
|
+
def multiline
|
151
|
+
lines = ["PROJECTILE: #{@name}", "=========="]
|
152
|
+
fields = {
|
153
|
+
"Caliber" => @cal,
|
154
|
+
"Grains" => @grains,
|
155
|
+
}
|
156
|
+
@ballistic_coefficient.each { |df, bc|
|
157
|
+
fields["BC (#{df.upcase})"] = bc
|
158
|
+
}
|
159
|
+
fields["Desc"] = @desc if @desc
|
160
|
+
fields.each { |name, val|
|
161
|
+
lines << [name.rjust(7, ' '), val].join(': ')
|
162
|
+
}
|
163
|
+
lines.join("\n")
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,321 @@
|
|
1
|
+
# MANDATORY
|
2
|
+
# $id:
|
3
|
+
# name:
|
4
|
+
# cal:
|
5
|
+
# grains:
|
6
|
+
# AT LEAST ONE OF
|
7
|
+
# g1:
|
8
|
+
# g7:
|
9
|
+
# OPTIONAL
|
10
|
+
# desc:
|
11
|
+
# intended: # e.g. 300 BLK
|
12
|
+
# base: flat|boat
|
13
|
+
# sd:
|
14
|
+
|
15
|
+
# FLAT BASE INTENDED FOR 300 BLK
|
16
|
+
|
17
|
+
barnes_90_otfb:
|
18
|
+
name: Barnes 90gr Zinc OTFB
|
19
|
+
cal: .308
|
20
|
+
grains: 90
|
21
|
+
g1: .246
|
22
|
+
intended: 300 BLK
|
23
|
+
base: flat
|
24
|
+
desc: Open tip, copper jacket, zinc core
|
25
|
+
|
26
|
+
barnes_110_tac_tx_300_blk:
|
27
|
+
name: Barnes 110gr TAC-TX 300 BLK
|
28
|
+
cal: .308
|
29
|
+
grains: 110
|
30
|
+
g1: .289
|
31
|
+
sd: .166
|
32
|
+
intended: 300 BLK
|
33
|
+
base: flat
|
34
|
+
desc: Black polymer tip, copper bullet
|
35
|
+
|
36
|
+
hornady_110_v_max_black:
|
37
|
+
name: Hornady 110gr V-MAX BLACK
|
38
|
+
cal: .308
|
39
|
+
grains: 110
|
40
|
+
g1: .290
|
41
|
+
sd: .166
|
42
|
+
intended: 300 BLK
|
43
|
+
base: flat
|
44
|
+
desc: Red polymer tip, copper jacket, lead core
|
45
|
+
|
46
|
+
remington_120_umc_otfb:
|
47
|
+
name: Remington 120gr UMC OTFB
|
48
|
+
cal: .308
|
49
|
+
grains: 120
|
50
|
+
g1: .297
|
51
|
+
intended: 300 BLK
|
52
|
+
base: flat
|
53
|
+
desc: Copper jacket, lead core
|
54
|
+
|
55
|
+
hornady_125_hp_match:
|
56
|
+
name: Hornady 125gr HP Match
|
57
|
+
cal: .308
|
58
|
+
grains: 125
|
59
|
+
g1: .320
|
60
|
+
sd: .128
|
61
|
+
intended: 300 BLK
|
62
|
+
base: flat
|
63
|
+
desc: Open tip, copper jacket, lead core
|
64
|
+
|
65
|
+
sierra_125_mk:
|
66
|
+
name: Sierra 125gr MatchKing OTFB
|
67
|
+
cal: .308
|
68
|
+
grains: 125
|
69
|
+
g1: .330
|
70
|
+
sd: .188
|
71
|
+
intended: 300 BLK
|
72
|
+
base: flat
|
73
|
+
desc: Open tip, copper jacket, lead core
|
74
|
+
|
75
|
+
sierra_125_tmk:
|
76
|
+
name: Sierra 125gr Tipped MatchKing
|
77
|
+
cal: .308
|
78
|
+
grains: 125
|
79
|
+
g1: .332
|
80
|
+
sd: .188
|
81
|
+
intended: 300 BLK
|
82
|
+
base: flat
|
83
|
+
desc: Green polymer tip, copper jacket, lead core
|
84
|
+
|
85
|
+
hornady_135_ftx:
|
86
|
+
name: Hornady 135gr FTX
|
87
|
+
cal: .308
|
88
|
+
grains: 135
|
89
|
+
g1: .274
|
90
|
+
sd: .203
|
91
|
+
intended: 300 BLK
|
92
|
+
base: flat
|
93
|
+
desc: Red polymer tip, copper jacket, lead core with InterLock
|
94
|
+
|
95
|
+
hornady_208_a_max_black:
|
96
|
+
name: Hornady 208gr A-MAX BLACK
|
97
|
+
cal: .308
|
98
|
+
grains: 208
|
99
|
+
g1: .648
|
100
|
+
sd: .313
|
101
|
+
intended: 300 BLK
|
102
|
+
base: flat
|
103
|
+
desc: Red polymer tip, copper jacket, lead core
|
104
|
+
|
105
|
+
remington_220_umc_otfb:
|
106
|
+
name: Remington UMC 220gr OTFB
|
107
|
+
cal: .308
|
108
|
+
grains: 220
|
109
|
+
g1: 0.680 # best guess, based on Rem 220gr OTFB
|
110
|
+
sd: 0.331 # best guess, based on 220gr SMK
|
111
|
+
intended: 300 BLK
|
112
|
+
base: flat
|
113
|
+
desc: Open tip, copper jacket, lead core
|
114
|
+
|
115
|
+
remington_220_otfb:
|
116
|
+
name: Remington 220gr Open Tip Flat Base
|
117
|
+
cal: .308
|
118
|
+
grains: 220
|
119
|
+
g1: .680
|
120
|
+
sd: 0.331 # best guess, based on 220gr SMK
|
121
|
+
intended: 300 BLK
|
122
|
+
base: flat
|
123
|
+
desc: Open tip, copper jacket, lead core
|
124
|
+
|
125
|
+
# OTHER FLAT BASE
|
126
|
+
|
127
|
+
# Note, Barnes TAC-TX is essentially identical to TTSX -- just a rebranding
|
128
|
+
# with restricted choices appropriate to Mil/LE rifles
|
129
|
+
barnes_110_tac_tx:
|
130
|
+
name: Barnes 110gr TAC-TX 30 CAL
|
131
|
+
cal: .308
|
132
|
+
grains: 110
|
133
|
+
g1: .295
|
134
|
+
sd: .166
|
135
|
+
base: flat
|
136
|
+
desc: Blue polymer tip, copper bullet, general 30 cal
|
137
|
+
|
138
|
+
# Note, Barnes TAC-X is essentially identical to TSX -- just a rebranding
|
139
|
+
# with restricted choices appropriate to Mil/LE rifles
|
140
|
+
barnes_110_tac_x:
|
141
|
+
name: Barnes 110gr TAC X
|
142
|
+
cal: .308
|
143
|
+
grains: 110
|
144
|
+
g1: .264
|
145
|
+
sd: .166
|
146
|
+
base: flat
|
147
|
+
desc: All copper
|
148
|
+
|
149
|
+
barnes_110_tsx:
|
150
|
+
name: Barnes 110gr TSX
|
151
|
+
cal: .308
|
152
|
+
grains: 110
|
153
|
+
g1: .264
|
154
|
+
sd: .166
|
155
|
+
base: flat
|
156
|
+
desc: All copper
|
157
|
+
|
158
|
+
barnes_110_ttsx:
|
159
|
+
name: Barnes 110gr TTSX
|
160
|
+
cal: .308
|
161
|
+
grains: 110
|
162
|
+
g1: .295
|
163
|
+
sd: .166
|
164
|
+
base: flat
|
165
|
+
desc: Blue polymer tip, copper bullet
|
166
|
+
|
167
|
+
sierra_110_fmj:
|
168
|
+
name: Sierra 110gr FMJ
|
169
|
+
cal: .308
|
170
|
+
grains: 110
|
171
|
+
g1: .170
|
172
|
+
sd: .166
|
173
|
+
intended: M1 Carbine
|
174
|
+
base: flat
|
175
|
+
desc: Copper jacket, lead core
|
176
|
+
|
177
|
+
sierra_110_hp:
|
178
|
+
name: Sierra 110gr HP
|
179
|
+
cal: .308
|
180
|
+
grains: 110
|
181
|
+
g1: .204
|
182
|
+
sd: .166
|
183
|
+
base: flat
|
184
|
+
desc: Hollow point, copper jacket, lead core, high accuracy
|
185
|
+
|
186
|
+
sierra_110_rn:
|
187
|
+
name: Sierra 110gr RN
|
188
|
+
cal: .308
|
189
|
+
grains: 110
|
190
|
+
g1: .170
|
191
|
+
sd: .166
|
192
|
+
intended: M1 Carbine
|
193
|
+
base: flat
|
194
|
+
desc: Round lead nose, copper jacket, lead core, expands at low velocity
|
195
|
+
|
196
|
+
berger_115_fb:
|
197
|
+
name: Berger 115gr FB Target
|
198
|
+
cal: .308
|
199
|
+
grains: 115
|
200
|
+
g1: .289
|
201
|
+
base: flat
|
202
|
+
desc: Copper jacket, lead core, 1:19 twist
|
203
|
+
|
204
|
+
sierra_125_spt:
|
205
|
+
name: Sierra 125gr SPT
|
206
|
+
cal: .308
|
207
|
+
grains: 125
|
208
|
+
g1: .264
|
209
|
+
sd: .188
|
210
|
+
base: flat
|
211
|
+
desc: Copper jacket, lead core, spitzer, intended for hunting
|
212
|
+
|
213
|
+
sierra_135_hp:
|
214
|
+
name: Sierra 135gr HP Varminter
|
215
|
+
cal: .308
|
216
|
+
grains: 135
|
217
|
+
g1: .275
|
218
|
+
sd: .203
|
219
|
+
base: flat
|
220
|
+
desc: Hollow point, copper jacket, lead core, 300 BLK compatible
|
221
|
+
|
222
|
+
barnes_150_tac_rrlp:
|
223
|
+
name: Barnes 150gr TAC RRLP
|
224
|
+
cal: .308
|
225
|
+
grains: 150
|
226
|
+
g1: .357
|
227
|
+
sd: .226
|
228
|
+
base: flat
|
229
|
+
desc: Frangible; Reduced Ricochet Limited Penetration
|
230
|
+
|
231
|
+
sierra_150_spt:
|
232
|
+
name: Sierra 150gr SPT
|
233
|
+
cal: .308
|
234
|
+
grains: 150
|
235
|
+
g1: .360
|
236
|
+
sd: .226
|
237
|
+
base: flat
|
238
|
+
desc: Copper jacket, lead core, spitzer, intended for hunting
|
239
|
+
|
240
|
+
sierra_150_rn:
|
241
|
+
name: Sierra 150gr RN
|
242
|
+
cal: .308
|
243
|
+
grains: 150
|
244
|
+
g1: .270
|
245
|
+
sd: .226
|
246
|
+
base: flat
|
247
|
+
desc: Round lead nose, copper jacket, lead core, accurate short range hunting
|
248
|
+
|
249
|
+
#
|
250
|
+
# BOAT TAILS
|
251
|
+
#
|
252
|
+
|
253
|
+
hornady_110_gmx:
|
254
|
+
name: Hornady 110gr GMX
|
255
|
+
intended: 300 BLK
|
256
|
+
cal: .308
|
257
|
+
grains: 110
|
258
|
+
g1: .305
|
259
|
+
sd: .166
|
260
|
+
base: boat
|
261
|
+
desc: Red polymer tip, copper alloy bullet, very short boat tail
|
262
|
+
# g7: TODO
|
263
|
+
|
264
|
+
barnes_120_tac_tx:
|
265
|
+
name: Barnes 120gr TAC-TX
|
266
|
+
cal: .308
|
267
|
+
grains: 120
|
268
|
+
g1: .358
|
269
|
+
sd: .181
|
270
|
+
base: boat
|
271
|
+
desc: Black polymer tip, copper bullet
|
272
|
+
# g7: TODO
|
273
|
+
|
274
|
+
barnes_130_tsx:
|
275
|
+
name: Barnes 130gr TSX
|
276
|
+
cal: .308
|
277
|
+
grains: 130
|
278
|
+
g1: .340
|
279
|
+
sd: .196
|
280
|
+
base: boat
|
281
|
+
desc: All copper
|
282
|
+
# g7: TODO
|
283
|
+
|
284
|
+
barnes_130_ttsx:
|
285
|
+
name: Barnes 130gr TTSX
|
286
|
+
cal: .308
|
287
|
+
grains: 130
|
288
|
+
g1: .350
|
289
|
+
sd: .196
|
290
|
+
base: boat
|
291
|
+
desc: Blue polymer tip, copper bullet
|
292
|
+
# g7: TODO
|
293
|
+
|
294
|
+
barnes_150_tsx:
|
295
|
+
name: Barnes 150gr TSX
|
296
|
+
cal: .308
|
297
|
+
grains: 150
|
298
|
+
g1: .369
|
299
|
+
sd: .226
|
300
|
+
base: boat
|
301
|
+
desc: All copper
|
302
|
+
|
303
|
+
barnes_150_ttsx:
|
304
|
+
name: Barnes 150gr TTSX
|
305
|
+
cal: .308
|
306
|
+
grains: 150
|
307
|
+
g1: .420
|
308
|
+
sd: .226
|
309
|
+
base: boat
|
310
|
+
desc: Blue polymer tip, copper bullet
|
311
|
+
# g7: TODO
|
312
|
+
|
313
|
+
sierra_220_hpbt_mk:
|
314
|
+
name: Sierra 220gr
|
315
|
+
cal: .308
|
316
|
+
grains: 220
|
317
|
+
g1: .608
|
318
|
+
sd: .331
|
319
|
+
base: boat
|
320
|
+
desc: Open tip, copper jacket, lead core
|
321
|
+
# g7: TODO
|