Doc 5 · Teach It to Aim — Spatial Intelligence for Coordinated Spotlights¶
Engineered Lighting prototype series · July 2026 Your V-JEPA model answers what is happening (reading, cooking, movie). This document answers where it's happening and what pan/tilt angles put light there — for multiple fixtures, coordinating. Constraints held: all video local; central RTX 6000 box runs perception; one camera per room; assisted room scan OK; HA/MQTT ecosystem; fixture form factor deprioritized (floor lamps fine).
Hardware assumption, stated plainly: the phases here run on the already-owned RTX 6000 Blackwell workstation. That card matters for the full vision (many rooms + V-JEPA); Phase 0's single-camera tracking runs fine on any recent CUDA GPU with ~12 GB+, so the first demo doesn't wait on big hardware.
Bill of Materials — per room + one-time, ~$120–320/room¶
| # | Part | Qty | Est. | Where | Notes |
|---|---|---|---|---|---|
| 1 | PoE camera — standard rooms: Amcrest IP5M-T1179EW-AI-V3 (5 MP, 133° lens) | 1/room | $80 | amcrest.com | Phase 0. The room's eyes: a wide fixed lens covering the whole room from a corner, streaming standard RTSP video the GPU box ingests directly. PoE = one cable carries power and data, and wired video is what keeps a many-camera home stable and lets the camera network run fully internet-isolated |
| 1b | — priority rooms: Loryta/Dahua IPC-T549M-ALED-S3 (full-color night vision) | opt. | $185 | empiretech01.com | Phase 1+, optional. Night matters: IR cameras output grayscale, which degrades RGB-trained models |
| 2 | PoE switch (8–16 port) + Cat6 runs | 1/home | $150–400 | Amazon | Phase 1+ (Phase 0's single camera can run off any PoE injector). Put cameras on their own VLAN with no internet route — privacy by construction |
| 3 | ChArUco calibration board (print + mount on rigid backing) | 1 | ~$10 | print it (calib.io generator) | Phase 1. For registering each camera to the room scan. Rigid and flat matters |
| 4 | iPhone/iPad Pro with LiDAR (borrow one) + Polycam or Scaniverse app | 1 | free–$ | App Store | Phase 1. One-time room scan, ~1–3 cm accuracy. Use Space Mode (LiDAR), not the auto-floorplan mode |
| 5 | Optional, later: one stereo depth camera — Orbbec Gemini 335L ($359) or Luxonis OAK-D Pro PoE ($579) | 0–1 | $359 / $579 | store.orbbec.com, shop.luxonis.com | Tier 2, later. True per-pixel 3D for the specific rooms where ground-plane geometry runs out (reclined people, heavy clutter) — buy after Tier-0 tracking measurably misses, not before (see "the depth question") |
| — | Already owned | — | — | — | RTX 6000 Blackwell box (runs all perception), the Doc 3/4 bench rig (the actuator being aimed), Home Assistant + MQTT (the message plumbing) |
Concepts (plain English)¶
- Frames & transforms: every position lives in some coordinate system ("frame") — the room, a camera, a fixture. A transform converts between them. The whole aiming stack is: target in room frame → transform to fixture frame → two angles.
- Intrinsics / extrinsics: a camera's intrinsics describe its lens (how pixels map to directions); extrinsics are where it sits in the room. Calibrate both once, then every pixel becomes a 3D ray.
- Ground-plane trick (homography): a person's feet touch the floor, and we know where the floor is. So one ordinary camera gives their 3D position: pixel → ray → intersect floor. This is the finding that deletes depth sensors from the plan.
- Keypoints / pose: models that find body joints (ankles, wrists, head) in an image. Body-scale keypoints work across a room; finger-scale does not (hands are 20–40 pixels at 4–8 m — too small, verified 2026 research).
- Tracking ID: detection says "a person is here this frame"; tracking says "it's the same person as last frame." Needed so beams follow individuals, not flicker between people.
- Open-vocabulary detection: models you query with words ("book") instead of fixed class lists. Used to confirm a book is present, not to measure it precisely.
- Latency vs. update rate: latency = how stale each measurement is; update rate = how often they arrive. Smooth following needs ~15–30 updates/second and prediction to cover the staleness (below).
- One Euro filter: the standard smoothing trick for noisy tracking — heavy smoothing when still (kills jitter), light smoothing when moving (kills lag). Cheap, three lines of code.
- Fast path / slow path: two loops sharing the cameras. Fast: person tracking at 15–30 Hz → aim. Slow: video clips → V-JEPA → "they're reading" (arrives seconds later, changes policy, not coordinates). The fast path never waits for the slow one.
- No-go cone: a computed exclusion zone around each tracked head that beams must never enter — borrowed from automotive adaptive headlights, which mask glare zones around oncoming drivers in exactly this way.
- Named tools, one line each: YOLO26 — the current fast, standard "find the people in this frame" model. ByteTrack — the standard "it's the same person as last frame" ID-keeper. Frigate — an open-source camera recorder/reviewer that runs on the GPU box (used for recording and clips, never in the aiming loop). DeepStream — NVIDIA's toolkit for running vision models over many camera streams at once (an optional productized shortcut). go2rtc — a small program that re-serves camera streams with minimal delay.
1. What we're building (the six findings)¶
- No stereo needed to start. Ground-plane localization delivers 4–19 cm accuracy in room-scale tests (4–13 cm standing, 16–19 cm walking) — comfortably inside the real beam, which the optics research pinned down: the tightest off-the-shelf 3-up optic (Carclo 10507, ~16°) throws a 0.42 m spot at 1.5 m, growing to ~0.85 m at 3 m. NVIDIA productized this pattern (DeepStream SV3DT/MV3DT, auto-calibration, 645–1,225 FPS aggregate on this GPU class). Seated people (feet unusable): the room model supplies the couch height, torso keypoints supply the rest. Stereo is a targeted later upgrade.
- Beam self-calibration is the differentiator. No commercial system — including $30k zactrack/BlackTrax — auto-calibrates fixtures; all use a manual jog onto known points. But the recipe exists (a 2025 patent describes it; telescope pointing models supply the math with ~170× margin over our 1° need): sweep the beam, let the camera watch where it lands, fit the model. A fixture that calibrates itself in ~2 minutes beats the industry's shipped state of the art. (Patent flag: US 12,190,542.)
- The follow-me loop is real but unforgiving. 100–300 ms end-to-end is achievable only on a bespoke path (camera → own tracker → fixture → CAN; the fixture link is MQTT on the bench, graduating to a direct ESPHome native-API action called via aioesphomeapi in production — one hop, typed floats, spec in Doc 6 §1). Convenience shortcuts cost seconds (Frigate events: 6–10 s; HA automations: documented 4–20 s traps). And prediction is structural, not polish: at 300 ms latency a walker moves 42 cm — comparable to the beam's half-width — so the aim point must lead the track by the measured latency. Geometry helps too, and for free: the fixed 10507 optic naturally widens with throw (~0.85 m at 3 m), so the beam is at its most forgiving exactly where tracking error and lag are largest; the tight-spot regime only exists at short throw, where tracking is at its best. (No variable-beam hardware needed — if beam-width experimentation matters later, the Carclo optics snap-swap in seconds, and a motorized-zoom path exists: Khatod's 45 mm slide-zoom, 11–45°, at the cost of redesigning to a single-die emitter.)
- Fixture speed requirement (computed): a person passing 1–1.5 m from a fixture's plumb line needs 54–80°/s pan. Doc 3's stage 5 measures whether the motors stay silent at those speeds; if not, the coordinator caps indoor slew and lets the beam lag through close passes.
- Hands don't work at range — design around them. The book story: anchor the person from feet/torso, offset to the wrist (body keypoints work at range), confirm "book" with open-vocabulary detection. Same evidence reshapes gestures: v1 gestures are arm-scale (raise, wave, hold-out — from body keypoints); finger gestures (pinch, palm shapes) are not feasible from a corner camera. Naive pointing rays err ~28° — fine for "which zone," not for precision (a trained pointing model reaches <2° if ever needed).
- The failure modes are about feelings: never sweep eyes (predictive no-go cones + soft-edged dimming + a hard interlock — tracking loss parks the beam within a deadline); move legibly (a small anticipatory "glance" before the main move reads as intentional — HRI-validated); and suppress motion during movie/settled-reading — lights that move when people are trying to be still is the documented trust-killer.
2. User stories (the problem space)¶
| ID | Story | Note |
|---|---|---|
| A — Follow & task | ||
| A1 | Follow me across the room | The canonical hard story: tracking + smoothing + handoff |
| A2 | Light the surface I'm using (table/board/desk) | Validated demand — $600 task lamps that don't even move |
| A3 | Spotlight the book in my hands | White space: every current solution is worn on the body |
| A4 | Cooking-step lighting (board → stove as activity shifts) | Context-driven; bridges to the DLP recipe story later |
| A5 | Light my face on video calls | Adjacent shipped demand (ring lights, Apple Edge Light) |
| B — Ambient & idle | ||
| B1 | Point at wall art when idle | Static target — trivial once calibrated |
| B2 | Plant/decor accents on schedule | Zero live perception needed |
| B3 | Gallery rotation with dwell times | Motion styling matters most here |
| C — Media & social | ||
| C1 | Movie mode = stillness | Suppression is a feature; movement here is the trust-killer |
| C2 | Light the board-game table when we gather | Group context from the activity model |
| C3 | Party sweeps | The one home for stage-light behavior |
| D — Utility | ||
| D1 | 3am path light | Ankle-height, dim, never near eyes |
| D2 | Find-my-keys by pointing light at them | No shipped product does this — needs object memory |
| D3 | Closet/pantry assist | Beam into the space you just opened |
| D4 | Pet play/follow | $20 auto laser toys validate the appetite |
| E — Interaction | ||
| E1 | Arm-scale gestures (raise/wave/hold-out), context-armed | Gating evidence: 5.5× fewer false positives; V-JEPA-gated version is novel |
| E2 | Point at a spot to send light there | Coarse zone-selection in v1; precision needs a trained model |
| E3 | Summon / banish the beam | Beckon it over; wave it away |
| F — Multi-person & multi-fixture | ||
| F1 | Each person gets their own beam | Research favors this "spatial multiplexing" over preference arbitration |
| F2 | Seamless fixture handoffs while walking | Hysteresis so beams don't ping-pong |
| F3 | Second fixture covers occlusions | Redundancy when line-of-sight breaks |
| F4 | My preferences follow me | Identity via trajectory re-ID; feeds the roadmap's identity layer |
| G — Trust (gates everything) | ||
| G1 | Never sweep a beam across eyes | Hard constraint: predictive no-go cones |
| G2 | Fail calm | Tracking loss → park/dim, never hunt |
| G3 | Legible motion | Anticipation micro-moves, context speed caps |
| G4 | Visible "perception off" state | The being-watched objection is the adoption risk |
3. The architecture in one picture¶
PoE cams ──► RTX 6000 box: go2rtc (low-latency restream)
├─ FAST 15–30 Hz: detect (YOLO26) → track IDs →
│ ground-plane 3D → keypoints → One-Euro+prediction
│ → TARGET RESOLVER → ASSIGNMENT → SAFETY LAYER
└─ SLOW (event clips, 2–8 fps): V-JEPA → activity state
Frigate: recording/review only — NOT in the control path
│ direct MQTT {fixture, pan, tilt, rate, dim}
ESPHome C6 nodes (batch_delay: 0) ──► CAN ──► RMD actuators
Home Assistant: observes, overrides — never in the loop
Annotations on each block:
- Target resolver: static targets (art, table) are label lookups in the room model — zero runtime perception. Dynamic targets come from tracks, led by velocity. Book = wrist offset from the person anchor.
- Assignment (which fixture takes which target): bipartite matching (Hungarian) with costs = incidence-angle badness (light the task from beside/behind the person, not their face) + travel + a hysteresis bonus for the incumbent. Run assignment at 1–5 Hz (sticky), aiming at 15–30 Hz — per-frame reassignment invites beam flapping. Handoffs cross-fade. Honest status: no published algorithm exists for lights; this is greenfield.
- Safety layer (runs last, overrides all): predictive no-go cones around heads (extrapolate by angular velocity — static per-frame checks demonstrably fail on fast motion), soft-edge dimming at cone borders, UGR ≤ 19 as a computable glare budget, and the interlock: tracking-confidence loss → park/dim within a deadline.
- The camera sees the beam — design for it: a bright moving spot shifts auto-exposure and casts moving shadows. Lock camera exposure, test the tracker with beams active, mask the commanded spot region if needed. (The same fact becomes an asset in calibration.)
- Aiming math: closed-form angles per fixture from the calibrated model, with the dual-solution constraint (every target has a mirrored pan+180° twin — pick one and don't flip).
4. Step-by-step execution plan¶
Phase 0 — "The lamp follows me" (a weekend; needs only the Doc 3/4 rig + any RTSP camera)¶
- Mount the camera high in a corner and get its stream working — budget an hour if you've never set up an IP camera: on first boot it forces an admin password (via its app or web page at the camera's IP); enable RTSP/ONVIF in its settings (often off by default); then confirm the stream plays in VLC (Media → Open Network Stream). Amcrest/Dahua URL pattern:
rtsp://user:pass@CAMERA_IP:554/cam/realmonitor?channel=1&subtype=0— the camera's web UI or manual confirms the exact path. While in settings, set fixed exposure (the beam-in-view rule from §3).
🤖 Give this to your agent
You're my bench agent for the Engineered Lighting perception stack
(chapter: engineering.engineered.lighting/05-teach-it-to-aim/, Phase 0
steps 2-6). The corner camera is mounted and streaming RTSP with fixed
exposure, and the Doc 3/4 gimbal rig is on the bench with its ESPHome
node subscribed to the spotlight/target MQTT topic, forwarding to CAN.
Start by proposing a plan and wait for my approval before executing
anything.
Task: build the follow-me tracker on the GPU box, in a git repo, and
iterate on it while I watch the beam. (a) pip install ultralytics and
run YOLO26 person detection on the stream with ByteTrack IDs via
model.track(); read frames through OpenCV with buffering disabled —
grab-and-discard so we always process the newest frame. (b) Floor
calibration: I tape 4 marks in a big rectangle and tape-measure their
true room-frame positions; take my clicked pixel positions from one
saved frame and compute the pixel-to-floor homography with
cv2.getPerspectiveTransform. (c) For each tracked person, map the
bottom-center of the box (the feet) through the homography to (x, y)
on the floor; smooth with a One Euro filter, estimate velocity, and
compute the led aim point (position + velocity × measured loop
latency). (d) Fixture pose: I tape-measure the gimbal's (x, y, z);
compute pan = atan2 and tilt = atan toward a chest-height point above
the aim point. (e) Publish {"v":1, "ts":..., "pan":..., "tilt":...,
"rate":60} — the Doc 6 envelope fields — to the spotlight/target
topic at ~10-15 Hz, and use mosquitto_sub on that topic to verify
what the fixture is actually being told; the 0xA4 speed field keeps
motion continuous between updates.
SAFETY — non-negotiable: never command motor motion unless I confirm
I'm watching with a hand near the supply switch. The bench current
limit stays as set. Announce each motion command before sending it
and wait for my explicit go.
Done when: the beam follows you smoothly across the room and you have
latency + noise numbers.
Report back: end-to-end latency (wave-to-beam from slow-mo video),
beam lag at walking speed, tracking noise while standing still, a
mosquitto_sub capture of spotlight/target, and the diff of every
script added to the repo.
- On the GPU box:
pip install ultralytics+ run YOLO26 person detection on the stream; add ByteTrack IDs (built into Ultralytics'model.track()); read frames via OpenCV with buffering disabled (grab-and-discard so you always process the newest frame — the classic seconds-of-lag trap). This script — and every GPU-box script in this doc — is ideal Claude Code territory: run it in a git repo on the box and have it scaffold, run, and iterate on the tracker while you watch the beam; it can alsomosquitto_subthe output topic to verify what the fixture is actually being told. - Floor calibration (15 min): tape 4 marks on the floor in a big rectangle; measure their true positions with a tape measure (room frame = one corner of the room, x/y along walls); click their pixel positions in one saved frame;
cv2.getPerspectiveTransformgives the pixel→floor homography. - For each tracked person: bottom-center of the box (≈ feet) → homography → (x, y) on the floor. Smooth with a One Euro filter; estimate velocity; compute the led aim point (position + velocity × measured loop latency).
- Fixture pose: measure the gimbal's (x, y, z) with a tape measure;
pan = atan2,tilt = atantoward a chest-height point above the aim point. - Publish
{"v":1, "ts":…, "pan":…, "tilt":…, "rate":60}(envelope fields per Doc 6) to the MQTT topicspotlight/targetat ~10–15 Hz (the name Doc 3 stage 9 and Doc 4's stage-6 look-ahead both use); the Doc 4 ESPHome node subscribed to that topic forwards to CAN. The 0xA4 speed field makes motion continuous between updates. - Walk the room. Measure: end-to-end latency (wave-to-beam on slow-mo video), beam lag at walking speed, noise during tracking.
Done when: the beam follows you smoothly across the room and you have latency + noise numbers. This single demo validates the entire stack's riskiest loop.
Phase 1 — Surfaces & suppression (the room model arrives)¶
🤖 Give this to your agent
You're my bench agent for the Engineered Lighting perception stack
(chapter: engineering.engineered.lighting/05-teach-it-to-aim/, Phase 1
— surfaces & suppression). The follow-me loop from Phase 0 works off
a 4-point floor homography, and I have a LiDAR room scan (Polycam
Space Mode, rescaled against one tape-measured distance) exported as
a mesh/point cloud.
Start by proposing a plan and wait for my approval before executing
anything.
Task: be my calibration helper for registering the camera to the room
scan and wiring in the room model. (a) Help me label ~10-20 surfaces
from the scan into named JSON entries {name, centroid, normal,
extent} — I do the lasso clicking in CloudCompare or SuperSplat, you
build and validate the JSON. (b) Register the camera to the scan: I
photograph the ChArUco board at a spot picked from the scan; you run
solvePnP and invert for the camera pose, with sanity checks —
reprojection under 1 px plus a few clicked non-coplanar points.
(c) Replace the Phase 0 4-point floor homography with the registered
camera + the scan's floor (better everywhere in the room). (d) Wire
activity context in: subscribe the states the existing model
publishes over MQTT and map them in the resolver — reading@couch to
wall-art idle, cooking to the cutting-board target, movie to
suppression (no spontaneous motion).
SAFETY — non-negotiable: never command motor motion unless I confirm
I'm watching with a hand near the supply switch. The bench current
limit stays as set. Announce each motion command before sending it
and wait for my explicit go.
Done when: "light the table," "point at the art," and movie-stillness
all work from label lookups.
Report back: the solvePnP reprojection error and non-coplanar check
results, before/after floor-position accuracy at a few tape-measured
spots, the labeled-surfaces JSON, a mosquitto_sub capture showing a
context state switching the target, and the diff.
- Scan the room (Polycam Space Mode, LiDAR); tape-measure one known distance; rescale if off. Export mesh/point cloud.
- Label ~10–20 surfaces once, manually (CloudCompare or SuperSplat lasso → named JSON
{name, centroid, normal, extent}). Fifteen minutes of clicking beats a research project — auto-labeling (open-vocab 3D) is still unreliable on loose language like "cutting board." - Register the camera to the scan: ChArUco board at a spot picked from the scan → one photo →
solvePnP→ camera pose (invert!). Sanity: reprojection <1 px, plus a few clicked non-coplanar points. (Marker-based beats automatic matching indoors — the leading auto tool's own maintainers report >80% indoor failure.) - Replace Phase 0's 4-point floor homography with the registered camera + scan floor (better everywhere in the room).
- Wire activity context in: your existing model publishes states over MQTT; the resolver maps
reading@couch→ wall-art idle vs.cooking→ cutting-board target;movie→ suppression (no spontaneous motion).
Done when: "light the table," "point at the art," and movie-stillness all work from label lookups.
Phase 2 — Self-calibration (the crown jewel)¶
Greenfield — no agent prompt yet: no proven recipe to encode. Work this phase with your agent from the text below.
- Sweep each fixture through a coarse pan/tilt grid spanning its full range but constrained to camera-visible landings (spots outside the FoV or occluded teach nothing; if the visible region is small, densify there or add a second camera pose).
- At each grid point: beam on/off, frame-difference, centroid of the spot; ray-cast that pixel onto the scan mesh for the 3D landing point. Lock exposure; run at dimmed ambient — the system controls the room's other lights, so calibrate at night automatically for maximum contrast.
- Fit fixture pose + encoder zero-offsets + axis non-orthogonality by least squares (Levenberg–Marquardt; the telescope-pointing term structure). Error budget: scan ~2 cm + registration ~2 cm + centroid ~2 cm → RSS ≈ 3.5 cm ≈ 0.67° at 3 m — inside the ~1° budget, not by miles; measure residuals rather than assuming them.
- Verify: command the beam to 10 labeled targets, measure landing error with the camera. Keep the manual 4-point jog as bootstrap/fallback. Re-fit automatically if drift is detected (the camera checks every landing forever — the system notices its own miscalibration).
Done when: a fixture placed anywhere self-calibrates in ~2 minutes and lands within ~1° on demand. This is also when fixture #2 arrives.
Phase 3 — Book & gestures v1¶
Greenfield — no agent prompt yet: no proven recipe to encode. Work this phase with your agent from the text below.
- Book: person anchor + wrist keypoint offset → aim; open-vocab confirm ("book" via YOLOE/SAM-3-class model on a wrist-region crop) to arm the behavior.
- Gestures: arm-scale only (raise/wave/hold-out from body keypoints), armed by context state; coarse point-to-zone (ray from shoulder→wrist, snapped to the nearest labeled surface).
Done when: the beam lands on a held book within one beam-width; a raised-arm gesture reliably toggles it; and a normal evening passes with zero false gesture triggers.
Phase 4 — Coordination & safety hardening¶
Greenfield — no agent prompt yet: no proven recipe to encode. Work this phase with your agent from the text below.
Two fixtures, two people: Hungarian assignment @ 1–5 Hz with hysteresis; cross-fade handoffs; predictive no-go cones + soft-edge dimming + tracking-loss interlock; motion styling (anticipation micro-move, context speed caps). Done when: two people walk crossing paths and the beams hand off without flapping or ever crossing a face.
Phase 5 — Precision & identity¶
Greenfield — no agent prompt yet: no proven recipe to encode. Work this phase with your agent from the text below.
Trained pointing model (<2°) only if coarse pointing earns it; geometric/trajectory re-ID → per-person preferences (feeds the roadmap's identity layer).
Done when: a pointed arm selects the intended zone ≥9 times in 10, and two household members each get their saved warmth/brightness without asking.
5. The depth question, answered directly¶
| Tier | Hardware | Covers | When |
|---|---|---|---|
| 0 — ground plane + room model | none new | follow-me, all static targets, couch-seated (model priors), book (wrist offset), heads for safety | Start here |
| 1 — better software | none | multi-camera fusion (halves jitter), occlusion-robust tracking, object memory | as stories demand |
| 2 — one stereo camera in a hard room | $359–579 | true 3D for reclined/floor-sitting, heavy clutter, tight multi-person; sharper self-cal | only when Tier 0 measurably misses |
| ✗ monocular depth networks | GPU only | — | skip — jittery, 18–40 cm @ 4 m, worse than free geometry |
Fisheye note: a 180°+ lens covers big rooms from one corner but needs a fisheye calibration model + dewarp before any of the geometry above — prefer two normal cameras when a room demands more coverage.
6. Risk register (honest)¶
- Novel, no precedent: the V-JEPA + real-time-tracker dual path and world-model-gated gestures are unpublished combinations — analogs de-risk the pattern; the integration is ours to prove.
- Coordination policy is greenfield — expect tuning cycles on costs/hysteresis; no literature will save us.
- Slow-path latency is seconds-to-tens-of-seconds (clips → V-JEPA): context-driven target switches lag activity changes; stories must tolerate it, and anything sub-second belongs on the fast path by design.
- Hands at range stay unsolved (2026) — stories are designed to wrist-level precision, which the beam width forgives.
- No public benchmarks for this GPU on Frigate/DeepStream/V-JEPA — benchmark early; margins on adjacent hardware suggest ample headroom.
- Edge-migration debt (strategic): the prototype is deliberately central-GPU, but the commercial product runs on a home-hub NPU. Cheap to migrate: YOLO-class detection, tracking, all the ground-plane/calibration/aiming math (it's just algebra). Expensive to migrate: SAM-3-class open-vocab segmentation, DeepStream-specific pipelines (NVIDIA-locked), full-size V-JEPA. Prefer the portable primitive wherever two options tie; treat every DeepStream convenience as prototype-only.
- Product-kit camera transport must be reconciled: if the commercial kit's per-room cameras stream continuous WiFi video, a 5–10 room home lands exactly in the documented WiFi-collapse regime. The edge hierarchy in the Engineered Lighting strategy roadmap (an internal doc outside this series) is the answer — tier-1 vision on-device, ship metadata/clips, not video — the prototype's stream-everything pattern is a lab convenience the product must not inherit. Wired/PoE is the alternative at installation-friction cost.
- Camera brand watch item (checked July 2026 — re-check before any camera purchase): the FCC Covered-List expansion targets Dahua/Hikvision procurement — residential unaffected, but firmware/inventory longevity is worth watching for Dahua-lineage brands.
- Patents for counsel: US 12,190,542 (beam self-calibration), US 11,956,873 (multi-fixture follow-spot control), Forma (motorized recessed fixtures).
- Trust is the real adoption risk: the same research validating demand documents the "being watched" objection — suppression states, legible motion, and a visible perception-off affordance are requirements, not polish.
Further reading (most load-bearing)¶
Ground-plane localization accuracy — arxiv.org/abs/2606.13509 · DeepStream 9.1 MV3DT + AutoMagicCalib — developer.nvidia.com/blog (July 2026) + DS_Performance docs · One Euro filter — CHI 2012, direction.bordeaux.inria.fr/~roussel · REACH (hands at room range) — arxiv.org/abs/2605.22231 · SAM 3 — ai.meta.com/blog/segment-anything-model-3 · YOLO26 — docs.ultralytics.com · Beam self-cal patent — patents.google.com/patent/US12190542B2 · Beamatron (steerable-projector math, MSR UIST 2012) — hbenko.com · Pan-tilt kinematic calibration — arxiv.org/pdf/1812.00232 · TPOINT pointing models — bisque.com · OpenCV solvePnP/ChArUco — docs.opencv.org · hloc indoor-failure admission — github.com/cvg/Hierarchical-Localization/issues/325 · Polycam — learn.poly.cam · zactrack/BlackTrax/Follow-Me (manual-calibration prior art) — vendor sites · LuminAR (MIT robotic lamp precedent) — spectrum.ieee.org · Frigate autotracking + smoothing lessons — docs.frigate.video, github issue #20903 · PointingNet — arxiv.org/abs/2307.02949 · Animation principles for robots (HRI 2011) — leilatakayama.org · ADB glare masking — NHTSA DOT HS 812 174 · ILDA audience-scanning safety — ilda.com · go2rtc — github.com/AlexxIT/go2rtc · WiFi multi-camera collapse — ipcamtalk thread 77100 · ESPHome batch_delay — esphome.io/components/api · V-JEPA 2 — github.com/facebookresearch/vjepa2