import struct
import zlib
from pathlib import Path
MAGIC = b"BC5D"
VERSION = 2
OUTPUT_FILE = Path("data/bc_tables/bc5d_308.bin")
WEIGHT_BINS = [150.0, 175.0, 200.0]
BC_BINS = [0.4, 0.5, 0.6]
MUZZLE_VEL_BINS = [2700.0, 3000.0]
CURRENT_VEL_BINS = [1000.0, 1500.0, 2000.0, 2500.0]
DRAG_TYPES = 2
def main():
print(f"Generating mock BC5D table...")
print(f" Weight bins: {WEIGHT_BINS}")
print(f" BC bins: {BC_BINS}")
print(f" Muzzle vel bins: {MUZZLE_VEL_BINS}")
print(f" Current vel bins: {CURRENT_VEL_BINS}")
print(f" Drag types: {DRAG_TYPES}")
total_cells = (
DRAG_TYPES
* len(WEIGHT_BINS)
* len(BC_BINS)
* len(MUZZLE_VEL_BINS)
* len(CURRENT_VEL_BINS)
)
print(f" Total cells: {total_cells}")
corrections = []
for drag_idx in range(DRAG_TYPES):
for weight_idx in range(len(WEIGHT_BINS)):
for bc_idx in range(len(BC_BINS)):
for muzzle_idx in range(len(MUZZLE_VEL_BINS)):
for vel_idx in range(len(CURRENT_VEL_BINS)):
correction = 0.95 + 0.0125 * vel_idx
if drag_idx == 1: correction += 0.02
corrections.append(correction)
data_buffer = bytearray()
for w in WEIGHT_BINS:
data_buffer.extend(struct.pack("<f", w))
for b in BC_BINS:
data_buffer.extend(struct.pack("<f", b))
for m in MUZZLE_VEL_BINS:
data_buffer.extend(struct.pack("<f", m))
for c in CURRENT_VEL_BINS:
data_buffer.extend(struct.pack("<f", c))
for corr in corrections:
data_buffer.extend(struct.pack("<f", corr))
checksum = zlib.crc32(data_buffer) & 0xFFFFFFFF
api_version = b"mock_v1.0\x00\x00\x00\x00\x00\x00\x00"[:16]
reserved = b"\x00" * 12
timestamp = 1706400000
header = struct.pack(
"<4sIfIIIIIIIQI16s12s",
MAGIC,
VERSION,
0.308, 0, 0, len(WEIGHT_BINS),
len(BC_BINS),
len(MUZZLE_VEL_BINS),
len(CURRENT_VEL_BINS),
DRAG_TYPES,
timestamp,
checksum,
api_version,
reserved,
)
OUTPUT_FILE.parent.mkdir(parents=True, exist_ok=True)
with open(OUTPUT_FILE, "wb") as f:
f.write(header)
f.write(data_buffer)
print(f"\nWritten: {OUTPUT_FILE} ({OUTPUT_FILE.stat().st_size} bytes)")
print(f"Checksum: {checksum:08x}")
print("\nVerification:")
with open(OUTPUT_FILE, "rb") as f:
magic = f.read(4)
print(f" Magic: {magic}")
assert magic == MAGIC, f"Magic mismatch: {magic}"
version = struct.unpack("<I", f.read(4))[0]
print(f" Version: {version}")
assert version == VERSION, f"Version mismatch: {version}"
caliber = struct.unpack("<f", f.read(4))[0]
print(f" Caliber: {caliber}")
assert abs(caliber - 0.308) < 0.001, f"Caliber mismatch: {caliber}"
print("\nMock table generated successfully!")
print(f"\nTest with: cargo run -- trajectory -v 3000 -b 0.5 -m 175 -d 0.308 --bc-table-dir data/bc_tables --max-range 1000")
if __name__ == "__main__":
main()