The camera measures its own smoothness
The last instrument was mis-specified: it compared an arriving update against our current position, but those are at different times, so most of the 0.40 m it reported was latency times speed rather than prediction error. It could not have shown a visual jump even if one existed. The follow trace agreed - per-step motion stayed tight at 1.36 to 1.68 m and tracked speed, with no outliers riding on top. It did settle one thing: corrections arrive 43 times a second, near the 50 Hz step rate, so whatever ticks a few times a second is not one per correction. So measure the symptom instead of a theory about its cause. A visible tick IS a step that moves much further, or much less, than the steps around it, and that is now counted directly: spikes above 2.5x a short running mean, stalls below 0.4x, judged against the mean rather than an absolute distance because a pod at 75 m/s moves 1.5 m per step and one against a wall moves nothing. Respawns are counted and excluded - they teleport hundreds of metres and are meant to be discontinuities. Stated in advance, so the result cannot be read to taste: spikes at a few per second confirms the tick is in entity motion and gives its rate; spikes and stalls near zero refutes it, and points at frame delivery or the newly-active map raster instead. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -349,6 +349,30 @@ void
|
||||
static int moved = 0;
|
||||
static Scalar biggest = 0.0f;
|
||||
|
||||
//
|
||||
// A visible tick IS a step that moves much further, or much less,
|
||||
// than the steps around it. Measuring that directly beats measuring
|
||||
// anything about where the number came from: it does not care
|
||||
// whether the cause is the network, the catch-up rule, or something
|
||||
// nobody has thought of yet.
|
||||
//
|
||||
// Judged against a short running mean rather than an absolute
|
||||
// distance, because a pod at 75 m/s moves 1.5 m per step and one
|
||||
// sitting against a wall moves nothing - a fixed threshold would
|
||||
// call every acceleration a spike.
|
||||
//
|
||||
// What confirms: spikes running at a few per second. That is the
|
||||
// reported tick, and its rate is in the count.
|
||||
// What refutes: spikes and stalls near zero. Then entity motion is
|
||||
// smooth and the tick is not in the simulation at all, which points
|
||||
// at frame delivery or the map raster instead.
|
||||
//
|
||||
static Scalar mean_step = 0.0f;
|
||||
static int spikes = 0;
|
||||
static int stalls = 0;
|
||||
static int respawns = 0;
|
||||
static Scalar worst_ratio = 0.0f;
|
||||
|
||||
++steps;
|
||||
if (have_last)
|
||||
{
|
||||
@@ -363,6 +387,38 @@ void
|
||||
{
|
||||
biggest = distance;
|
||||
}
|
||||
|
||||
//
|
||||
// A respawn teleports hundreds of metres and is MEANT to be a
|
||||
// discontinuity. Counted, excluded, and the mean restarted so
|
||||
// one does not brand the following steps as stalls.
|
||||
//
|
||||
if (distance > 50.0f)
|
||||
{
|
||||
++respawns;
|
||||
mean_step = 0.0f;
|
||||
}
|
||||
else if (mean_step > 0.01f)
|
||||
{
|
||||
Scalar ratio = distance / mean_step;
|
||||
if (ratio > 2.5f)
|
||||
{
|
||||
++spikes;
|
||||
if (ratio > worst_ratio)
|
||||
{
|
||||
worst_ratio = ratio;
|
||||
}
|
||||
}
|
||||
else if (ratio < 0.4f)
|
||||
{
|
||||
++stalls;
|
||||
}
|
||||
mean_step = mean_step * 0.9f + distance * 0.1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
mean_step = distance;
|
||||
}
|
||||
}
|
||||
last_target = target;
|
||||
have_last = True;
|
||||
@@ -374,11 +430,19 @@ void
|
||||
DEBUG_STREAM << "CamLog: follow - " << steps << " steps, "
|
||||
<< moved << " moved, biggest jump " << biggest
|
||||
<< "m, " << gCameraCuts << " cut(s)\n" << std::flush;
|
||||
DEBUG_STREAM << "CamLog: smoothness - " << spikes
|
||||
<< " spike(s), " << stalls << " stall(s), "
|
||||
<< respawns << " respawn(s), worst " << worst_ratio
|
||||
<< "x the running mean of " << mean_step << "m\n" << std::flush;
|
||||
}
|
||||
next_say = ((Scalar) Now()) + 5.0f;
|
||||
steps = 0;
|
||||
moved = 0;
|
||||
biggest = 0.0f;
|
||||
spikes = 0;
|
||||
stalls = 0;
|
||||
respawns = 0;
|
||||
worst_ratio = 0.0f;
|
||||
gCameraCuts = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user