Lower synthetic visual marker candidates
This commit is contained in:
parent
fdba81cac1
commit
fa2c8ed63b
8 changed files with 139 additions and 5 deletions
|
|
@ -426,12 +426,13 @@ Let Fensalir fuse Mimir observations into field claims:
|
|||
|
||||
Acceptance:
|
||||
|
||||
- one synthetic multi-camera marker creates a stable world-space claim;
|
||||
- implemented synthetic multi-camera marker proof: Mimir lowers a deterministic
|
||||
camera marker candidate with calibration/marker identity and a world-space
|
||||
confidence envelope, and Fensalir plans it as a `DebugOverlay` FieldEvidence
|
||||
packet;
|
||||
- implemented synthetic audio source proof: Mimir lowers an SRP/PHAT-style
|
||||
source candidate with calibration/source identity and a world-space confidence
|
||||
envelope, and Fensalir plans it as a `DebugOverlay` FieldEvidence packet;
|
||||
- next remaining acceptance item: one synthetic multi-camera marker creates a
|
||||
stable world-space claim;
|
||||
- claims can be inspected by source observation and calibration id.
|
||||
|
||||
### Phase 6: Program Output Receipts
|
||||
|
|
|
|||
|
|
@ -274,6 +274,9 @@ a named invariant that the native runtime cannot protect yet.
|
|||
Phase 5 synthetic audio-source candidate: an SRP/PHAT-style localization
|
||||
result is lowered with calibration/source identity and a world-space
|
||||
confidence envelope, then planned as a FieldEvidence `DebugOverlay` packet.
|
||||
It also proves a synthetic multi-camera marker candidate using the same
|
||||
FieldEvidence authority: deterministic marker features plan as
|
||||
`DebugOverlay` packets while ambiguous raw camera features still defer.
|
||||
- Fensalir now owns the first in-process D3D12 field resource resolver cut:
|
||||
shared structured/curve buffer resources import/alias GPU-resident handles,
|
||||
and Fensalir-owned resources allocate GPU slots only when Fensalir is the
|
||||
|
|
|
|||
|
|
@ -467,7 +467,10 @@ Mimir lowers an SRP/PHAT-style localized source with calibration/source
|
|||
identity and a world-space confidence envelope, and Fensalir plans it as a
|
||||
FieldEvidence `DebugOverlay` packet. Live room geometry must still come from an
|
||||
explicit measured coordinate frame, not inferred from the recent two-distance
|
||||
monitor notes.
|
||||
monitor notes. Phase 5's synthetic marker proof now exists too: Mimir lowers a
|
||||
deterministic multi-camera marker candidate with calibration/marker identity and
|
||||
world-space support, and Fensalir plans it as `DebugOverlay` evidence while
|
||||
ambiguous raw camera features still defer.
|
||||
|
||||
The current teardown/migration map is
|
||||
`docs/fensalir-rendering-rebuild-migration.md`, paired with Fensalir's
|
||||
|
|
|
|||
|
|
@ -2192,6 +2192,20 @@ static int RunPerfectMachineProfileSmoke()
|
|||
1_000_000_000L)
|
||||
]);
|
||||
var acousticSourcePlan = AquariumFieldLoweringPlanner.Plan(acousticSourceFrame);
|
||||
var visualMarkerFrame = lowerer.BuildVisualMarkerCandidateFrame(
|
||||
[
|
||||
new MimirVisualMarkerFieldCandidate(
|
||||
"marker-a",
|
||||
"synthetic-camera-rig-calibration",
|
||||
"synthetic-marker-a",
|
||||
"mimir-multi-camera-marker",
|
||||
["kiyo-pro-rgb:1", "leap-stereo-ir:1"],
|
||||
new Vector3(0.0f, 1.2f, 2.5f),
|
||||
0.05,
|
||||
0.88,
|
||||
1_000_000_000L)
|
||||
]);
|
||||
var visualMarkerPlan = AquariumFieldLoweringPlanner.Plan(visualMarkerFrame);
|
||||
var authority = new MimirAuthorityPolicyEvaluator().Evaluate(new MimirAuthorityEvaluationInput(
|
||||
"raven-scarlett-witness",
|
||||
new HashSet<string>(["known-node", "matching-codebook", "clock-fit-confidence", "response-profile"], StringComparer.Ordinal),
|
||||
|
|
@ -2218,6 +2232,8 @@ static int RunPerfectMachineProfileSmoke()
|
|||
$"perfect-machine-fensalir cameraResources={cameraFieldFrame.Resources.Count} cameraClaims={cameraFieldFrame.Claims.Count} cameraPlanned={cameraPlan.Packets.Count} cameraDeferred={cameraPlan.DeferredRequests.Count} acousticClaims={acousticFieldEvidence.Claims.Count} acousticPlanned={acousticPlan.Packets.Count} acousticDeferred={acousticPlan.DeferredRequests.Count}");
|
||||
Console.WriteLine(
|
||||
$"perfect-machine-localization candidates={localizationGrid.Count} best=({localization?.PositionMeters.X ?? float.NaN:0.000},{localization?.PositionMeters.Y ?? float.NaN:0.000},{localization?.PositionMeters.Z ?? float.NaN:0.000}) score={localization?.Score ?? 0.0:0.000} sourceClaims={acousticSourceFrame.Claims.Count} sourcePlanned={acousticSourcePlan.Packets.Count} sourceDeferred={acousticSourcePlan.DeferredRequests.Count}");
|
||||
Console.WriteLine(
|
||||
$"perfect-machine-visual-marker claims={visualMarkerFrame.Claims.Count} planned={visualMarkerPlan.Packets.Count} deferred={visualMarkerPlan.DeferredRequests.Count}");
|
||||
Console.WriteLine(
|
||||
$"perfect-machine-authority appliesTo=raven-scarlett-witness decision={authority.Decision} rule={authority.RuleId}");
|
||||
Console.WriteLine(
|
||||
|
|
@ -2257,6 +2273,11 @@ static int RunPerfectMachineProfileSmoke()
|
|||
acousticSourcePlan.DeferredRequests.Count == 0 &&
|
||||
acousticSourceFrame.Claims[0].ClaimKey.Contains("synthetic-tdoa-calibration", StringComparison.Ordinal) &&
|
||||
acousticSourceFrame.Claims[0].ClaimKey.Contains("synthetic-audio-source", StringComparison.Ordinal) &&
|
||||
visualMarkerFrame.Claims.Count == 1 &&
|
||||
visualMarkerPlan.Packets.Count == 1 &&
|
||||
visualMarkerPlan.DeferredRequests.Count == 0 &&
|
||||
visualMarkerFrame.Claims[0].ClaimKey.Contains("synthetic-camera-rig-calibration", StringComparison.Ordinal) &&
|
||||
visualMarkerFrame.Claims[0].ClaimKey.Contains("synthetic-marker-a", StringComparison.Ordinal) &&
|
||||
localization is { Score: > 0.90 } &&
|
||||
authority.Decision == MimirAuthorityDecision.TrustedEvidence &&
|
||||
transport.Transport?.Id == MimirNetworkTransportConfigurations.CultMeshTimingState.Id &&
|
||||
|
|
|
|||
|
|
@ -150,6 +150,17 @@ public sealed record MimirAcousticSourceFieldCandidate(
|
|||
double Confidence,
|
||||
long ObservedTimeNs);
|
||||
|
||||
public sealed record MimirVisualMarkerFieldCandidate(
|
||||
string CandidateKey,
|
||||
string CalibrationId,
|
||||
string MarkerId,
|
||||
string ProducerKey,
|
||||
IReadOnlyList<string> SourceObservationKeys,
|
||||
System.Numerics.Vector3 PositionMeters,
|
||||
double RadiusMeters,
|
||||
double Confidence,
|
||||
long ObservedTimeNs);
|
||||
|
||||
public readonly record struct MimirSurfaceAxes(
|
||||
string X,
|
||||
string Y,
|
||||
|
|
|
|||
|
|
@ -147,6 +147,39 @@ public sealed class MimirFensalirFieldLowering(MimirFensalirLoweringOptions? opt
|
|||
};
|
||||
}
|
||||
|
||||
public AquariumFieldEvidenceFrame BuildVisualMarkerCandidateFrame(
|
||||
IEnumerable<MimirVisualMarkerFieldCandidate> markerCandidates)
|
||||
{
|
||||
var domains = new List<AquariumFieldDomain>();
|
||||
var claims = new List<AquariumFieldClaim>();
|
||||
var candidates = new List<AquariumFieldCandidate>();
|
||||
var seenDomains = new HashSet<string>(StringComparer.Ordinal);
|
||||
|
||||
foreach (var markerCandidate in markerCandidates)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(markerCandidate.CandidateKey))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var domain = DomainForVisualMarkerCandidate(markerCandidate);
|
||||
AddDomain(domains, seenDomains, domain);
|
||||
|
||||
var claim = ClaimForVisualMarkerCandidate(markerCandidate, domain.DomainKey);
|
||||
claims.Add(claim);
|
||||
candidates.Add(CandidateForClaim(claim, AquariumFieldGuide.Valid(claim.Confidence)));
|
||||
}
|
||||
|
||||
return new AquariumFieldEvidenceFrame
|
||||
{
|
||||
Domains = domains,
|
||||
Claims = claims,
|
||||
Candidates = candidates,
|
||||
AccumulationWindowSeconds = (float)options.AccumulationWindowSeconds,
|
||||
PresentationDelaySeconds = (float)options.PresentationDelaySeconds
|
||||
};
|
||||
}
|
||||
|
||||
private static void AddDomain(
|
||||
ICollection<AquariumFieldDomain> domains,
|
||||
ISet<string> seenDomains,
|
||||
|
|
@ -304,6 +337,23 @@ public sealed class MimirFensalirFieldLowering(MimirFensalirLoweringOptions? opt
|
|||
"Mimir.Runtime");
|
||||
}
|
||||
|
||||
private static AquariumFieldDomain DomainForVisualMarkerCandidate(MimirVisualMarkerFieldCandidate candidate)
|
||||
{
|
||||
var radius = Math.Max(0.001f, (float)candidate.RadiusMeters);
|
||||
var center = candidate.PositionMeters;
|
||||
var boundsRadius = new Vector3(radius);
|
||||
return new AquariumFieldDomain(
|
||||
DomainKeyForVisualMarkerCandidate(candidate),
|
||||
"",
|
||||
AquariumFieldDomainKind.CameraSensor,
|
||||
Matrix4x4.Identity,
|
||||
Matrix4x4.Identity,
|
||||
center - boundsRadius,
|
||||
center + boundsRadius,
|
||||
Vector3.Zero,
|
||||
"Mimir.Runtime");
|
||||
}
|
||||
|
||||
private static AquariumFieldDomain DomainForSurfaceIntent(MimirSurfaceIntent intent) =>
|
||||
new(
|
||||
DomainKeyForSurfaceIntent(intent.IntentKey),
|
||||
|
|
@ -387,6 +437,31 @@ public sealed class MimirFensalirFieldLowering(MimirFensalirLoweringOptions? opt
|
|||
Confidence: confidence);
|
||||
}
|
||||
|
||||
private AquariumFieldClaim ClaimForVisualMarkerCandidate(
|
||||
MimirVisualMarkerFieldCandidate markerCandidate,
|
||||
string domainKey)
|
||||
{
|
||||
var confidence = Clamp01((float)markerCandidate.Confidence);
|
||||
var proposal = new AquariumFieldProposalPolicy(
|
||||
AquariumFieldProposalKind.DeterministicStructural,
|
||||
SourcePdf: 1.0f,
|
||||
TargetContribution: confidence,
|
||||
RepresentedCandidateCount: Math.Max(1, markerCandidate.SourceObservationKeys.Count),
|
||||
Seed: StableSeed(markerCandidate.CandidateKey));
|
||||
|
||||
return new AquariumFieldClaim(
|
||||
ClaimKey: $"visual-marker:{markerCandidate.CalibrationId}:{markerCandidate.MarkerId}:{markerCandidate.CandidateKey}",
|
||||
DomainKey: domainKey,
|
||||
ProducerKey: markerCandidate.ProducerKey,
|
||||
Layer: AquariumFieldLayer.Form,
|
||||
Encoding: AquariumFieldEncoding.Feature,
|
||||
Support: SupportForVisualMarkerCandidate(markerCandidate),
|
||||
Proposal: proposal,
|
||||
PayloadHandle: markerCandidate.CalibrationId,
|
||||
ObservedTimeNs: markerCandidate.ObservedTimeNs,
|
||||
Confidence: confidence);
|
||||
}
|
||||
|
||||
private AquariumFieldClaim ClaimForSurfaceIntent(
|
||||
MimirSurfaceIntent intent,
|
||||
string domainKey,
|
||||
|
|
@ -515,6 +590,19 @@ public sealed class MimirFensalirFieldLowering(MimirFensalirLoweringOptions? opt
|
|||
TemporalUncertainty: 0.0f);
|
||||
}
|
||||
|
||||
private AquariumFieldSupport SupportForVisualMarkerCandidate(MimirVisualMarkerFieldCandidate markerCandidate)
|
||||
{
|
||||
var radius = Math.Max(options.DefaultSupportRadius, (float)markerCandidate.RadiusMeters);
|
||||
return new AquariumFieldSupport(
|
||||
Center: markerCandidate.PositionMeters,
|
||||
Radius: new Vector3(radius),
|
||||
LocalFrame: Matrix4x4.Identity,
|
||||
ConservativeRadius: radius,
|
||||
ProjectedError: radius,
|
||||
Curvature: 0.0f,
|
||||
TemporalUncertainty: 0.0f);
|
||||
}
|
||||
|
||||
private AquariumFieldSupport SupportForSurfaceIntent(MimirSurfaceIntent intent)
|
||||
{
|
||||
var age = Math.Max(0.0f, (float)intent.SupportPolicy.MaximumAgeSeconds);
|
||||
|
|
@ -681,6 +769,9 @@ public sealed class MimirFensalirFieldLowering(MimirFensalirLoweringOptions? opt
|
|||
private static string DomainKeyForAcousticSourceCandidate(MimirAcousticSourceFieldCandidate candidate) =>
|
||||
$"mimir:acoustic-source:{candidate.CalibrationId}:{candidate.SourceId}:{candidate.CandidateKey}";
|
||||
|
||||
private static string DomainKeyForVisualMarkerCandidate(MimirVisualMarkerFieldCandidate candidate) =>
|
||||
$"mimir:visual-marker:{candidate.CalibrationId}:{candidate.MarkerId}:{candidate.CandidateKey}";
|
||||
|
||||
private static string DomainKeyForSurfaceIntent(string intentKey) => $"mimir:intent:{intentKey}";
|
||||
|
||||
private static float Clamp01(float value) => Math.Clamp(value, 0.0f, 1.0f);
|
||||
|
|
|
|||
|
|
@ -206,3 +206,4 @@
|
|||
{"ts": "2026-05-28T08:20:48+01:00", "type": "verification", "status": "blocked", "note": "ASIO monitor split proof 20260528-081813 added --play-output-channel and captured output 0/output 1 separately. Loopback channels confirmed distinct ASIO output buffers, but physical mic delays were nearly identical across outputs (shotgun delta about 20.885 us; cardioid delta about 24.789 us), inconsistent with declared left/right monitor geometry. Downstream monitor routing/isolation must be verified before learning left/right acoustic paths."}
|
||||
{"ts": "2026-05-28T12:06:53+01:00", "type": "implementation", "status": "ok", "note": "Fensalir now selects FieldEvidence AudioPath Phase/Confidence claims as DebugOverlay backend packets, so Mimir acoustic calibration constraints are planned rather than deferred. Mimir profile smoke now reports acousticPlanned=1 acousticDeferred=0; acoustic source volumes remain Phase 5 fusion work."}
|
||||
{"ts": "2026-05-28T12:10:23+01:00", "type": "implementation", "status": "ok", "note": "Phase 5 synthetic audio-source proof added: Mimir lowers an SRP/PHAT-style localized source candidate with calibration/source identity and a world-space confidence envelope; Fensalir plans it as a FieldEvidence DebugOverlay packet. Live room geometry still needs an explicit coordinate frame before physical candidates become runtime truth."}
|
||||
{"ts": "2026-05-28T12:13:46+01:00", "type": "implementation", "status": "ok", "note": "Phase 5 synthetic marker proof added: deterministic multi-camera marker candidates lower with calibration/marker identity and world-space support, and Fensalir plans them as FieldEvidence DebugOverlay packets. Ambiguous raw camera feature claims still defer."}
|
||||
|
|
|
|||
|
|
@ -503,7 +503,10 @@ accepted_design:
|
|||
localization result with calibration/source identity and a world-space
|
||||
confidence envelope, and Fensalir plans it as a FieldEvidence DebugOverlay
|
||||
packet. Live room geometry still needs an explicit measured coordinate
|
||||
frame before those candidates become runtime truth.
|
||||
frame before those candidates become runtime truth. Phase 5's synthetic
|
||||
marker proof now lowers a deterministic multi-camera marker candidate with
|
||||
calibration/marker identity and world-space support, and Fensalir plans it
|
||||
as DebugOverlay evidence while ambiguous raw camera features still defer.
|
||||
- `config/perfect-machine.example.json` declares live owners, sensors,
|
||||
reservoir views, and runtime policy.
|
||||
- `src/Mimir.Runtime/Synchronization` now includes the Perfect Machine module
|
||||
|
|
|
|||
Loading…
Reference in a new issue