A running mean is blind to alternation

The split is unanimous and one detail settles it: in two windows the eye
travelled 0.0001m - a trackside camera standing perfectly still - and the
pod stalled 15 and 29 times anyway. CameraShip::FollowGoal is exonerated,
and so is the pan. It is the pod motion itself.

That contradicts this trace only in appearance. It has been comparing each
step against a RUNNING MEAN, and a running mean cannot see an alternating
pattern: high, low, high, low averages to the mean and nothing ever looks
anomalous. The renderer compares each frame against the PREVIOUS one,
which catches exactly that, and counted 15 to 46 stalls in the same motion
this trace called clean. So the mean test never ruled out uneven motion.
It only ever ruled out drift.

Apply the same consecutive test one level down, and keep twelve
consecutive step lengths verbatim so the shape can be read rather than
inferred from counters. Twelve steps is a quarter second at 50Hz - long
enough to show a beat, short enough to fit on one line.

The clock fix confirmed itself in passing: the reported intervals are now
multiples of 17ms, the frame time, which is the honest resolution for a
per-frame detector. The 1/32s artifact is gone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-08-11 10:33:57 -05:00
co-authored by Claude Opus 5
parent 2bd824e16e
commit 3c49bc4fd1
+54
View File
@@ -726,6 +726,11 @@ void
static Scalar min_percent = 1.0f;
static Scalar max_percent = 0.0f;
static Scalar worst_error = 0.0f;
static Scalar last_distance = 0.0f;
static Scalar samples[12];
static int sample_count = 0;
static int seq_stalls = 0;
static int seq_spikes = 0;
++steps;
if (have_last)
@@ -734,6 +739,43 @@ void
moved.Subtract(localOrigin.linearPosition, last_pos);
Scalar distance = moved.Length();
//
// The same test the renderer applies to drawn frames:
// this step against the one before it, not against a
// running mean.
//
// A running mean is blind to an alternating pattern -
// high, low, high, low averages to the mean and nothing
// ever looks anomalous - which is why this trace has
// been reporting zero spikes and zero stalls while the
// renderer, comparing consecutive frames, counted
// fifteen to forty-six stalls in the same motion. The
// mean test only ever ruled out DRIFT.
//
if (distance < 50.0f)
{
if (last_distance > 0.001f)
{
Scalar sequential = distance / last_distance;
if (sequential < 0.4f) { ++seq_stalls; }
else if (sequential > 2.5f) { ++seq_spikes; }
}
last_distance = distance;
//
// And keep a few consecutive steps verbatim, so the
// shape can be READ rather than inferred from
// counters. Twelve steps is a quarter second at
// 50Hz - long enough to show a beat, short enough
// to fit one line.
//
if (sample_count < 12)
{
samples[sample_count++] = distance;
}
}
if (distance > 50.0f)
{
mean_step = 0.0f; // respawn, not motion
@@ -766,6 +808,15 @@ void
<< "s worst miss " << worst_error << "s\n"
<< std::flush;
DEBUG_STREAM << "CamLog: replicant sequence - "
<< seq_stalls << " stall(s), " << seq_spikes
<< " spike(s) against the PREVIOUS step; steps:";
for (int s = 0; s < sample_count; s++)
{
DEBUG_STREAM << " " << samples[s];
}
DEBUG_STREAM << "\n" << std::flush;
DEBUG_STREAM << "CamLog: replicant arrivals - widest gap "
<< widestGap << "s, " << longGapCount
<< " long, " << queuedGapCount
@@ -788,6 +839,9 @@ void
min_percent = 1.0f;
max_percent = 0.0f;
worst_error = 0.0f;
sample_count = 0;
seq_stalls = 0;
seq_spikes = 0;
}
{
Scalar missed =