This commit is contained in:
Boki 2026-02-15 11:41:25 -05:00
parent a3001e36e4
commit 343168d85a
2 changed files with 53 additions and 11 deletions

View file

@ -38,8 +38,13 @@ public class MinimapCapture : IFrameConsumer, IDisposable
if (detected != _detectedMode)
{
var oldMode = _detectedMode;
var oldRegion = _detectedMode == MinimapMode.Overlay ? _config.OverlayRegion : _config.CornerRegion;
_detectedMode = detected;
Log.Information("MODE SWITCH: {Old} → {New}", oldMode, _detectedMode);
var newRegion = _detectedMode == MinimapMode.Overlay ? _config.OverlayRegion : _config.CornerRegion;
Log.Information("MODE SWITCH: {Old} → {New} | oldRegion=({OX},{OY},{OW}x{OH}) newRegion=({NX},{NY},{NW}x{NH})",
oldMode, _detectedMode,
oldRegion.X, oldRegion.Y, oldRegion.Width, oldRegion.Height,
newRegion.X, newRegion.Y, newRegion.Width, newRegion.Height);
ResetAdaptation();
ModeChanged?.Invoke(_detectedMode);
}
@ -56,7 +61,7 @@ public class MinimapCapture : IFrameConsumer, IDisposable
var frame = ProcessBgr(bgr);
if (frame == null) return;
Log.Debug("Process: mode={Mode} cropSize={W}x{H} classifiedSize={CW}x{CH} wallSize={WW}x{WH}",
Log.Information("Process: mode={Mode} cropSize={W}x{H} classifiedSize={CW}x{CH} wallSize={WW}x{WH}",
_detectedMode, bgr.Width, bgr.Height,
frame.ClassifiedMat.Width, frame.ClassifiedMat.Height,
frame.WallMask.Width, frame.WallMask.Height);

View file

@ -85,8 +85,8 @@ public class WorldMap : IDisposable
StitchWithConfidence(classifiedMat, _position, boosted: true, mode: mode);
if (_consecutiveMatchFails >= 30)
{
Log.Information("Re-bootstrap: stitching at current position after {Fails} match failures ({Ms:F1}ms)",
_consecutiveMatchFails, sw.Elapsed.TotalMilliseconds);
Log.Information("Re-bootstrap: mode={Mode} pos=({X:F1},{Y:F1}) frameSize={FS} walls={W} stitch={Ms:F1}ms",
mode, _position.X, _position.Y, classifiedMat.Width, wallCountAfter, sw.Elapsed.TotalMilliseconds);
_consecutiveMatchFails = 0;
}
else
@ -114,13 +114,16 @@ public class WorldMap : IDisposable
_consecutiveMatchFails = 0;
LastMatchSucceeded = true;
var prevPos = _position;
_position = matched;
var stitchStart = sw.Elapsed.TotalMilliseconds;
StitchWithConfidence(classifiedMat, _position, boosted: false, mode: mode);
var stitchMs = sw.Elapsed.TotalMilliseconds - stitchStart;
Log.Information("MatchAndStitch: dedup={Dedup:F1}ms match={Match:F1}ms stitch={Stitch:F1}ms total={Total:F1}ms",
dedupMs, matchMs, stitchMs, sw.Elapsed.TotalMilliseconds);
var posDx = _position.X - prevPos.X;
var posDy = _position.Y - prevPos.Y;
Log.Information("MatchAndStitch: mode={Mode} pos=({X:F1},{Y:F1}) moved=({Dx:F1},{Dy:F1}) dedup={Dedup:F1}ms match={Match:F1}ms stitch={Stitch:F1}ms total={Total:F1}ms",
mode, _position.X, _position.Y, posDx, posDy, dedupMs, matchMs, stitchMs, sw.Elapsed.TotalMilliseconds);
return _position;
}
@ -525,19 +528,53 @@ public class WorldMap : IDisposable
}
/// <summary>
/// Mode switch: clear frame dedup cache (frame sizes differ between modes)
/// but keep template matching active — no blind bootstrap needed since scales match.
/// Mode switch: halve confidence around current position so old mode's weak walls
/// decay quickly while strong walls provide matching reference for the new mode.
/// No re-bootstrap stitch — let the first match find the correct position.
/// </summary>
public void Rebootstrap()
{
Log.Information("Rebootstrap: frameCount={N} pos=({X:F1},{Y:F1}) matchFails={Fails} prevWallMask={Size}",
_frameCount, _position.X, _position.Y, _consecutiveMatchFails,
_prevWallMask != null ? $"{_prevWallMask.Width}x{_prevWallMask.Height}" : "null");
// Halve confidence around current position — weak walls get demoted,
// strong walls survive to help the new mode's first match find position
var halfClear = 250; // slightly larger than largest frame half (200)
var cx = (int)Math.Round(_position.X);
var cy = (int)Math.Round(_position.Y);
var x0 = Math.Max(0, cx - halfClear);
var y0 = Math.Max(0, cy - halfClear);
var w = Math.Min(_config.CanvasSize, cx + halfClear) - x0;
var h = Math.Min(_config.CanvasSize, cy + halfClear) - y0;
if (w > 0 && h > 0)
{
var rect = new Rect(x0, y0, w, h);
var confThreshold = (short)_config.ConfidenceThreshold;
using var confRoi = new Mat(_confidence, rect);
using var canvasRoi = new Mat(_canvas, rect);
var demoted = 0;
for (var row = 0; row < h; row++)
for (var col = 0; col < w; col++)
{
var conf = confRoi.At<short>(row, col);
if (conf <= 0) continue;
conf = (short)(conf / 2);
confRoi.Set(row, col, conf);
if (conf < confThreshold && canvasRoi.At<byte>(row, col) == (byte)MapCell.Wall)
{
canvasRoi.Set(row, col, (byte)MapCell.Explored);
demoted++;
}
}
Log.Information("Rebootstrap: halved confidence in {W}x{H} area, demoted {Demoted} weak walls", w, h, demoted);
}
_prevWallMask?.Dispose();
_prevWallMask = null;
// Force one re-bootstrap stitch so the new mode seeds walls on the canvas.
// This triggers needsBootstrap=true (>= 30), skips dedup, stitches boosted.
_consecutiveMatchFails = 30;
// Don't force re-bootstrap — let the match find the correct position first
}
public void Dispose()