← back to BallisticLens

Stack

What's actually running.

The technical substrate behind BallisticLens — the libraries, the storage, the guardrails, and the deliberate choices about where determinism ends and the model begins.

The stack

PHP · MySQL · PDO
Web Audio API · BiquadFilterNode
HTML5 Canvas · Imagick
Pejsa-style drop approximation
PHP GD Library
ElevenLabs TTS
WebAuthn / Passkeys (V2)

Range card generation

PHP GD library renders a branded USPSA-style session card: initials-only shooter identity (no full name, no email), hardware and ammo stamps, scaled hit overlays with centroid marker, and split times when available. Cards are output as JPEG at 1200×1600, sized for print.

On the roadmap

  • QR deep-link to a shareable verification pageMP-511
  • 9:16 story-size card variant for socialMP-512
  • Revocable verification links from the history dashboardMP-8

Acoustic shot timer

Built on the Web Audio API with a BiquadFilterNode set to 500Hz lowpass — Pocket Mode. The filter isolates the concussive pressure wave of a muzzle blast from the noise floor of a live range: brass hitting concrete, holster draws, steel impacts. Indoor echo lockout: 120ms. Outdoor: 50ms. AudioContext.suspend() fires after five minutes of silence. Split times, total string, and raw timestamps persist per session.

Lead Instructor coaching persona

A vocabulary engine of coaching lines organized into four tiers: Elite, Improved, Consistency, and Regression. Context-matched by Shooter Delta, split performance, experience level, and target distance, then delivered via ElevenLabs text-to-speech. The persona is stoic, technical, and direct. It does not congratulate. It diagnoses.

On the roadmap

  • Expand the library to 48+ linesMP-141
  • Session repetition tracking — never repeat a lineMP-141
  • Cold-start detection (first shot of the day)MP-11

Computer vision pipeline

Imagick preprocessing chain: grayscale conversion → 15% contrast stretch floor → 2px Gaussian blur → candidate hole detection. Results are rendered on an HTML5 Canvas with manual tap override — the shooter confirms or corrects detections before scoring is applied. Manual confirmation is always authoritative. Every upload has EXIF and GPS metadata stripped via Imagick::stripImage() before storage. Files are renamed to SHA256-derived hashes; the storage directory is locked from public listing.

Pejsa-style zeroing & Shooter Delta

The Pejsa-style solver approximates theoretical point of impact from firearm profile data — bore-to-optic height, zero distance, muzzle velocity — so the Shooter Delta (the vector between the actual hit centroid and theoretical POI) is already corrected for mechanical offset before any coaching happens. A close-range low hit caused by sight-over-bore offset reads as a low prediction too, so it never gets mistaken for a flinch. From there a deterministic fault wheel maps the delta to its likely cause along the standard shot-analysis chart — low-left to jerking the trigger, high to heeling, and so on through all eight directions — mirrored for left-handed shooters. That mapping is an established coaching heuristic, not a physics proof, so the read is framed honestly: a probable cause from a consistent group, to be confirmed with a ball-and-dummy or dry-fire check, never a verdict on a single shot. It weighs how far to trust each read by how tight the group is — a scattered group is told to fix the grip before chasing a direction — and pairs every diagnosis with the drill that confirms it. A mid-session hardware hot-swap control lets the shooter change firearm profiles without ending the string.