mirror of
https://github.com/NawfalMotii79/PLFM_RADAR.git
synced 2026-05-22 15:51:58 +00:00
Audit of how the ADAR1000 is actually steered in production. Reproduces
main.cpp:initializeBeamMatrices() (PHASE_DIFFERENCES, matrix1, matrix2,
vector_0) verbatim in Python and runs the patterns through the same array-
factor pipeline used for the firmware-vs-correct comparison.
Key findings — context for fixing the setBeamAngle() bug without regression:
1) setBeamAngle() is DEAD CODE in production. grep for callers across the
whole tree returns only the definition itself (ADAR1000_Manager.cpp:215),
the header declaration (line 58), and one comment in ADAR1000_AGC.cpp
referencing the sign convention. main.cpp does NOT call it. The 4-phase
broadcast bug exposed in commit 2f4d45c is therefore latent, not active.
Fixing setBeamAngle() has zero risk of changing production behaviour.
2) Production path: initializeBeamMatrices() (main.cpp:467) computes
matrix1[bp][el] = degTo7Bit(el * phase_differences[bp]) for all 16
elements properly (no 4-broadcast). main.cpp's runRadarPulseSequence()
then calls setCustomBeamPattern16(matrix1[bp], TX/RX) → 16-element
progressive phase reaches the chips correctly. This part is right.
3) HOWEVER — the production tables themselves have separate concerns:
a) SIGN CONVENTION MISLABEL: comment says "matrix1 = positive steering
angles" but math+sim show positive phase_diff steers to NEGATIVE θ.
matrix1[bp=0] (phase_diff=+160°) → actual peak -62°.
Either the comment is wrong, or hardware wiring inverts what's
labeled "+elevation" — needs a hardware test to confirm.
b) ASYMMETRIC INDEXING: matrix2 uses phase_differences[bp + 16] which
gives matrix2[bp=0]=-3.4° while matrix1[bp=0]=-62°. So as bp goes
0→14, matrix1 zooms in toward broadside (-62°→-4°) while matrix2
zooms out (+4°→+62°) — they're NOT mirror images. Symmetric mirror
would be phase_differences[30 - bp].
c) NON-UNIFORM COVERAGE: phase_differences[] follows 160/n pattern
(160, 80, 53.33, 40, 32, ...). After sin⁻¹ this gives 17 unique
scan angles spanning -62°..+62° with a 36° GAP between -62° and
-26°, but 2° spacing near broadside. May be intentional (oversample
near nominal target line) but flag for confirmation.
d) WORST-CASE SLL at extreme scan (matrix1[0] → -62°): only -2.9 dB.
Main beam barely clears sidelobes — typical at near-grazing scan
due to embedded element pattern roll-off.
e) initializeBeamMatricesWithSteeringAngles() (main.cpp:1611) is also
dead code. It computes the same thing two different ways. Safe to
remove or merge during cleanup.
Recommendation for fix sequence (low → high risk):
i. Fix setBeamAngle() to call setCustomBeamPattern16() with proper
16-element table (or mark deprecated). Zero production risk.
ii. Add unit test that runs setBeamAngle and verifies the resulting
phase codes match a known-good 16-element progression.
iii. Update the misleading comments in initializeBeamMatrices() to say
what the matrices ACTUALLY do (the sign convention).
iv. Hardware test BEFORE touching matrix2 indexing or phase_differences
distribution — these may be deliberately tuned to platform mounting.