rugnux: the rotation-scale walk stops where the next step would move the sweep end by under half a frame
Each refit reads a share of the error left, so the walk's steps contract by about the ratio of the
last two. Where the step that ratio predicts moves the end of the sweep by less than half a frame,
the refit (an integration of the pre-pass frames and a post-refinement) and the indexing probe after
it are not made; the scale the validation frames last preferred is adopted, as before.
Measured on the walk sets of the battery against rc175 edde4439c: p.hkl and MTZ data identical; it
fired on one open set (2 refits instead of 3, same adopted scale), about -7 s there.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EizBKhTqrAYago9KJG3dA3
This commit is contained in:
@@ -31,9 +31,9 @@ namespace {
|
||||
return 1.0 + 0.7 * (true_scale / k - 1.0);
|
||||
}
|
||||
|
||||
RotationScaleWalk Walk(double first_fit) {
|
||||
RotationScaleWalk Walk(double first_fit, int64_t sweep_images = 3600) {
|
||||
return WalkRotationScale(first_fit, [this](float k) { return IndexAt(k); },
|
||||
[this](float k) { return RefitAt(k); }, 8);
|
||||
[this](float k) { return RefitAt(k); }, 8, sweep_images);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -65,6 +65,22 @@ TEST_CASE("WalkRotationScale_ReachesTheFixedPoint", "[RotationScale]") {
|
||||
CHECK_FALSE(walk.trail.empty());
|
||||
}
|
||||
|
||||
TEST_CASE("WalkRotationScale_StopsWhereTheNextStepIsUnderHalfAFrame", "[RotationScale]") {
|
||||
// Spots enough for the validation frames to prefer every step: what ends the walk is the step the
|
||||
// contraction predicts, measured against the sweep. Each refit reads 70 % of the error left, so the
|
||||
// steps contract by 0.3.
|
||||
SyntheticSweep short_sweep{0.97};
|
||||
short_sweep.spots = 1000000000;
|
||||
const auto a = short_sweep.Walk(short_sweep.RefitAt(1.0f).value(), 360);
|
||||
SyntheticSweep long_sweep{0.97};
|
||||
long_sweep.spots = 1000000000;
|
||||
const auto b = long_sweep.Walk(long_sweep.RefitAt(1.0f).value(), 36000);
|
||||
CHECK(short_sweep.refit_calls < long_sweep.refit_calls);
|
||||
// Where it stops, what is left of the error moves the end of the sweep by under a frame.
|
||||
CHECK(std::fabs(a.scale - 0.97) * 360 < 1.0);
|
||||
CHECK(std::fabs(b.scale - 0.97) * 36000 < 1.0);
|
||||
}
|
||||
|
||||
TEST_CASE("WalkRotationScale_StoredAnglesStand", "[RotationScale]") {
|
||||
SECTION("A healthy stage: a fit off by noise scores no better than the stored angles") {
|
||||
SyntheticSweep sweep{1.0};
|
||||
|
||||
Reference in New Issue
Block a user