Neural Capture · Demo: open Demo tour

Monograph · 02 · Hardware · cameras

02

Foundations · cameras

Hardware · cameras

Chapter contract

Owns Sapera integration: discovery, connect, Snap/Wait, color conversion, parallel group capture. Must not own turntable motion (ch.03) or session path policy (ch.05). Done when a reader can explain why Snap is sequential and save can be parallel.

Role

CameraManager is a singleton wrapping Teledyne DALSA Sapera. It discovers GigE devices, connects transfer+buffer pairs, and captures ordered multi-camera stacks into a directory path supplied by the session layer.

Data model · CaptureParams

CameraManager.hppstruct
// thread-safe params passed by value into CaptureAllCameras
struct CaptureParams {{
  int parallel_groups = 1;   // cameras attempted per group
  int group_delay_ms  = 750; // pause between groups
  int stagger_delay_ms = 150; // delay within group policy
}};
First use · GigE bandwidth

Each 4112×3008 frame is on the order of tens of MB. Saturating a 1 Gbps link with overlapping transfers was observed to crash Sapera — hence sequential Snap+Wait.

End-to-end · CaptureAllCameras

Algorithm · CameraManager::CaptureAllCameras · L331+
  1. Validate parallel_groups ≥ 1, delays ≥ 0; clamp groups to camera count
  2. Warn if parallel_groups > 1 && stagger_ms < 20 (bandwidth risk)
  3. create_directories(session_path)
  4. Build cameras_to_capture from discovered ∩ connected \ disabled
  5. For each group slice of size parallel_groups:
    1. Phase gather: lock mutex, collect SapAcqDeviceToBuf* + SapBuffer*
    2. Phase capture: for each cam Snap() then Wait(5000) sequentially
    3. Phase save: write buffers to disk (parallelizable I/O)
    4. Sleep group_delay_ms before next group
  6. Return success aggregate
Why sequential Snap even inside a “parallel group”

Comments in code: “GigE bandwidth limitation requires sequential Snap+Wait per camera. But file saving can be parallelized.” The speedup (~1.85× cited in thesis) is primarily save-side concurrency, not simultaneous network bursts.

War story · bandwidth

Overlapping transfers caused hard failures in the vendor SDK. The contract is explicit in logs: stagger delays prevent spikes; group delays space bursts. Changing parallel_groups without reading Wait timeouts produces intermittent “Wait timeout” on random cameras — not a clean error every time.

Decision

Sequential Snap + parallel save

Why not full parallel Snap

GigE + Sapera crashed under concurrent transfers. Sequential Snap+Wait is correct; disk I/O parallelism recovers most of the wall-clock (~1.85× save speedup in thesis measurements).

Capture loop with bandwidth contract
Fig. HW-1

Bandwidth contract plate. Same loop diagram used in ch.04 — Snap phase is sequential by design.

Source map

src/hardware/CameraManager.hppAPI · CaptureParams · ColorConfig
src/hardware/CameraManager.cppDiscover · Connect · CaptureAllCameras
src/hardware/CameraTypes.*CameraInfo records