Commit 21fe0c02 authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: T2 - in-loop 16-bit feeder replaces the 9.7 GiB float preload

Real per-scene file I/O inside the measured loop (the honest RT test, and the
production shape: 4 reader threads = the 4xSATA-2 device groups of 4
consecutive sensors). New CuasSceneFeeder parses the single-strip 16-bit TIFF
layout ONCE from file #1 (strip@557, 656640 B, big-endian, telemetry row 0 -
verified constant over the whole segment and bit-exact vs the production
ImagejJp4Tiff reader), then preads raw strip bytes straight into the native
pinned u16 staging (PosixIo/libc - the kernel's read IS the pinned write,
half the pinned-write bytes of the float path). The GPU converts (byte-swap)
+ applies the borrowed per-scene Row/Col (prior scales snapshotted at
creation, exact double chain) + two-map conditions in ONE kernel
(condition_lwir_u16, native 84d7ab6) - bit-identical to the preload path by
the u16_cond case, so the Done-line byte-identity gate carries over.

Cold-read honesty: posix_fadvise(DONTNEED) after every file - reruns never
replay the page cache (the production RAM-based dual-port SATA feeder always
serves NEW frames). Cold bench: 4 threads 4.4/5.4/7.3 ms/scene p50/p95/max -
hidden under the ~12 ms DP entry via the D5 overlap, which now awaits the
in-flight read (kicked one scene ahead at collect-safe points, keeping the
one-scene staging slack contract).

Arrival moderation (Andrey 07/18): in paced (pose_pace) mode the feeder is
armed with the same 60 Hz epoch grid - the DATA, not just the loop, arrives
at 60 Hz; the overlap then fires only when the next read already landed
(never parks inside the DP window), i.e. exactly when running behind.

