Commit 0a8d2415 authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: pose test rebased on the certified CuasRender chain (lean v2: MB + all-defined disparity)

Per Andrey: restore the pose test using the new (certified) data.

- Disparity: ONE source for all of RT - the plain DSI slice through
  CuasRender.conditionDisparityCuas (defined for ALL tiles, sky=infinity,
  negatives clamped). The use_lma_dsi gate removed from the pose test (the
  LMA slice is NaN over the sky and silently shrank the usable set).
- leanMeasure/leanFitScene: MB compensation (lean v2) - the same certified
  machinery as CuasRender: setInterTasksMotionBlur two task sets + the
  erase-first interCorrTDMotionBlur double convert (undefined tiles NaN for
  the consolidation), gated by imp.mb_en, vectors from the existing per-scene
  getMotionBlur block (previously computed but unused by lean).
- pose_stored branch gets the same MB treatment.

Expected in the next lean run (LMA, 150-cluster selection, mb_en ON):
az/tilt wobble (v*tau, 0.5 px rotating) collapses toward the MBEN oracle
(0.029/0.021 mrad), corr RMS toward ~0.08; roll bias = the remaining open
question (FPN-mask lead).

Verified: mvn -DskipTests clean package OK.
Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
parent e4e65e23
...@@ -257,6 +257,11 @@ public class CuasPoseRT { ...@@ -257,6 +257,11 @@ public class CuasPoseRT {
* @param img_out null or length-1 holder - filled with the imclt render of the * @param img_out null or length-1 holder - filled with the imclt render of the
* consolidated composite scene ([width*height], NaN outside task tiles); * consolidated composite scene ([width*height], NaN outside task tiles);
* requesting it adds an erased re-convert + an imclt pass (debug only) * requesting it adds an erased re-convert + an imclt pass (debug only)
* @param mb_vectors null (no motion-blur compensation) or [2][ntiles] blur vectors -
* the certified-chain MB: two task sets, double convert (positive SET +
* negative shifted SUBTRACT), erase-first so undefined tiles stay NaN
* @param mb_tau bolometer time constant, s (imp.mb_tau)
* @param mb_max_gain max MB scale before offset stretching (imp.mb_max_gain_inter)
* @return [3][num_pix][] {centers pXpYD, vector_XYS {dx,dy,strength}, eigen * @return [3][num_pix][] {centers pXpYD, vector_XYS {dx,dy,strength}, eigen
* {e0x,e0y,l0,l1}} - the coord_motion contract of interCorrPair - or null * {e0x,e0y,l0,l1}} - the coord_motion contract of interCorrPair - or null
*/ */
...@@ -271,6 +276,9 @@ public class CuasPoseRT { ...@@ -271,6 +276,9 @@ public class CuasPoseRT {
final double [] scene_xyz, final double [] scene_xyz,
final double [] scene_atr, final double [] scene_atr,
final int margin, final int margin,
final double [][] mb_vectors, // By Claude on 07/05/2026
final double mb_tau, // By Claude on 07/05/2026
final double mb_max_gain, // By Claude on 07/05/2026
final double [][][] corr_pd_out, // By Claude on 07/04/2026 final double [][][] corr_pd_out, // By Claude on 07/04/2026
final float [][] img_out, // By Claude on 07/04/2026 final float [][] img_out, // By Claude on 07/04/2026
final int debugLevel) { final int debugLevel) {
...@@ -280,6 +288,47 @@ public class CuasPoseRT { ...@@ -280,6 +288,47 @@ public class CuasPoseRT {
final double [][] scene_pXpYD = OpticalFlow.transformToScenePxPyD( final double [][] scene_pXpYD = OpticalFlow.transformToScenePxPyD(
null, center_disparity, scene_xyz, scene_atr, scene, center_CLT); null, center_disparity, scene_xyz, scene_atr, scene, center_CLT);
final double disparity_corr = clt_parameters.imp.disparity_corr + center_CLT.getDispInfinityRef(); final double disparity_corr = clt_parameters.imp.disparity_corr + center_CLT.getDispInfinityRef();
if (mb_vectors != null) {
// Motion-blur compensation (lean v2, the certified CuasRender chain): two task
// sets, double convert (positive SET + negative shifted SUBTRACT), erase-first
// so undefined tiles reach downstream (consolidation, renders) as NaN.
// By Claude on 07/05/2026.
final TpTask [][] tp_tasks2 = GpuQuad.setInterTasksMotionBlur(
scene.getNumSensors(),
scene.getGeometryCorrection().getSensorWH()[0],
false, // GPU calculates port coordinates
scene_pXpYD,
selection, // only the calibrated tile selection
mb_tau,
mb_max_gain,
mb_vectors,
scene.getGeometryCorrection(),
disparity_corr,
margin,
null, // valid_tiles
ImageDtt.THREADS_MAX);
if ((tp_tasks2 == null) || (tp_tasks2[0] == null) || (tp_tasks2[0].length == 0)) {
System.out.println("leanMeasure(): no MB tasks for scene "+scene.getImageName());
return null;
}
image_dtt.interCorrTDMotionBlur(
clt_parameters.img_dtt,
1, // erase_clt_first: NaN outside the task set
tp_tasks2,
null, // fcorr_td - not used with mask=0
clt_parameters.gpu_sigma_r,
clt_parameters.gpu_sigma_b,
clt_parameters.gpu_sigma_g,
clt_parameters.gpu_sigma_m,
scene.isMonochrome() ? 1.0 : clt_parameters.gpu_sigma_rb_corr,
clt_parameters.getGpuCorrSigma(scene.isMonochrome()),
clt_parameters.getGpuCorrLoGSigma(scene.isMonochrome()),
clt_parameters.corr_red,
clt_parameters.corr_blue,
0, // sensor_mask_inter = 0: convert only
ImageDtt.THREADS_MAX,
debugLevel);
} else {
final TpTask [] tp_tasks = GpuQuad.setInterTasks( final TpTask [] tp_tasks = GpuQuad.setInterTasks(
scene.getNumSensors(), scene.getNumSensors(),
scene.getGeometryCorrection().getSensorWH()[0], scene.getGeometryCorrection().getSensorWH()[0],
...@@ -319,6 +368,7 @@ public class CuasPoseRT { ...@@ -319,6 +368,7 @@ public class CuasPoseRT {
if (img_out != null) { if (img_out != null) {
gpuQuad.execConvertDirect(false, null, 1); gpuQuad.execConvertDirect(false, null, 1);
} }
}
// 3. the CPU consolidation bridge (future clt_average_sensors kernel). // 3. the CPU consolidation bridge (future clt_average_sensors kernel).
// The TRUE weighted average is fed to the correlator (NOT scaled to the oracle's // The TRUE weighted average is fed to the correlator (NOT scaled to the oracle's
// 16-pair sum): the sum-scaling experiment (LEAN-07) made peaks WIDER (sqrt_l0 // 16-pair sum): the sum-scaling experiment (LEAN-07) made peaks WIDER (sqrt_l0
...@@ -413,6 +463,9 @@ public class CuasPoseRT { ...@@ -413,6 +463,9 @@ public class CuasPoseRT {
final boolean [] param_select, final boolean [] param_select,
final double [] reg_weights, final double [] reg_weights,
final int margin, final int margin,
final double [][] mb_vectors, // null - no MB compensation // By Claude on 07/05/2026
final double mb_tau, // By Claude on 07/05/2026
final double mb_max_gain, // By Claude on 07/05/2026
final double [] lma_rms, // out final double [] lma_rms, // out
final double [][][] coord_motion_rslt, // out [3][][] final double [][][] coord_motion_rslt, // out [3][][]
final double [][][] corr_pd_out, // null or len-1: last-cycle PD correlations // By Claude on 07/04/2026 final double [][][] corr_pd_out, // null or len-1: last-cycle PD correlations // By Claude on 07/04/2026
...@@ -428,7 +481,8 @@ public class CuasPoseRT { ...@@ -428,7 +481,8 @@ public class CuasPoseRT {
cm = leanMeasure( cm = leanMeasure(
clt_parameters, image_dtt, center_CLT, scene, clt_parameters, image_dtt, center_CLT, scene,
center_disparity, pXpYD_center, selection, center_disparity, pXpYD_center, selection,
scene_xyzatr0[0], scene_xyzatr0[1], margin, corr_pd_out, img_out, debugLevel); scene_xyzatr0[0], scene_xyzatr0[1], margin,
mb_vectors, mb_tau, mb_max_gain, corr_pd_out, img_out, debugLevel);
if (cm == null) return null; if (cm == null) return null;
final double [][] eigen_masked = clt_parameters.imp.eig_xy_lma ? null : cm[2]; final double [][] eigen_masked = clt_parameters.imp.eig_xy_lma ? null : cm[2];
intersceneLma.prepareLMA( intersceneLma.prepareLMA(
...@@ -510,7 +564,6 @@ public class CuasPoseRT { ...@@ -510,7 +564,6 @@ public class CuasPoseRT {
final QuadCLT [] quadCLTs, final QuadCLT [] quadCLTs,
final int debugLevel) { final int debugLevel) {
final double min_str = clt_parameters.curt.pose_str; // e.g. 1.0 final double min_str = clt_parameters.curt.pose_str; // e.g. 1.0
final boolean use_lma_dsi = clt_parameters.imp.use_lma_dsi;
final int margin = clt_parameters.imp.margin; final int margin = clt_parameters.imp.margin;
final double mb_tau = clt_parameters.imp.mb_tau; final double mb_tau = clt_parameters.imp.mb_tau;
final double mb_max_gain = clt_parameters.imp.mb_max_gain_inter; final double mb_max_gain = clt_parameters.imp.mb_max_gain_inter;
...@@ -540,10 +593,13 @@ public class CuasPoseRT { ...@@ -540,10 +593,13 @@ public class CuasPoseRT {
// ---- Reference prep (ONCE) - the persistent virtual-center TD reference ---- // ---- Reference prep (ONCE) - the persistent virtual-center TD reference ----
final boolean is_aux = center_CLT.isAux(); final boolean is_aux = center_CLT.isAux();
final double [][] center_dsi = center_CLT.dsi; final double [][] center_dsi = center_CLT.dsi;
final double [] disparity = center_dsi[is_aux ? TwoQuadCLT.DSI_DISPARITY_AUX : TwoQuadCLT.DSI_DISPARITY_MAIN];
final double [] disparity_lma = center_dsi[is_aux ? TwoQuadCLT.DSI_DISPARITY_AUX_LMA : TwoQuadCLT.DSI_DISPARITY_MAIN_LMA];
final double [] strength = center_dsi[is_aux ? TwoQuadCLT.DSI_STRENGTH_AUX : TwoQuadCLT.DSI_STRENGTH_MAIN]; final double [] strength = center_dsi[is_aux ? TwoQuadCLT.DSI_STRENGTH_AUX : TwoQuadCLT.DSI_STRENGTH_MAIN];
final double [] center_disparity = (use_lma_dsi && (disparity_lma != null)) ? disparity_lma : disparity; // ONE disparity source for all of RT (Andrey ruling, certified in the render test):
// the PLAIN slice conditioned to be defined for ALL tiles (sky = infinity/0,
// negatives clamped). NOT gated by use_lma_dsi (the LMA slice is NaN over the sky).
// By Claude on 07/05/2026.
final double [] center_disparity = CuasRender.conditionDisparityCuas(
center_dsi[is_aux ? TwoQuadCLT.DSI_DISPARITY_AUX : TwoQuadCLT.DSI_DISPARITY_MAIN]);
final boolean [] reliable_ref = new boolean [strength.length]; final boolean [] reliable_ref = new boolean [strength.length];
int num_reliable = 0; int num_reliable = 0;
for (int i = 0; i < strength.length; i++) { for (int i = 0; i < strength.length; i++) {
...@@ -665,9 +721,10 @@ public class CuasPoseRT { ...@@ -665,9 +721,10 @@ public class CuasPoseRT {
clt_parameters.getScaleStrength(center_CLT.isAux()), clt_parameters.getScaleStrength(center_CLT.isAux()),
center_CLT.getGPU()) : null; center_CLT.getGPU()) : null;
if (clt_parameters.curt.pose_lean) { if (clt_parameters.curt.pose_lean) {
System.out.println("CuasPoseRT.testPoseSequence(): LEAN measurement engine (phase B): "+ System.out.println("CuasPoseRT.testPoseSequence(): LEAN measurement engine (phase B v2, "+
"TD-average(16) x virtual-center single conj-multiply. NOTE: no MB compensation "+ "certified CuasRender chain): TD-average(16) x virtual-center single conj-multiply, "+
"in lean v1 - compare against the NOMB baseline"); "all-defined conditioned disparity, MB compensation "+
(clt_parameters.imp.mb_en ? "ON (compare vs MBEN/stored)" : "OFF (compare vs NOMB)"));
} }
if (clt_parameters.curt.pose_stored) { // By Claude on 07/04/2026 if (clt_parameters.curt.pose_stored) { // By Claude on 07/04/2026
System.out.println("CuasPoseRT.testPoseSequence(): pose_stored ON (DEBUG) - STORED poses, "+ System.out.println("CuasPoseRT.testPoseSequence(): pose_stored ON (DEBUG) - STORED poses, "+
...@@ -819,6 +876,7 @@ public class CuasPoseRT { ...@@ -819,6 +876,7 @@ public class CuasPoseRT {
clt_parameters, image_dtt_lean, center_CLT, quadCLTs[nscene], clt_parameters, image_dtt_lean, center_CLT, quadCLTs[nscene],
center_disparity, pXpYD_center, reliable_ref, center_disparity, pXpYD_center, reliable_ref,
use_pose[0], use_pose[1], margin, use_pose[0], use_pose[1], margin,
mb_vectors_scene, mb_tau, mb_max_gain, // MB per imp.mb_en // By Claude on 07/05/2026
corr_pd_holder, img_holder, debugLevel - 2); corr_pd_holder, img_holder, debugLevel - 2);
if (cm != null) { if (cm != null) {
pose = new double [][] {use_pose[0].clone(), use_pose[1].clone()}; pose = new double [][] {use_pose[0].clone(), use_pose[1].clone()};
...@@ -851,6 +909,9 @@ public class CuasPoseRT { ...@@ -851,6 +909,9 @@ public class CuasPoseRT {
param_select, // boolean [] param_select, param_select, // boolean [] param_select,
reg_weights, // double [] reg_weights, reg_weights, // double [] reg_weights,
margin, // int margin, margin, // int margin,
mb_vectors_scene, // double [][] mb_vectors (MB per imp.mb_en - lean v2) // By Claude on 07/05/2026
mb_tau, // double mb_tau, // By Claude on 07/05/2026
mb_max_gain, // double mb_max_gain, // By Claude on 07/05/2026
lma_rms, // double [] lma_rms (out), lma_rms, // double [] lma_rms (out),
coord_motion_rslt, // double [][][] coord_motion_rslt (out), coord_motion_rslt, // double [][][] coord_motion_rslt (out),
corr_pd_holder, // double [][][] corr_pd_out (last-cycle PD correlations) // By Claude on 07/04/2026 corr_pd_holder, // double [][][] corr_pd_out (last-cycle PD correlations) // By Claude on 07/04/2026
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment