- 16 Jul, 2026 8 commits
-
-
Andrey Filippov authored
Design 3-A4i rung B (native tile_processor_gpu 5f47326): for the lean three-angle shape the GPU decision drives the Java state machine: - resident-valid production path: accept/stop from packed[23..24], RMS from packed[19..22] (floats widened exactly), parameters_vector from the resident candidate; NO Java candidate projection, NO re-decision, NO rejection-restore projection (GPU retained current state, device-side set-index commit). Decision equivalence was proven over 1,988 steps with zero mismatches (session-43 gate). - invalid resident result (singular solve / non-finite) = REJECTED-STEP semantics: caller raises lambda and retries/exits; no Java-double fallback for the lean shape (fallbacks only where free). General shapes and the no-resident paths are unchanged. - one-shot oracle preserved: at pose_lma_debug>=1 the first step falls through the legacy path once and prints the existing preparation/candidate/ RMS-decision comparisons; production steps never compute the double side. - marker updated: 'resident CUDA float LMA decision AUTHORITATIVE'. Gates: mvn package PASS; mvn test PASS (no test sources); Stage0 33/33; full native suite in tile_processor_gpu 5f47326. Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
Design 3-A4i rung A (2026-07-16 handoff): the 00:25:48 gate profile's 'leanMeasure other' (26.1 ms/call, 43% of post) was unprofiled debug-save data motion (pose_corr_save/pose_img_save). Changes: - leanFitScene passes corr_pd_out/img_out only on the LAST outer cycle in fixed-cycle mode (legacy convergence mode keeps every-cycle so an early exit still fills the holders). - New DEBUG_FETCH profile stage wraps perSensorImagesFromTD, the no-MB debug re-convert, and fetchNormalizedPD, so debug data motion can never hide in 'leanMeasure other' again (it joins measureAccounted). Armed pose_corr capture unaffected (fetch keyed on isArmed() unchanged). Expected gate: poses/records byte-exact, hyperstacks identical, capacity ~3.9 -> ~5.5 scenes/s in the debug config. Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
Co-authored-by:Codex <codex@elphel.com>
-
Andrey Filippov authored
Co-authored-by:Codex <codex@elphel.com>
-
Andrey Filippov authored
Co-authored-by:Codex <codex@elphel.com>
-
Andrey Filippov authored
Co-authored-by:Codex <codex@elphel.com>
-
Andrey Filippov authored
Co-authored-by:Codex <codex@elphel.com>
-
Andrey Filippov authored
Co-authored-by:Codex <codex@elphel.com>
-
- 15 Jul, 2026 10 commits
-
-
Andrey Filippov authored
Co-authored-by:Codex <codex@elphel.com>
-
Andrey Filippov authored
Co-authored-by:Codex <codex@elphel.com>
-
Andrey Filippov authored
Co-authored-by:Codex <codex@elphel.com>
-
Andrey Filippov authored
Co-authored-by:Codex <codex@elphel.com>
-
Andrey Filippov authored
Co-authored-by:Codex <codex@elphel.com>
-
Andrey Filippov authored
Co-authored-by:Codex <codex@elphel.com>
-
Andrey Filippov authored
Co-authored-by:Codex <codex@elphel.com>
-
Andrey Filippov authored
Co-authored-by:Codex <codex@elphel.com>
-
Andrey Filippov authored
CLAUDE: leanMeasure - drop the just-added JCuda Java-oracle fallback branch (Andrey's ruling: fallbacks only where free) The dual-path else-branch added earlier today (f8df8dce) would silently run a second implementation on the JCuda backend - the exact divergence the JNA-migration-keep-it-clean policy avoids. Now: no GPU peak kernel -> loud 'requires the JNA backend' message, scene returns null. NOT a JCuda purge: all pre-existing JCuda code stays (base execCorr2DPeaks null-return, the consolidation CPU bridge, legacy paths); the double kernel and the Java oracle remain as VALIDATION tiers in tests/export capture. mvn package OK. Co-Authored-By:
Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
leanMeasure now measures peaks ON the GPU (corr2D_peak_eig_f via GpuQuad.execCorr2DPeaks, float = the ratified production precision; the double kernel stays the validation tier): per LMA iteration only the small task streams go up and [n_corr][8] peak floats come down - the PD download happens ONLY for debug rendering (-POSE-RT-CORR2D), the pose_corr export capture, or the JCuda fallback (the original Java-oracle loop, kept intact). - GpuQuad: execCorr2DPeaks/setPeakDebias base = null/false (JCuda -> Java fallback); PEAK_ROW_FLOATS contract constant. - GpuQuadJna + TpJna: tp_proc_exec_corr2d_peak(use_float)/get_peaks/ set_peak_debias bindings. - TDCorrTile: convertTDtoPDInPlace split - fetchNormalizedPD is now the optional D2H half. - CuasPoseRT.leanMeasure: normalize in place -> float peak kernel -> map rows by packed corr index (valid==0 = kernel reject == oracle null); de-bias uploaded as the float array when pose_debias > 0; once-per-program 'GPU peak kernel active' console line. - PoseCorrExport.iterGpuPeaks: the production float rows land in the case (expected_gpu_peaks_it<k>, corr_indices order) = the TOL-0 peak tier; test_pose_corr_jna compares its float replay bit-exactly when present (tile_processor_gpu companion commit). mvn package OK; CuasTD headless self-test ALL PASSED; run_cases.sh ALL PASS (pre-hookup case: gpu_peaks buffer absent -> skipped gracefully). Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
- 14 Jul, 2026 3 commits
-
-
Andrey Filippov authored
New KEY_DIRS entry (index 12, same pattern as cuasSynth/cuasNoise): SET casesFile <path> in a scene-sequence .list names the GPU-test case manifest (tile_processor_gpu run_cases.sh reads the same SET). A FILE key: exempt from the auto-mkdirs branch; resolved vs rootDirectory and recorded in this.casesFile (informational for now - reserved for in-program use). Parses cleanly instead of the '*********** Unknown SET' console warning. Companion to tile_processor_gpu edc6c4a. mvn compile OK. Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
Companion to tile_processor_gpu 72e2caf (cases.list + run_cases.sh). Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
CLAUDE: 3-C rung 2 - 15-arg peak contract in the lean oracle, FZ-norm in place, pose_corr checkpoint-2 export Andrey's ruling 07/13/2026 (frozen GPU contract = 15-arg getMaxXYCmEig superset; recentering runtime knob; de-bias optional, default off): - CuasRtParameters: NEW 'CUAS RT' knobs pose_recenter (recentering passes, 0 = validated single-pass baseline) + pose_debias (window-autocorr envelope de-bias fraction, 0 = off); corr-xml _curt_pose_recenter/_curt_pose_debias. - CuasPoseRT.leanMeasure: peak measurement switched to the 15-arg getMaxXYCmEig (eig_fast2x2=true = the contract's closed-form eigen); windowAutocorrDebias() = the single source of the de-bias array (Java oracle, export case, JNA host). - TDCorrTile.convertTDtoPDInPlace: corr2D_normalize runs on the inter corr TD buffer where execCorr2D_inter_TD left it (NULL weights == the repack path's uniform 1.0 -> bit-identical PD); the TD D2H->repack->H2D round trip is gone from the lean chain on both backends. - PoseCorrExport: checkpoint 2 in the same case - expected_corr_pd (GPU-produced normalized PD, the tol-0 target for the in-place replay), expected_peaks (double Java oracle incl. weak-peak rejects as NaN rows), contract params + optional debias array in the manifest; compareResults round-trips corr_pd/peaks when the C++ test writes them. mvn -DskipTests clean package OK; C++ side: tile_processor_gpu same-day commit (corr2D_peak_eig + tests, synthetic gate PASS, regressions PASS). Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
- 13 Jul, 2026 12 commits
-
-
Andrey Filippov authored
Backward step from the first two known stored poses (prev_pose/prev_ts pre-initialized before the loop; the in-loop rate code is untouched): the seed scene's rate becomes exactly (stored[next]-stored[first])/dt instead of the zero-rate special case that left scene 0 with mb=(0,0) and the uncompensated v*tau bias. Using a difference of actual poses avoids any hand-derived rotation rate and its sign-convention risk. In RT production the continuous stream always has a real previous frame; this seam also covers stream (re)starts, where the nominal-rotation config can feed the same prev_pose/prev_ts initialization. Deliberate consequence: the next full-sequence run is NOT digit-identical to the 07/13 baseline in scene 0 (expected equal or better - the seed previously carried the v*tau bias). Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
Measured on the first real case: an offline nvcc build cannot be bit-exact vs the NVRTC-JIT production module (FMA/codegen divergence) - the direct -G binary is the stepping companion; the NVRTC-module replay (jna/test_pose_corr_jna) PASSed bit-exact @tol 0, all 4 iterations. Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
CLAUDE: 3-C rung 1 - pose_corr kernel-test export (checkpoint 1 = raw TD corr after correlate2D_inter) curt.kernel_test dropdown entry pose_corr: runs the normal lean pose sequence with a static armed capture (PoseCorrExport) that records, for the FIRST fitted scene, every LMA iteration's task streams exactly as the GPU received them (pre-offsets, task|511) and as the consolidation flattened them (post-offsets, disp_dist tail zero), the conditioned 16-sensor images exactly as uploaded (hook in conditionSceneToGpuInner - the data never lands in QuadCLT), geometry/correction-vector floats, aberration-kernel flatten, the four LPF/HPF constant payloads, the resident center TD (gpu_clt_ref cam 0) and the expected packed corr indices + raw TD correlation (captured right after execCorr2D_inter_TD, before FZ-normalize = the rung-2 boundary). The sequence stops early once the case is written; the TILE-CALIB save is additionally gated on !captureDone() so a truncated max-over-scenes calibration can never be written, and kernelTest refuses to run without an existing -POSE-RT-TILE-CALIB (the bootstrap FULL pass must never be capture- truncated). Requires pose_lean+pose_raw ON, pose_stored/pose_full OFF. C++ side: tile_processor_gpu tests_bin/test_pose_corr --data <case> --tol 0 (newly exercises calculate_tiles_offsets + correlate2D_inter; results/ are saved reordered into oracle index order for the Java round-trip compare). Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
CLAUDE: 3-A3 fix - pure border-ring interior gate (morphological shrink annihilated the patchy selection) First attempt (8fb0eea4) shrank the finite-calibration mask morphologically - but the calibration is NaN wherever a tile was not STRENGTH-selected (whole sky + scattered terrain holes, ~21% finite density), so a 2-tile 8-dir shrink left ~2 tiles per scene: num=2 fits, dstored 6-10 px, LMA failures (07/13 run, killed). Andrey's ruling: pure border ring - the OOB-missing band is geometrically confined to the frame border (margin-dropped ring 1-2 tiles + partial-OOB soft band 12 px = 1.5 tiles), so excluding tiles within curt.pose_shrink (default now 4) tiles of the array border covers hard+soft+slack with zero collateral on interior strength holes. No TileNeibs, no morphology. Dialog label now "Pose tile selection border ring (tiles)"; key _curt_pose_shrink unchanged. Co-Authored-By:
Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
Tile selection (deriveSelection): new interior gate per Andrey's 07/13 ruling - usable = finite calibration (measured in EVERY scene) shrunk by curt.pose_shrink tiles (TileNeibs 8-dir, default 2; array-border ring cleared explicitly). Excludes the partial-OOB band (soft margin 12 px = 1.5 tiles) so every selected tile keeps all 16 sensors interior at every scene pose - enables the fixed per-sequence GPU tile list with the consolidation OOB pass bypassed by host policy. leanMeasure: sort task streams by (tileY, tileX) - setInterTasks* fill from worker threads, so tile order was nondeterministic run-to-run; the fixed selection + sort = the static task-stream contract for the pose_corr checkpoint (rung 1). New dialog knob (CUAS RT tab): "Pose tile selection shrink (tiles)" (curt.pose_shrink, corr-xml _curt_pose_shrink). Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
- pose_max_lma: inner LMA cap for the lean pose only (0 = legacy imp.max_LMA, which stays ~25 for flying-camera applications). 1 validated 07/13: static 4x1 shape, dstored RMS 0.0350/0.0377/0.0213 == unlimited-inner run. - Verbosity (Andrey): scene line now carries cyc=N and mb=(x, y); the separate 'CuasPoseRT cycles:' trace and per-scene uniform-MB lines print only at curt.pose_lma_debug >= 1 (investigation closed; QC not-settled line stays). Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
Root cause of the eigen-ON 3x slow pose convergence (probed synthetically): pedestal-included covariance inflates the peak eigen lambdas; sqrt(lambda) reaches imp.eig_max_sqrt (6) where setEigenTransform's k=max(0,1/sqrt(l)-1/6) ZEROES the tile's measurement components - blur-wide tiles (sigma ~2.5-3 px, the lean consolidated-average x center regime) contribute nothing and the solve limps on the few sharp tiles. Companion zero-build retune: raise imp.eig_max_sqrt 6 -> ~20 (dialog) when re-enabling eigen. Solver algebra verified consistent (jt, both Y-Fx variants, WJtJ share the transform). Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
Per outer cycle: RE-MEASURED pure RMS (prepareLMA, after re-correlation) > MODEL-PREDICTED pure RMS (runLma, after the solve). Jacobian/chain-rule error signature (Andrey's hypothesis): solved_n low but meas_{n+1} bounces back up - the model overpromised and re-correlation takes it back. Healthy damping: meas_{n+1} ~ solved_n, both creep down. Zero extra computation - both values already existed inside IntersceneLma. Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
New int knob (0 = quiet): >=2 passes the level into the inner runLma so its existing per-step line prints (good/done flags, full/pure RMS, lambda), with a CuasPoseRT header attributing each block to its scene + outer cycle; 3-4 = the solver's deeper dumps. Shared IntersceneLma untouched. Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
Root cause of the 6-13 outer cycles (Andrey's diagnosis, confirmed in code): the inner runLma restarts at ilp.ilma_lambda=0.1 EVERY outer measure<->solve cycle, and the 0.1%-improvement inner exit fires while steps are still lambda-limited -> outer loop under-relaxes (~0.8/cycle decay). New curt.pose_lambda (default 0.001, 0 = legacy ilma_lambda) starts the inner solve near-Gauss-Newton for the near-linear overdetermined 3-angle problem. Trace line now also logs inner runLma iterations per outer cycle + lambda0. 07/12 21:56 run (legacy convergence + uniform MB): dstored RMS az/tilt/roll 0.1416/0.0777/0.0983 vs per-tile-MB baseline 0.1355/0.0765/0.1005 = uniform MB VALIDATED (A1); 0 degenerates; outer cycles mean 7.4, max 13 @ lambda 0.1. Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
- uniformMotionBlur: representative = defined reference tile nearest the frame center passing getMotionBlur's own gates (mirrored locally; the synthetic averaged frame-center point failed SILENTLY on every scene in the 07/12 run). Degenerate fallback now prints the tried point + rates (self-explaining). - leanFitScene: per-scene 'CuasPoseRT cycles: ... dATR/cycle = ...' trace line (fixed AND legacy modes) - the convergence-trajectory data for the open 'why does azimuth need so many cycles' investigation (3 cycles: az RMS 0.5209; 6 cycles: 0.1805; legacy baseline: 0.1355 px). Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
Phase A items 1-2 of the pose GPU-migration plan (Andrey's design 07/12/2026): - curt.pose_mb_uniform (default ON): ONE motion-blur vector per scene shared by all tiles - constant-rpm CUAS flow is uniform up to the roll component (small) and wobble (2nd degree). Same Jacobian-times-rates as per-tile getMotionBlur, evaluated at the frame center and broadcast; rates = finite differences of predicted poses, unchanged. OFF = legacy per-tile path (A/B knob). - curt.pose_cycles (default 3): EXACTLY N measure<->solve cycles, no convergence early exit (static GPU launch shape); convergence delta kept as QC printout (flags scenes missing the legacy exit_change_atr). 0 = legacy convergence exit. Validation = pose_test run vs 07/12 JNA baseline (497/497, az/tilt/roll RMS 0.1355/0.0765/0.1005 px) - policy A/B by pose quality, not bit-exactness. Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
- 12 Jul, 2026 3 commits
-
-
Andrey Filippov authored
Use the frozen v1 kernel chain in the program instead of the Java CPU code (roadmap step 4, JNA-only per Andrey's 07/12/2026 ruling): - GpuQuad.execConsolidateSensorsTD: base hook, returns false (JCuda backend keeps the CPU bridge - no JCuda launch code for new kernels). - GpuQuadJna override -> TpJna.tp_proc_exec_consolidate: on-device chain, TD never leaves the GPU (zero-copy; only flattened TpTask streams cross); validated bit-exact vs the real-scene avg_td_oob oracle case (tile_processor_gpu jna/test_proc_consolidate, max|diff|=0). - CuasTD.consolidateToSlot0: shared bridge - GPU-first, CPU fallback now OOB-mask-capable (oobSensorMasks + masked consolidateSensorsTD), so both backends produce the v1-filtered average. - CuasPoseRT.leanMeasure + CuasRender.renderSceneVirtual: task sets hoisted out of the MB/no-MB branches and passed to the bridge (replaces the getCltData -> consolidateSensorsTD -> setCltData(0) round-trip). - CuasRtParameters: new curt.oob_soft / curt.oob_hard (defaults = CuasTD.OOB_SOFT/HARD_DEFAULT 12/8, frozen spec; 0/0 = v0 unfiltered A/B knob), new dialog group under CUAS RT; corr-xml keys _curt_oob_*; consumed by the bridge at both call sites and by the avg_td_oob export (replaces hardcoded defaults in CuasRT.kernelTest). Verified: mvn package; CuasTD headless self-test ALL PASSED (exit 0). Co-authored-by:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
CuasTD.oobSensorMasks() = the contract oracle of the future index_consolidate (pass 1) + OOB priority (pass 2) kernels: input TpTask[2][] (MB pair, [1] may be null = no-MB, matching setInterTasksMotionBlur), sets matched by txy lookup; per tile - present (task!=0) in EVERY provided set, else mask 0; per sensor - depth = min over sets of tile-center distance to nearest frame edge; depth<hard always skipped, any sensor >=soft -> only those, else hard survivors as last resort; NaN xy excluded; margins 0 = tier off (frozen spec soft~12/hard~8 @4e0db8b). consolidateSensorsTD(fclt,counts,masks,colors): mask-gated average, mask 0 = whole-tile NaN poison; null masks = bit-exact v0 (2-arg delegates). AvgTdExport.exportOob(): case carries RAW flattened task streams (exact GPU struct layout, both sets) + margins in manifest + expected masks/ avg/counts. KERNEL_TESTS += avg_td_oob; CuasRT.kernelTest case (set 1 = null until the RT-chain MB wiring). Headless self-test (java -cp ... cuas.rt.CuasTD): 18/18 PASSED (tiering, MB drop, no-MB mode, NaN xy, poison, v0 bit-exact repro). mvn -DskipTests clean package: OK. Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
Andrey Filippov authored
Replaces the would-be per-kernel checkbox sprawl (Andrey 07/12 design): - CuasRtParameters: KERNEL_TESTS registry {none, avg_td} + kernel_test String param (addChoice, corr-xml _curt_kernel_test, unknown values sanitized to none); one dropdown entry per kernel in the 2c+ ladder. - CuasRT.diagnostics(): kernel_test != none -> EXCLUSIVE kernelTest() dispatch, nothing else runs that pass. - kernelTest() avg_td case = the AvgTdExport call site (settles the open pick): conditioned image_data of the GPU-bound scene -> uniform-grid convert -> CPU oracle + testdata case export (<model>/testdata/avg_td, incl. per-sensor TpTask XY for the OOB soft/hard-margin stage) -> validateConsolidation; imports+compares C++ results/ when present, else prints the exact tests_bin command to run. - CuasMotion.convertFromData: overload with tasks_out (old signature delegates) so the export gets the conversion TpTask grid. mvn -DskipTests clean package: OK. Run validation in Eclipse = Andrey's. Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
-
- 11 Jul, 2026 3 commits
-
-
Andrey Filippov authored
Per-segment absolute registration of the per-tile terrain models (*_SZXY.tiff: S/Z/X/Y slices) against a 3DEP DEM using the ground_planes geodetic anchor (lat/lon/alt + qenu with the validated axis adapter perm(2,0,1) signs(1,-1,-1)). Reports vertical offset (= IMS altitude error trace; observed -43..+19 m across passes), optional dx/dy/scale search, robust 2x25% trim. Validated on the pond segment 1763233023_625897: placement rms 0.17 m at scale 1.0; scale fitting documented as valid only on temporally stable relief (the 2020-flooded pond trims itself out). Co-authored-by:Claude <claude@elphel.com>
-
Andrey Filippov authored
Dense graveyard model triangulated with our poses puts the ground plane at z median -77.5 XML-units vs 77.4 m AGL from ELEV_GND - the earlier 'SfM-scale' caveat was an analysis artifact (wrong sub-camera baseline assumption), retracted. Co-authored-by:Claude <claude@elphel.com>
-
Andrey Filippov authored
Exports *-INTERFRAME.corr-xml scene poses as a COLMAP text sparse model (PINHOLE camera, empty points3D) so point_triangulator/OpenMVS can use our IMS/interscene poses with no SfM pose estimation - the FOPEN step-3 path for vegetation scenes where COLMAP's own mapper fails. Convention verified against the 2026-07-10 graveyard run (ref 1763232420_274928): R = diag(1,-1,-1) @ (Ry(az)Rx(tilt)Rz(roll))^T, t = -R C. Fixed-pose triangulation on the corrected NADIR-MERGED-RECTILINEAR renders gives 0.453 px mean reprojection (COLMAP free mapper: 0.351 px on the same images). Co-authored-by:Claude <claude@elphel.com>
-
- 10 Jul, 2026 1 commit
-
-
Andrey Filippov authored
The RECTILINEAR nadir pass multiplied sampling coordinates by getRByRDist() (distorted->ideal), but sampling positions must be moved to where the ideal ray lands in the distorted image - the FORWARD distortion getRDistByR(), same direction as GeometryCorrection.getImageCoordinates(). The old code ADDED the common radial distortion to the output instead of removing it. Evidence (graveyard ref 1763232420_274928, flat constant-disparity terrain where translation flow must be uniform for a true pinhole image): - plain NADIR-MERGED edge/center flow ratio 0.965 (expected 0.954 from the calibration polynomial: ~4.8 px barrel at the edge), - old RECTILINEAR 0.952 - worse than uncorrected, - COLMAP self-calibrated f=1003/k1=-0.385 on the old rectilinear stack. Co-authored-by:Claude <claude@elphel.com>
-