New saved checkbox curt.pose_feed16 (default ON) selects the feeder; OFF =
the legacy float preload (A/B). CPU-oracle fallback (heap reads + the exact
preload float chain) covers cond_gpu OFF and any native failure. Stage0
42/42; mvn package PASS.
Co-authored-by: 's avatarClaude Fable 5 <claude-fable-5@anthropic.com>
parent a8ffb2f8
...@@ -578,6 +578,129 @@ public class CuasConditioning { ...@@ -578,6 +578,129 @@ public class CuasConditioning {
// 3-B rung B0: one-shot conditioning-stage split (see above). By Claude on 07/16/2026. // 3-B rung B0: one-shot conditioning-stage split (see above). By Claude on 07/16/2026.
private static boolean b0_condition_reported = false; private static boolean b0_condition_reported = false;
// ---- T2 16-bit feeder (07/18/2026): in-loop reads + GPU u16 conditioning.
// The pinned staging already holds the scene's raw strip bytes (the feeder
// pread them there); conditioning = enqueue per-sensor async H2D + the
// per-scene Row/Col block + ONE condition_lwir_u16 launch, all on the copy
// stream. Bit-identical to the preload float path by the u16_cond case.
// By Claude on 07/18/2026, from Andrey's T2 design. ----
private static boolean feeder_path_reported = false; // once-per-program "path active" note
/** Upload the resident linear calibration maps for the feeder harness (the
* preload twin). Returns false when the CPU oracle must be used. */
public static boolean prepareFeederConditioning(
final QuadCLT scene,
final CuasSceneFeeder feeder,
final Config cfg) {
if ((scene == null) || (feeder == null) || (cfg == null)) return false;
return prepareGpuConditioning(
scene.getGPUQuad(), feeder.getNumSensors(), feeder.getNumPixels(),
scene.getLwirScales(), scene.getLwirOffsets(), scene.getLwirScales2(), scene.getFPN(), cfg);
}
/**
* Serial (non-overlap) feeder conditioning of one scene into the ACTIVE image
* set: await the staged read, then u16 H2D + Row/Col + condition in one async
* pass. CPU fallback (heap mode / native failure) rebuilds the exact preload
* floats and takes the legacy float upload. False = input failed (caller coasts).
*/
public static boolean conditionFeederSceneToGpu(
final QuadCLT scene,
final CuasSceneFeeder feeder,
final int nscene,
final float [][] cpu_raw, // scratch [sensor][pixels] for the CPU fallback
final float [][] cpu_scratch, // scratch for the CPU-conditioned output
final Config cfg) {
if ((scene == null) || (feeder == null)) return false;
final Config use_cfg = (cfg != null) ? cfg : new Config();
if (use_cfg.rowcol_enable) {
throw new IllegalArgumentException("Feeder Row/Col is applied in-kernel, not by the timed Config");
}
if (use_cfg.zero_dc && Double.isNaN(use_cfg.dc_level)) {
throw new IllegalArgumentException("Feeder conditioning requires a fixed sequence DC level");
}
if (!feeder.awaitStaged(nscene)) return false;
final GpuQuad gpuQuad = scene.getGPUQuad();
if (feeder.isPinned() && prepareGpuConditioning(
gpuQuad, feeder.getNumSensors(), feeder.getNumPixels(),
scene.getLwirScales(), scene.getLwirOffsets(), scene.getLwirScales2(), scene.getFPN(), use_cfg)) {
if (enqueueFeederScene(scene, feeder, nscene, gpuQuad)) {
if (!feeder_path_reported) {
feeder_path_reported = true;
System.out.println("CuasConditioning: 16-bit feeder path active (in-loop read -> pinned u16 H2D"+
" -> one-pass GPU convert+"+(feeder.isRowColEnabled() ? "Row/Col+" : "")+"condition)");
}
return true;
}
System.out.println("CuasConditioning: u16 conditioning failed for scene "+nscene+
" - CPU fallback for this scene");
}
// CPU oracle: exact preload floats -> linear conditioning -> legacy upload
if ((cpu_raw == null) || (feeder.readSceneFloats(nscene, cpu_raw) == null)) return false;
conditionLinearToFloat(cpu_raw, cpu_scratch, scene.getLwirScales(), scene.getLwirOffsets(),
scene.getLwirScales2(), scene.getFPN(), use_cfg);
scene.saveQuadClt();
scene.setHasNewImageData(false);
gpuQuad.setBayerImages(cpu_scratch, true);
return true;
}
/**
* D5 overlap variant: condition one FEEDER scene into ring set img_set while
* the previous scene's DP chain runs. The caller has already verified the
* staged read (never parks inside the DP window). GPU-only by construction.
*/
public static boolean conditionFeederSceneToGpuOverlap(
final QuadCLT scene,
final CuasSceneFeeder feeder,
final int nscene,
final Config cfg,
final int img_set,
final int restore_set) {
if ((scene == null) || (feeder == null) || !feeder.isPinned() || !feeder.isStaged(nscene)) return false;
final Config use_cfg = (cfg != null) ? cfg : new Config();
if (use_cfg.rowcol_enable || (use_cfg.zero_dc && Double.isNaN(use_cfg.dc_level))) return false;
final GpuQuad gpuQuad = scene.getGPUQuad();
if (!prepareGpuConditioning(
gpuQuad, feeder.getNumSensors(), feeder.getNumPixels(),
scene.getLwirScales(), scene.getLwirOffsets(), scene.getLwirScales2(), scene.getFPN(), use_cfg)) {
return false;
}
if (!gpuQuad.selectImageSet(img_set)) return false;
boolean ok = false;
try {
ok = enqueueFeederScene(scene, feeder, nscene, gpuQuad);
} finally {
if (!ok) {
gpuQuad.selectImageSet(restore_set); // never leave a half-filled set active
}
}
return ok;
}
/** Common enqueue: per-sensor u16 H2D + per-scene Row/Col block + the one-pass
* convert/condition kernel, all async on the copy stream (records the active
* set's ready event - the D5a ONE-event contract). */
private static boolean enqueueFeederScene(
final QuadCLT scene,
final CuasSceneFeeder feeder,
final int nscene,
final GpuQuad gpuQuad) {
final int slot = feeder.getSlot(nscene);
if (slot < 0) return false;
scene.saveQuadClt();
scene.setHasNewImageData(false);
for (int cam = 0; cam < feeder.getNumSensors(); cam++) {
if (!gpuQuad.setImageStagedU16(cam, slot)) return false;
}
if (feeder.isRowColEnabled()) {
final com.sun.jna.Pointer rc = gpuQuad.rowcolStaging(slot);
if ((rc == null) || !feeder.writeRowcolStaging(nscene, rc)) return false;
if (!gpuQuad.setRowcolStaged(slot)) return false;
}
return gpuQuad.execConditioningU16(feeder.isBigEndian(), feeder.isRowColEnabled());
}
/** /**
* D5 overlap variant of the preloaded upload (design ratified 07/17/2026): * D5 overlap variant of the preloaded upload (design ratified 07/17/2026):
* condition ONE scene into device image-set ring slot img_set while the * condition ONE scene into device image-set ring slot img_set while the
......
...@@ -2582,9 +2582,20 @@ public class CuasPoseRT { ...@@ -2582,9 +2582,20 @@ public class CuasPoseRT {
final QuadCLT [] quadCLTs, final QuadCLT [] quadCLTs,
final CuasScenePreload scenePreload, final CuasScenePreload scenePreload,
final int debugLevel) { final int debugLevel) {
return testPoseSequence(clt_parameters, center_CLT, quadCLTs, scenePreload, null, debugLevel);
}
/** Pose sequence using either the float preload or the in-loop 16-bit feeder (T2). */
public static double [][][] testPoseSequence(
final CLTParameters clt_parameters,
final QuadCLT center_CLT,
final QuadCLT [] quadCLTs,
final CuasScenePreload scenePreload,
final CuasSceneFeeder sceneFeeder, // By Claude on 07/18/2026 (T2)
final int debugLevel) {
final boolean [] saved_calib = new boolean [1]; final boolean [] saved_calib = new boolean [1];
double [][][] fitted = poseSequencePass(clt_parameters, center_CLT, quadCLTs, double [][][] fitted = poseSequencePass(clt_parameters, center_CLT, quadCLTs,
scenePreload, scenePreload, sceneFeeder,
saved_calib, // out: set when this pass generated+saved the tile calibration saved_calib, // out: set when this pass generated+saved the tile calibration
debugLevel); debugLevel);
if (saved_calib[0]) { // bootstrap: calibration was just generated - re-run filtered if (saved_calib[0]) { // bootstrap: calibration was just generated - re-run filtered
...@@ -2592,7 +2603,7 @@ public class CuasPoseRT { ...@@ -2592,7 +2603,7 @@ public class CuasPoseRT {
" was just generated; re-running the sequence with the filtered selection"+ " was just generated; re-running the sequence with the filtered selection"+
" (all outputs are overwritten by the filtered run)"); " (all outputs are overwritten by the filtered run)");
fitted = poseSequencePass(clt_parameters, center_CLT, quadCLTs, fitted = poseSequencePass(clt_parameters, center_CLT, quadCLTs,
scenePreload, scenePreload, sceneFeeder,
null, // saved_calib: a filtered pass never writes the calibration null, // saved_calib: a filtered pass never writes the calibration
debugLevel); debugLevel);
} }
...@@ -2606,6 +2617,7 @@ public class CuasPoseRT { ...@@ -2606,6 +2617,7 @@ public class CuasPoseRT {
final QuadCLT center_CLT, final QuadCLT center_CLT,
final QuadCLT [] quadCLTs, final QuadCLT [] quadCLTs,
final CuasScenePreload scenePreload, final CuasScenePreload scenePreload,
final CuasSceneFeeder sceneFeeder, // in-loop 16-bit feeder (T2) or null // By Claude on 07/18/2026
final boolean [] saved_calib, // out (may be null): [0]=true if the tile calibration was saved final boolean [] saved_calib, // out (may be null): [0]=true if the tile calibration was saved
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
...@@ -2768,8 +2780,10 @@ public class CuasPoseRT { ...@@ -2768,8 +2780,10 @@ public class CuasPoseRT {
} }
} }
CuasScenePreload activePreload = scenePreload; CuasScenePreload activePreload = scenePreload;
if ((activePreload != null) && Double.isNaN(cond_cfg.dc_level)) { final CuasSceneFeeder activeFeeder = sceneFeeder; // T2 in-loop 16-bit feeder // By Claude on 07/18/2026
System.out.println("CuasPoseRT: ERROR - preloaded RT path requires fixed sequence DC; pose RT measurement NOT RUN because RT-STATE/manual dc_center is unavailable"); if (activeFeeder != null) activePreload = null; // mutually exclusive; the feeder supersedes
if (((activePreload != null) || (activeFeeder != null)) && Double.isNaN(cond_cfg.dc_level)) {
System.out.println("CuasPoseRT: ERROR - preloaded/feeder RT path requires fixed sequence DC; pose RT measurement NOT RUN because RT-STATE/manual dc_center is unavailable");
return null; return null;
} }
final float [][] preloadCpuScratch; final float [][] preloadCpuScratch;
...@@ -2786,6 +2800,24 @@ public class CuasPoseRT { ...@@ -2786,6 +2800,24 @@ public class CuasPoseRT {
} else { } else {
preloadCpuScratch = null; preloadCpuScratch = null;
} }
// T2 feeder (Andrey 07/18): real per-scene file I/O INSIDE the measured loop
// (the honest RT test; also the production 4xSATA shape). Row/Col moves into
// the conversion kernel (per-scene borrowed profiles, prior scales snapshotted
// at feeder creation), so the timed Config stays strictly linear like the
// preload contract. By Claude on 07/18/2026.
final float [][] feederCpuRaw;
final float [][] feederCpuScratch;
if (activeFeeder != null) {
cond_cfg.rowcol_enable = false;
feederCpuRaw = new float [activeFeeder.getNumSensors()][activeFeeder.getNumPixels()];
feederCpuScratch = new float [activeFeeder.getNumSensors()][activeFeeder.getNumPixels()];
System.out.println("CuasPoseRT: 16-BIT FEEDER input active (in-loop reads, "+
(activeFeeder.isRowColEnabled() ? "borrowed Row/Col in-kernel" : "Row/Col bypassed")+
", timed conditioning="+(cond_cfg.gpu_enable ? "GPU u16" : "CPU")+")");
} else {
feederCpuRaw = null;
feederCpuScratch = null;
}
// D5 overlap state (design ratified 07/17/2026): dp_overlap_scene[0] = the // D5 overlap state (design ratified 07/17/2026): dp_overlap_scene[0] = the
// scene index already conditioned into the ACTIVE device image-set ring slot // scene index already conditioned into the ACTIVE device image-set ring slot
// during the previous scene's DP entry (-1 = none); dp_ring_set[0] = the ring // during the previous scene's DP entry (-1 = none); dp_ring_set[0] = the ring
...@@ -2932,14 +2964,35 @@ public class CuasPoseRT { ...@@ -2932,14 +2964,35 @@ public class CuasPoseRT {
RtPoseProfile rtProfile = null; RtPoseProfile rtProfile = null;
com.elphel.imagej.common.PerfDaemon.Hold rtPerfHold = null; // 'measure' clock hold for the timed run // By Claude on 07/17/2026 com.elphel.imagej.common.PerfDaemon.Hold rtPerfHold = null; // 'measure' clock hold for the timed run // By Claude on 07/17/2026
RT_POSE_PROFILE.remove(); RT_POSE_PROFILE.remove();
if (activePreload != null) { if ((activePreload != null) || (activeFeeder != null)) { // feeder harness: same RT instrumentation // By Claude on 07/18/2026
int rtInputs = 0; int rtInputs = 0;
for (int i = earliest; i < quadCLTs.length; i++) if (quadCLTs[i] != null) rtInputs++; for (int i = earliest; i < quadCLTs.length; i++) if (quadCLTs[i] != null) rtInputs++;
if (activePreload != null) {
if (cond_cfg.gpu_enable && !CuasConditioning.preparePreloadedConditioning( if (cond_cfg.gpu_enable && !CuasConditioning.preparePreloadedConditioning(
quadCLTs[earliest], activePreload.getScene(earliest), cond_cfg)) { quadCLTs[earliest], activePreload.getScene(earliest), cond_cfg)) {
System.out.println("CuasPoseRT: WARNING - requested GPU linear conditioning is unavailable for this configuration; timed preload path will use the CPU oracle"); System.out.println("CuasPoseRT: WARNING - requested GPU linear conditioning is unavailable for this configuration; timed preload path will use the CPU oracle");
} }
} else {
// T2: prepare the resident maps, then switch the feeder to pinned mode
// (preads land straight in the native u16 staging). Failure of either
// leaves the CPU-oracle heap mode - functional, honest, just slower.
// By Claude on 07/18/2026.
activeFeeder.reset(); // bootstrap second pass / rerun: drain + clean staging state
final boolean feeder_gpu = cond_cfg.gpu_enable &&
CuasConditioning.prepareFeederConditioning(quadCLTs[earliest], activeFeeder, cond_cfg) &&
activeFeeder.enablePinned(quadCLTs[earliest].getGPUQuad());
if (cond_cfg.gpu_enable && !feeder_gpu) {
System.out.println("CuasPoseRT: WARNING - GPU u16 conditioning unavailable for this configuration; feeder falls back to the CPU oracle (heap reads)");
}
}
rtTiming = new RtPoseTiming(clt_parameters.curt.pose_pace, rtInputs); rtTiming = new RtPoseTiming(clt_parameters.curt.pose_pace, rtInputs);
if (activeFeeder != null) {
// Arrival moderation (Andrey 07/18): in paced mode the DATA - not just
// the loop - is released on the 60 Hz epoch grid; scene k's read starts
// no earlier than epoch + k*period. Then kick scene 0's read.
if (clt_parameters.curt.pose_pace) activeFeeder.arm(rtTiming.epochNs, rtTiming.periodNs);
activeFeeder.requestNext();
}
final int profileCycles = (clt_parameters.curt.pose_cycles > 0) ? final int profileCycles = (clt_parameters.curt.pose_cycles > 0) ?
clt_parameters.curt.pose_cycles : clt_parameters.imp.max_cycles; clt_parameters.curt.pose_cycles : clt_parameters.imp.max_cycles;
rtProfile = new RtPoseProfile(rtInputs, profileCycles); rtProfile = new RtPoseProfile(rtInputs, profileCycles);
...@@ -3001,6 +3054,18 @@ public class CuasPoseRT { ...@@ -3001,6 +3054,18 @@ public class CuasPoseRT {
// previous scene's DP entry - nothing to do here. By Claude on 07/17/2026. // previous scene's DP entry - nothing to do here. By Claude on 07/17/2026.
dp_overlap_scene[0] = -1; dp_overlap_scene[0] = -1;
raw_ok = true; raw_ok = true;
// T2 safe point: everything through the previous chain has collected,
// so the next staging slot's H2D is at least one full scene behind
// (the float path's one-scene-of-slack contract) - kick the next read.
// By Claude on 07/18/2026.
if (activeFeeder != null) activeFeeder.requestNext();
} else if (activeFeeder != null) {
// T2 serial path: await this scene's staged read, enqueue u16 H2D +
// convert/condition, then kick the next read (same safe point).
// By Claude on 07/18/2026.
raw_ok = CuasConditioning.conditionFeederSceneToGpu(
quadCLTs[nscene], activeFeeder, nscene, feederCpuRaw, feederCpuScratch, cond_cfg);
activeFeeder.requestNext();
} else { } else {
raw_ok = (activePreload != null) ? raw_ok = (activePreload != null) ?
CuasConditioning.conditionPreloadedSceneToGpu( CuasConditioning.conditionPreloadedSceneToGpu(
...@@ -3159,8 +3224,10 @@ public class CuasPoseRT { ...@@ -3159,8 +3224,10 @@ public class CuasPoseRT {
// as before. Any failure restores the previous set and disables the // as before. Any failure restores the previous set and disables the
// overlap for the rest of the run (fail-safe). By Claude on 07/17/2026. // overlap for the rest of the run (fail-safe). By Claude on 07/17/2026.
Runnable dp_overlap_work = null; Runnable dp_overlap_work = null;
final CuasScenePreload overlapPreload = activePreload;
if (dp_overlap_ok[0] && clt_parameters.curt.pose_h2d_overlap && if (dp_overlap_ok[0] && clt_parameters.curt.pose_h2d_overlap &&
clt_parameters.curt.pose_raw && (activePreload != null) && clt_parameters.curt.pose_raw &&
((activePreload != null) || ((activeFeeder != null) && activeFeeder.isPinned())) && // T2: feeder overlap (file I/O IS the overlap now) // By Claude on 07/18/2026
center_CLT.getGPUQuad().supportsPoseSceneDpOverlap()) { center_CLT.getGPUQuad().supportsPoseSceneDpOverlap()) {
int nn = -1; int nn = -1;
for (int j = nscene + 1; j < quadCLTs.length; j++) { for (int j = nscene + 1; j < quadCLTs.length; j++) {
...@@ -3169,9 +3236,34 @@ public class CuasPoseRT { ...@@ -3169,9 +3236,34 @@ public class CuasPoseRT {
if (nn >= 0) { if (nn >= 0) {
final int next_scene = nn; final int next_scene = nn;
dp_overlap_work = () -> { dp_overlap_work = () -> {
if (activeFeeder != null) {
// T2: paced mode never parks inside the DP window - the overlap
// only fires when the next scene's read already landed (i.e.
// when running behind arrival, exactly when throughput is
// needed); when caught up the serial order has idle margin.
// Unpaced (capacity) mode awaits the in-flight read - it was
// kicked a full scene ago and hides under the ~12 ms DP entry.
// A failed read just skips (the serial path coasts that scene);
// it does NOT disable the overlap. By Claude on 07/18/2026.
if (activeFeeder.isPaced() ? !activeFeeder.isStaged(next_scene) :
!activeFeeder.awaitStaged(next_scene)) {
return;
}
final int target_set = dp_ring_set[0] ^ 1;
if (CuasConditioning.conditionFeederSceneToGpuOverlap(
quadCLTs[next_scene], activeFeeder, next_scene,
cond_cfg, target_set, dp_ring_set[0])) {
dp_ring_set[0] = target_set;
dp_overlap_scene[0] = next_scene;
} else {
dp_overlap_ok[0] = false;
System.out.println("CuasPoseRT: D5 overlap conditioning DISABLED for this run - serial order resumes");
}
return;
}
final int target_set = dp_ring_set[0] ^ 1; final int target_set = dp_ring_set[0] ^ 1;
if (CuasConditioning.conditionPreloadedSceneToGpuOverlap( if (CuasConditioning.conditionPreloadedSceneToGpuOverlap(
quadCLTs[next_scene], activePreload.getScene(next_scene), quadCLTs[next_scene], overlapPreload.getScene(next_scene),
preloadCpuScratch, cond_cfg, target_set, dp_ring_set[0])) { preloadCpuScratch, cond_cfg, target_set, dp_ring_set[0])) {
dp_ring_set[0] = target_set; dp_ring_set[0] = target_set;
dp_overlap_scene[0] = next_scene; dp_overlap_scene[0] = next_scene;
......
...@@ -88,8 +88,22 @@ public class CuasRT { ...@@ -88,8 +88,22 @@ public class CuasRT {
// calibratePhotometric(): borrowed Row/Col profiles are expressed under the prior // calibratePhotometric(): borrowed Row/Col profiles are expressed under the prior
// corr-xml scales still attached to the scenes here. By Codex on 07/15/2026. // corr-xml scales still attached to the scenes here. By Codex on 07/15/2026.
CuasScenePreload scenePreload = null; CuasScenePreload scenePreload = null;
CuasSceneFeeder sceneFeeder = null; // T2 in-loop 16-bit feeder // By Claude on 07/18/2026
if (clt_parameters.curt.pose_test && clt_parameters.curt.pose_raw && if (clt_parameters.curt.pose_test && clt_parameters.curt.pose_raw &&
"none".equals(clt_parameters.curt.kernel_test)) { "none".equals(clt_parameters.curt.kernel_test)) {
if (clt_parameters.curt.pose_feed16) {
// T2 (Andrey 07/18): drop the ~9.7 GiB float preload - real per-scene
// 16-bit reads inside the measured loop (honest RT test, production
// 4xSATA shape). Created HERE for the same reason as the preload: the
// borrowed Row/Col prior scales must be snapshotted before
// calibratePhotometric() refines them. By Claude on 07/18/2026.
sceneFeeder = CuasSceneFeeder.create(
quadCLTs, clt_parameters.curt.rowcol_en, debugLevel - 2);
if (sceneFeeder == null) {
System.out.println("CuasRT: ERROR - 16-bit feeder setup failed; pose RT measurement NOT RUN (uncheck curt_pose_feed16 for the float preload)");
return;
}
} else {
scenePreload = CuasScenePreload.load( scenePreload = CuasScenePreload.load(
quadCLTs, clt_parameters.curt.rowcol_en, quadCLTs, clt_parameters.curt.rowcol_en,
ImageDtt.THREADS_MAX, debugLevel - 2); ImageDtt.THREADS_MAX, debugLevel - 2);
...@@ -98,12 +112,15 @@ public class CuasRT { ...@@ -98,12 +112,15 @@ public class CuasRT {
return; return;
} }
} }
}
calibratePhotometric(clt_parameters, master_CLT, quadCLTs, quadCLT_main, ref_index, debugLevel); calibratePhotometric(clt_parameters, master_CLT, quadCLTs, quadCLT_main, ref_index, debugLevel);
appropriateCenter(clt_parameters, master_CLT, debugLevel); appropriateCenter(clt_parameters, master_CLT, debugLevel);
// ---- 2. DIAGNOSTICS (optional, exclusive - replace production and return) ---- // ---- 2. DIAGNOSTICS (optional, exclusive - replace production and return) ----
if (diagnostics(clt_parameters, master_CLT, quadCLTs, scenePreload, debugLevel)) { if (diagnostics(clt_parameters, master_CLT, quadCLTs, scenePreload, sceneFeeder, debugLevel)) {
if (sceneFeeder != null) sceneFeeder.shutdown(); // By Claude on 07/18/2026
return; return;
} }
if (sceneFeeder != null) sceneFeeder.shutdown(); // By Claude on 07/18/2026
// ---- 3. PRODUCTION: per-scene processing + target detection ---- // ---- 3. PRODUCTION: per-scene processing + target detection ----
detect(clt_parameters, cuasRanging, master_CLT, imp_targets, uasLogReader, batch_mode, debugLevel); detect(clt_parameters, cuasRanging, master_CLT, imp_targets, uasLogReader, batch_mode, debugLevel);
} }
...@@ -367,6 +384,7 @@ public class CuasRT { ...@@ -367,6 +384,7 @@ public class CuasRT {
final QuadCLT master_CLT, final QuadCLT master_CLT,
final QuadCLT [] quadCLTs, final QuadCLT [] quadCLTs,
final CuasScenePreload scenePreload, final CuasScenePreload scenePreload,
final CuasSceneFeeder sceneFeeder, // T2 in-loop 16-bit feeder (or null) // By Claude on 07/18/2026
final int debugLevel) { final int debugLevel) {
boolean ran = false; boolean ran = false;
if (!"none".equals(clt_parameters.curt.kernel_test)) { if (!"none".equals(clt_parameters.curt.kernel_test)) {
...@@ -389,6 +407,7 @@ public class CuasRT { ...@@ -389,6 +407,7 @@ public class CuasRT {
master_CLT, // QuadCLT center_CLT, master_CLT, // QuadCLT center_CLT,
quadCLTs, // QuadCLT [] quadCLTs, quadCLTs, // QuadCLT [] quadCLTs,
scenePreload, // CuasScenePreload preloaded raw scenes (or null) scenePreload, // CuasScenePreload preloaded raw scenes (or null)
sceneFeeder, // CuasSceneFeeder in-loop 16-bit feeder (or null) // By Claude on 07/18/2026
debugLevel); // int debugLevel debugLevel); // int debugLevel
ran = true; ran = true;
} }
......
This diff is collapsed.
/**
** PosixIo.java - minimal libc file I/O for the CUAS RT 16-bit scene feeder.
**
** Copyright (C) 2026 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** PosixIo.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** PosixIo.java is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with PosixIo.java. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
package com.elphel.imagej.cuas.rt;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
/**
* Direct-mapped libc calls for the T2 16-bit feeder: pread() straight into the
* pinned u16 staging buffer (no Java heap copy - the kernel's read() IS the
* pinned write), and posix_fadvise(DONTNEED) so every run's in-loop reads stay
* honestly cold (the production feeder is a RAM-based dual-port SATA device
* whose frames are always new - page-cache replay would fake the I/O cost).
* Linux/glibc only, like the JNA tile-processor backend it feeds.
* By Claude on 07/18/2026, from Andrey's T2 design.
*/
public final class PosixIo {
public static final int O_RDONLY = 0;
public static final int POSIX_FADV_DONTNEED = 4;
public static native int open(String path, int flags);
public static native long pread(int fd, Pointer buf, long count, long offset);
public static native int close(int fd);
public static native int posix_fadvise(int fd, long offset, long len, int advice);
private static boolean available = false;
static {
try {
Native.register(PosixIo.class, "c");
available = true;
} catch (Throwable t) {
System.out.println("PosixIo: libc direct mapping unavailable ("+t.getMessage()+
") - the 16-bit feeder will fall back to heap reads");
}
}
public static boolean isAvailable() { return available; }
private PosixIo() {}
}
...@@ -3156,6 +3156,35 @@ public class GpuQuad{ // quad camera description ...@@ -3156,6 +3156,35 @@ public class GpuQuad{ // quad camera description
public boolean imageSetReadyRecord() { public boolean imageSetReadyRecord() {
return false; return false;
} }
// ---- T2 16-bit feeder (07/18/2026): pinned u16 staging + one-pass GPU
// uint16->float + Row/Col + two-map conditioning. Base/JCuda: unsupported -
// the float preload/direct paths remain. By Claude on 07/18/2026. ----
public boolean supportsU16Conditioning() {
return false;
}
/** Pinned host u16 staging for slot (0/1) - the feeder preads raw TIFF strip
* bytes straight into it. Null = unsupported/failed. */
public com.sun.jna.Pointer u16Staging(int slot) {
return null;
}
/** Pinned host staging for the borrowed per-scene Row/Col doubles:
* rows [cam][width] | cols [cam][height] | inv_scales [cam]. */
public com.sun.jna.Pointer rowcolStaging(int slot) {
return null;
}
/** Enqueue the async H2D of one sensor's u16 image from staging slot (copy stream). */
public boolean setImageStagedU16(int cam, int slot) {
return false;
}
/** Enqueue the async H2D of the rowcol staging block (copy stream). */
public boolean setRowcolStaged(int slot) {
return false;
}
/** Convert+condition the staged u16 scene into the ACTIVE image set on the copy
* stream (async; records the set's ready event - ONE event = uploaded+conditioned). */
public boolean execConditioningU16(boolean swapBytes, boolean rowcolEnable) {
return false;
}
/** D5b launch half of execPoseSceneDp: same inputs, no readbacks - enqueue the whole /** D5b launch half of execPoseSceneDp: same inputs, no readbacks - enqueue the whole
* per-scene chain and return immediately (want_trace/want_mstats fix what the later * per-scene chain and return immediately (want_trace/want_mstats fix what the later
* collect may read). Returns 1 (launched) or a negative. */ * collect may read). Returns 1 (launched) or a negative. */
......
...@@ -982,6 +982,60 @@ public class GpuQuadJna extends GpuQuad { ...@@ -982,6 +982,60 @@ public class GpuQuadJna extends GpuQuad {
return false; return false;
} }
} }
// ---- T2 16-bit feeder (07/18/2026): pinned u16 staging + one-pass GPU
// uint16->float + Row/Col + two-map conditioning. By Claude on 07/18/2026. ----
@Override public boolean supportsU16Conditioning() { return !rectilinear; }
@Override public Pointer u16Staging(int slot) {
try {
final Pointer ptr = lib.tp_proc_bayer_staging_u16(proc, slot);
if (ptr == null) System.out.println("GpuQuadJna.u16Staging("+slot+"): "+lib.tp_last_error());
return ptr;
} catch (UnsatisfiedLinkError e) {
System.out.println("GpuQuadJna.u16Staging(): native missing ("+e.getMessage()+")");
return null;
}
}
@Override public Pointer rowcolStaging(int slot) {
try {
final Pointer ptr = lib.tp_proc_rowcol_staging(proc, slot);
if (ptr == null) System.out.println("GpuQuadJna.rowcolStaging("+slot+"): "+lib.tp_last_error());
return ptr;
} catch (UnsatisfiedLinkError e) {
System.out.println("GpuQuadJna.rowcolStaging(): native missing ("+e.getMessage()+")");
return null;
}
}
@Override public boolean setImageStagedU16(int cam, int slot) {
try {
final int rc = lib.tp_proc_set_image_staged_u16(proc, cam, slot);
if (rc != 0) System.out.println("GpuQuadJna.setImageStagedU16("+cam+","+slot+"): rc="+rc+" ("+lib.tp_last_error()+")");
return rc == 0;
} catch (UnsatisfiedLinkError e) {
System.out.println("GpuQuadJna.setImageStagedU16(): native missing ("+e.getMessage()+")");
return false;
}
}
@Override public boolean setRowcolStaged(int slot) {
try {
final int rc = lib.tp_proc_set_rowcol_staged(proc, slot);
if (rc != 0) System.out.println("GpuQuadJna.setRowcolStaged("+slot+"): rc="+rc+" ("+lib.tp_last_error()+")");
return rc == 0;
} catch (UnsatisfiedLinkError e) {
System.out.println("GpuQuadJna.setRowcolStaged(): native missing ("+e.getMessage()+")");
return false;
}
}
@Override public boolean execConditioningU16(boolean swapBytes, boolean rowcolEnable) {
try {
final int rc = lib.tp_proc_exec_conditioning_u16(proc, swapBytes ? 1 : 0, rowcolEnable ? 1 : 0);
if (rc != 0) System.out.println("GpuQuadJna.execConditioningU16(): rc="+rc+" ("+lib.tp_last_error()+")");
if (rc == 0) jna_bayer_set = true; // conditioned images are now resident, same as an upload
return rc == 0;
} catch (UnsatisfiedLinkError e) {
System.out.println("GpuQuadJna.execConditioningU16(): native missing ("+e.getMessage()+")");
return false;
}
}
@Override public int execPoseSceneDpLaunch( @Override public int execPoseSceneDpLaunch(
final IntersceneLmaFloat.Camera reference, final IntersceneLmaFloat.Camera reference,
final IntersceneLmaFloat.Camera scene, final IntersceneLmaFloat.Camera scene,
......
...@@ -10,7 +10,7 @@ import com.sun.jna.Pointer; ...@@ -10,7 +10,7 @@ import com.sun.jna.Pointer;
* com.elphel.imagej.gpu.jna.Stage0 [kernel_src_dir] [libcudadevrt.a] * com.elphel.imagej.gpu.jna.Stage0 [kernel_src_dir] [libcudadevrt.a]
*/ */
public class Stage0 { public class Stage0 {
private static final int EXPECTED_KERNELS = 41; // 40 (through rung D4) + erase_clt_task_tiles (margin rung M1: erase-by-task-list in the pose chain) // By Claude on 07/17/2026 private static final int EXPECTED_KERNELS = 42; // 41 (through margin rung M1) + condition_lwir_u16 (T2 16-bit feeder) // By Claude on 07/18/2026
public static void main(String[] args) { public static void main(String[] args) {
String srcdir = (args.length > 0) ? args[0] : "/home/elphel/git/tile_processor_gpu/src"; String srcdir = (args.length > 0) ? args[0] : "/home/elphel/git/tile_processor_gpu/src";
String devrt = (args.length > 1) ? args[1] : "/usr/local/cuda/targets/x86_64-linux/lib/libcudadevrt.a"; String devrt = (args.length > 1) ? args[1] : "/usr/local/cuda/targets/x86_64-linux/lib/libcudadevrt.a";
......
...@@ -81,6 +81,22 @@ public interface TpJna extends Library { ...@@ -81,6 +81,22 @@ public interface TpJna extends Library {
* return immediately (per-sensor copy/compute pipelining). Image consumers fence * return immediately (per-sensor copy/compute pipelining). Image consumers fence
* natively, so a partial upload is never visible to kernels or readbacks. */ * natively, so a partial upload is never visible to kernels or readbacks. */
int tp_proc_set_image_staged(Pointer proc, int cam, int slot); int tp_proc_set_image_staged(Pointer proc, int cam, int slot);
// ---- T2 16-bit feeder (07/18/2026): pinned u16 staging + one-pass GPU
// uint16->float + Row/Col + two-map conditioning. By Claude on 07/18/2026. ----
/** Pinned host u16 staging for slot (0/1): num_cams*img_w*img_h uint16 - the feeder
* preads raw TIFF strip bytes straight into it (no heap copy). Null on failure. */
Pointer tp_proc_bayer_staging_u16(Pointer proc, int slot);
/** Pinned host staging for the borrowed per-scene Row/Col doubles:
* rows [cam][img_w] | cols [cam][img_h] | inv_scales [cam]. Null on failure. */
Pointer tp_proc_rowcol_staging(Pointer proc, int slot);
/** Enqueue the async H2D of ONE sensor's u16 image from staging slot into the device
* u16 scratch (copy stream; consumed by tp_proc_exec_conditioning_u16). */
int tp_proc_set_image_staged_u16(Pointer proc, int cam, int slot);
/** Enqueue the async H2D of the whole rowcol staging block (copy stream). */
int tp_proc_set_rowcol_staged(Pointer proc, int slot);
/** Convert+condition the staged u16 scene into the ACTIVE image set on the copy
* stream (async; records the set's ready event - the D5a ONE-event contract). */
int tp_proc_exec_conditioning_u16(Pointer proc, int swapBytes, int rowcolEnable);
/** De-pitch one resident source image into out[width*height]. */ /** De-pitch one resident source image into out[width*height]. */
int tp_proc_get_image(Pointer proc, int cam, float[] out); int tp_proc_get_image(Pointer proc, int cam, float[] out);
/** Resident production calibration maps, contiguous [camera][height][width]. */ /** Resident production calibration maps, contiguous [camera][height][width]. */
......
...@@ -25,6 +25,7 @@ public class CuasRtParameters { ...@@ -25,6 +25,7 @@ public class CuasRtParameters {
public int pose_shrink = 4; // tile-selection interior gate (3-A3, Andrey's rulings 07/13/2026): exclude tiles within this many tiles of the tile-array BORDER before selection (pure ring, NO morphological shrink - the calibration is NaN wherever a tile was not strength-selected, ~21% finite density, so a blind shrink annihilated the selection to ~2 tiles in the first attempt). The OOB-missing band is geometrically confined to the frame border (margin-dropped ring 1-2 tiles + partial 16-sensor OOB soft band 12 px = 1.5 tiles); ring 4 = hard+soft+slack, guaranteeing all-16-interior tiles at every scene pose - the GPU pose chain can then bypass the consolidation OOB pass with a FIXED per-sequence tile list. 0 = off (legacy selection). // By Claude on 07/13/2026 public int pose_shrink = 4; // tile-selection interior gate (3-A3, Andrey's rulings 07/13/2026): exclude tiles within this many tiles of the tile-array BORDER before selection (pure ring, NO morphological shrink - the calibration is NaN wherever a tile was not strength-selected, ~21% finite density, so a blind shrink annihilated the selection to ~2 tiles in the first attempt). The OOB-missing band is geometrically confined to the frame border (margin-dropped ring 1-2 tiles + partial 16-sensor OOB soft band 12 px = 1.5 tiles); ring 4 = hard+soft+slack, guaranteeing all-16-interior tiles at every scene pose - the GPU pose chain can then bypass the consolidation OOB pass with a FIXED per-sequence tile list. 0 = off (legacy selection). // By Claude on 07/13/2026
public boolean pose_raw = false; // phase A2/RT ingest: preload all RAW /jp4/ scenes before the measured loop; apply borrowed Row/Col profiles there when enabled; then condition with the current scale/offset/FPN/DC and force-upload. Bypasses prepared image_data and excludes file I/O from RT timing. // By Claude on 07/05/2026, preload Codex 07/15/2026 public boolean pose_raw = false; // phase A2/RT ingest: preload all RAW /jp4/ scenes before the measured loop; apply borrowed Row/Col profiles there when enabled; then condition with the current scale/offset/FPN/DC and force-upload. Bypasses prepared image_data and excludes file I/O from RT timing. // By Claude on 07/05/2026, preload Codex 07/15/2026
public boolean pose_pace = false; // preloaded pose RT harness: false = maximum-throughput run; true = release every input at exactly 60 Hz, process every scene with no skipping, and report queue/latency/deadline statistics. Saved as curt_pose_pace for run provenance. // By Codex on 07/15/2026 public boolean pose_pace = false; // preloaded pose RT harness: false = maximum-throughput run; true = release every input at exactly 60 Hz, process every scene with no skipping, and report queue/latency/deadline statistics. Saved as curt_pose_pace for run provenance. // By Codex on 07/15/2026
public boolean pose_feed16 = true; // T2 (Andrey 07/18): replace the ~9.7 GiB float preload with the in-loop 16-bit feeder - real per-scene fixed-offset TIFF reads (4 threads = the production 4xSATA sensor groups) pread straight into pinned u16 staging, GPU does byte-swap + borrowed Row/Col + conditioning in one kernel (bit-exact vs the preload, case u16_cond). fadvise keeps reruns honestly cold; paced mode also gates the DATA at 60 Hz arrival. OFF = the legacy preload. // By Claude on 07/18/2026
public boolean pose_lean = false; // phase B measurement engine: TD-average the 16 sensors (CuasTD, CPU bridge) then ONE conj-multiply vs the virtual-center TD -> FZ-normalize -> PD -> argmax+eigen (getMaxXYCmEig) -> 3-angle LMA. All existing GPU kernels. v1: NO motion-blur compensation - compare vs the NOMB baseline. // By Claude on 07/05/2026 public boolean pose_lean = false; // phase B measurement engine: TD-average the 16 sensors (CuasTD, CPU bridge) then ONE conj-multiply vs the virtual-center TD -> FZ-normalize -> PD -> argmax+eigen (getMaxXYCmEig) -> 3-angle LMA. All existing GPU kernels. v1: NO motion-blur compensation - compare vs the NOMB baseline. // By Claude on 07/05/2026
public boolean pose_full = false; // DEBUG: use ALL strength-selected tiles (~1074) - the -POSE-RT-TILE-CALIB calibration is neither read nor written (temporary bypass of the 150-tile filter for measurement debugging). // By Claude on 07/04/2026 public boolean pose_full = false; // DEBUG: use ALL strength-selected tiles (~1074) - the -POSE-RT-TILE-CALIB calibration is neither read nor written (temporary bypass of the 150-tile filter for measurement debugging). // By Claude on 07/04/2026
public boolean pose_corr_save = false; // DEBUG: save the per-scene 2D correlations vs the virtual center in the pixel domain (-POSE-RT-CORR2D: z=scenes, tile grid of 16x16 cells, last LMA cycle) - lean engine only. // By Claude on 07/04/2026 public boolean pose_corr_save = false; // DEBUG: save the per-scene 2D correlations vs the virtual center in the pixel domain (-POSE-RT-CORR2D: z=scenes, tile grid of 16x16 cells, last LMA cycle) - lean engine only. // By Claude on 07/04/2026
...@@ -142,6 +143,8 @@ public class CuasRtParameters { ...@@ -142,6 +143,8 @@ public class CuasRtParameters {
"Preload every RAW /jp4/ scene before timing; optionally apply borrowed Row/Col profiles during setup, then condition with current scale/offset/FPN/DC and force-upload. File I/O is excluded from RT timing."); "Preload every RAW /jp4/ scene before timing; optionally apply borrowed Row/Col profiles during setup, then condition with current scale/offset/FPN/DC and force-upload. File I/O is excluded from RT timing.");
gd.addCheckbox ("Pace preloaded pose test at 60 FPS", this.pose_pace, // By Codex on 07/15/2026 gd.addCheckbox ("Pace preloaded pose test at 60 FPS", this.pose_pace, // By Codex on 07/15/2026
"OFF = maximum-throughput run. ON = release all inputs at 60 Hz without skipping and report bounded-queue, latency and deadline statistics. Applies only when the all-scene preload succeeds."); "OFF = maximum-throughput run. ON = release all inputs at 60 Hz without skipping and report bounded-queue, latency and deadline statistics. Applies only when the all-scene preload succeeds.");
gd.addCheckbox ("In-loop 16-bit feeder (no preload)", this.pose_feed16, // By Claude on 07/18/2026
"Read the 16-bit scene TIFFs INSIDE the measured loop (4 reader threads = the production 4xSATA sensor groups) straight into pinned staging; the GPU converts+conditions in one kernel, bit-exact vs the preload. Honest RT I/O; with 60 FPS pacing the data arrival is gated too. OFF = the legacy ~9.7 GiB float preload.");
gd.addCheckbox ("Pose test lean correlation (B)", this.pose_lean, // By Claude on 07/05/2026 gd.addCheckbox ("Pose test lean correlation (B)", this.pose_lean, // By Claude on 07/05/2026
"Phase B measurement: TD-average the 16 sensors, then ONE conj-multiply vs the virtual-center TD -> FZ-normalize -> PD -> argmax+eigen -> 3-angle LMA. v1 has NO motion-blur compensation (compare vs the NOMB baseline)."); "Phase B measurement: TD-average the 16 sensors, then ONE conj-multiply vs the virtual-center TD -> FZ-normalize -> PD -> argmax+eigen -> 3-angle LMA. v1 has NO motion-blur compensation (compare vs the NOMB baseline).");
...@@ -358,6 +361,7 @@ public class CuasRtParameters { ...@@ -358,6 +361,7 @@ public class CuasRtParameters {
this.pose_shrink = (int) gd.getNextNumber(); // By Claude on 07/13/2026 this.pose_shrink = (int) gd.getNextNumber(); // By Claude on 07/13/2026
this.pose_raw = gd.getNextBoolean(); // By Claude on 07/05/2026 this.pose_raw = gd.getNextBoolean(); // By Claude on 07/05/2026
this.pose_pace = gd.getNextBoolean(); // By Codex on 07/15/2026 this.pose_pace = gd.getNextBoolean(); // By Codex on 07/15/2026
this.pose_feed16 = gd.getNextBoolean(); // By Claude on 07/18/2026
this.pose_lean = gd.getNextBoolean(); // By Claude on 07/05/2026 this.pose_lean = gd.getNextBoolean(); // By Claude on 07/05/2026
this.pose_full = gd.getNextBoolean(); // By Claude on 07/04/2026 this.pose_full = gd.getNextBoolean(); // By Claude on 07/04/2026
this.pose_corr_save = gd.getNextBoolean(); // By Claude on 07/04/2026 this.pose_corr_save = gd.getNextBoolean(); // By Claude on 07/04/2026
...@@ -469,6 +473,7 @@ public class CuasRtParameters { ...@@ -469,6 +473,7 @@ public class CuasRtParameters {
properties.setProperty(prefix+"pose_shrink", this.pose_shrink+""); // int // By Claude on 07/13/2026 properties.setProperty(prefix+"pose_shrink", this.pose_shrink+""); // int // By Claude on 07/13/2026
properties.setProperty(prefix+"pose_raw", this.pose_raw+""); // boolean // By Claude on 07/05/2026 properties.setProperty(prefix+"pose_raw", this.pose_raw+""); // boolean // By Claude on 07/05/2026
properties.setProperty(prefix+"pose_pace", this.pose_pace+""); // boolean // By Codex on 07/15/2026 properties.setProperty(prefix+"pose_pace", this.pose_pace+""); // boolean // By Codex on 07/15/2026
properties.setProperty(prefix+"pose_feed16", this.pose_feed16+""); // boolean // By Claude on 07/18/2026
properties.setProperty(prefix+"pose_lean", this.pose_lean+""); // boolean // By Claude on 07/05/2026 properties.setProperty(prefix+"pose_lean", this.pose_lean+""); // boolean // By Claude on 07/05/2026
properties.setProperty(prefix+"pose_full", this.pose_full+""); // boolean // By Claude on 07/04/2026 properties.setProperty(prefix+"pose_full", this.pose_full+""); // boolean // By Claude on 07/04/2026
properties.setProperty(prefix+"pose_corr_save", this.pose_corr_save+""); // boolean // By Claude on 07/04/2026 properties.setProperty(prefix+"pose_corr_save", this.pose_corr_save+""); // boolean // By Claude on 07/04/2026
...@@ -580,6 +585,7 @@ public class CuasRtParameters { ...@@ -580,6 +585,7 @@ public class CuasRtParameters {
if (properties.getProperty(prefix+"pose_shrink")!=null) this.pose_shrink=Integer.parseInt(properties.getProperty(prefix+"pose_shrink")); // By Claude on 07/13/2026 if (properties.getProperty(prefix+"pose_shrink")!=null) this.pose_shrink=Integer.parseInt(properties.getProperty(prefix+"pose_shrink")); // By Claude on 07/13/2026
if (properties.getProperty(prefix+"pose_raw")!=null) this.pose_raw=Boolean.parseBoolean(properties.getProperty(prefix+"pose_raw")); // By Claude on 07/05/2026 if (properties.getProperty(prefix+"pose_raw")!=null) this.pose_raw=Boolean.parseBoolean(properties.getProperty(prefix+"pose_raw")); // By Claude on 07/05/2026
if (properties.getProperty(prefix+"pose_pace")!=null) this.pose_pace=Boolean.parseBoolean(properties.getProperty(prefix+"pose_pace")); // By Codex on 07/15/2026 if (properties.getProperty(prefix+"pose_pace")!=null) this.pose_pace=Boolean.parseBoolean(properties.getProperty(prefix+"pose_pace")); // By Codex on 07/15/2026
if (properties.getProperty(prefix+"pose_feed16")!=null) this.pose_feed16=Boolean.parseBoolean(properties.getProperty(prefix+"pose_feed16")); // By Claude on 07/18/2026
if (properties.getProperty(prefix+"pose_lean")!=null) this.pose_lean=Boolean.parseBoolean(properties.getProperty(prefix+"pose_lean")); // By Claude on 07/05/2026 if (properties.getProperty(prefix+"pose_lean")!=null) this.pose_lean=Boolean.parseBoolean(properties.getProperty(prefix+"pose_lean")); // By Claude on 07/05/2026
if (properties.getProperty(prefix+"pose_full")!=null) this.pose_full=Boolean.parseBoolean(properties.getProperty(prefix+"pose_full")); // By Claude on 07/04/2026 if (properties.getProperty(prefix+"pose_full")!=null) this.pose_full=Boolean.parseBoolean(properties.getProperty(prefix+"pose_full")); // By Claude on 07/04/2026
if (properties.getProperty(prefix+"pose_corr_save")!=null) this.pose_corr_save=Boolean.parseBoolean(properties.getProperty(prefix+"pose_corr_save")); // By Claude on 07/04/2026 if (properties.getProperty(prefix+"pose_corr_save")!=null) this.pose_corr_save=Boolean.parseBoolean(properties.getProperty(prefix+"pose_corr_save")); // By Claude on 07/04/2026
...@@ -694,6 +700,7 @@ public class CuasRtParameters { ...@@ -694,6 +700,7 @@ public class CuasRtParameters {
cp.pose_shrink = this.pose_shrink; // By Claude on 07/13/2026 cp.pose_shrink = this.pose_shrink; // By Claude on 07/13/2026
cp.pose_raw = this.pose_raw; cp.pose_raw = this.pose_raw;
cp.pose_pace = this.pose_pace; // By Codex on 07/15/2026 cp.pose_pace = this.pose_pace; // By Codex on 07/15/2026
cp.pose_feed16 = this.pose_feed16; // By Claude on 07/18/2026
cp.pose_lean = this.pose_lean; cp.pose_lean = this.pose_lean;
cp.pose_full = this.pose_full; // By Claude on 07/04/2026 cp.pose_full = this.pose_full; // By Claude on 07/04/2026
cp.pose_corr_save = this.pose_corr_save; // By Claude on 07/04/2026 cp.pose_corr_save = this.pose_corr_save; // 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