Skip to content

Commit 9e7dd20

Browse files
RMANOVclaude
andcommitted
Fix Rust convergence bug: compare smoothed vs previous target, not current
The convergence check compared smoothed values against the current tick's target, which gets overwritten by process_brightness/process_audio before the check. With noisy camera readings the target fluctuates each tick, preventing convergence. Now saves previous targets before processing and compares against those — matching the Python version's behavior. Also fixes v4l2 capture_frame requiring &mut self for MmapStream::next(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e1fa9be commit 9e7dd20

File tree

3 files changed

+11
-7
lines changed

3 files changed

+11
-7
lines changed

adaptive-rust/Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

adaptive-rust/crates/bin/src/camera.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl Camera {
5656
}
5757

5858
/// Capture a frame and return grayscale pixel data
59-
pub fn capture_frame(&self) -> Result<Vec<u8>> {
59+
pub fn capture_frame(&mut self) -> Result<Vec<u8>> {
6060
let (buf, _meta) = self.stream.next()?;
6161

6262
// Convert to grayscale based on format

adaptive-rust/crates/bin/src/controller.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ impl Controller {
166166
}
167167
self.last_update = now;
168168

169+
// Save previous targets for convergence (compare smoothed vs PREVIOUS target, like Python)
170+
let prev_target_b = self.last_target_brightness;
171+
let prev_target_v = self.last_target_volume;
172+
169173
// Process brightness data
170174
self.process_brightness()?;
171175

@@ -174,9 +178,9 @@ impl Controller {
174178

175179
// Auto-exit convergence check (after warmup)
176180
if self.config.auto_exit && self.warmup_frame >= self.config.warmup_frames {
177-
let b_ok = self.last_target_brightness
181+
let b_ok = prev_target_b
178182
.map_or(false, |t| (self.smoothed_brightness - t).abs() < 1.0);
179-
let v_ok = self.last_target_volume
183+
let v_ok = prev_target_v
180184
.map_or(true, |t| (self.smoothed_volume - t).abs() < 1.0);
181185
if b_ok && v_ok {
182186
self.converge_count += 1;
@@ -347,7 +351,7 @@ impl Drop for Controller {
347351

348352
/// Camera worker thread
349353
fn camera_worker(tx: Sender<FrameData>, shutdown: Arc<Mutex<bool>>) {
350-
let camera = match Camera::new(0) {
354+
let mut camera = match Camera::new(0) {
351355
Ok(c) => c,
352356
Err(e) => {
353357
warn!("Failed to open camera: {}", e);

0 commit comments

Comments
 (0)