Add per-element Yagi control (Advanced Mode) - #6
Merged
Conversation
A Yagi was auto-designed only: element_count drove rules-of-thumb lengths and
0.20-wavelength spacing. This adds optional per-element geometry.
* model/antenna.py — YagiElementRole + YagiElement (role, length, boom
position), and an optional YagiModel.elements. When set it overrides the
auto-design; validated for exactly one driven element, at most one
reflector, >= 2 elements, and distinct positions. element_count is then
ignored, so a custom beam is not capped at six. director_count and a new
total_element_count cover both paths.
* cards/yagi.py — refactored around resolve_yagi_elements(): auto-design or
explicit, both producing the same element list. auto_yagi_elements() is
exposed so the UI can seed the editor. The 1=driven / 2=reflector /
3+=director tag scheme is preserved, so per-element loading still targets
the right wire and the feed stays on the driven element.
* ui/yagi_elements_editor.py — an add/remove editor (role, length, boom
position), shown in a checkable "Customise Yagi elements" Advanced box.
Enabling it seeds from the auto-design so the user tweaks a working beam.
* main_window.py — the box, build-model branch, capture/restore, and unit
propagation.
Existing Yagi and per-element-loading tests are unchanged (auto-design path is
byte-for-byte the same). New tests cover the model rules, the auto/explicit
resolver, the preserved tags, a custom NEC solve, and the UI seed/build/
round-trip. Suite 493 -> 504.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A Yagi was auto-designed only —
element_countdrove rules-of-thumb lengths (reflector 1.05×, directors 0.95×) and 0.20 λ spacing. This adds optional per-element geometry in Advanced Mode: set each element's role, length, and boom position.This is the prerequisite the parked Yagi designer wizard was waiting on.
How
model/antenna.py—YagiElementRole+YagiElement(role, length, boom position), and an optionalYagiModel.elements. When set it overrides the auto-design; validated for exactly one driven, at most one reflector, ≥ 2 elements, distinct positions.element_countis then ignored, so a custom beam isn't capped at six.director_count+ a newtotal_element_countcover both paths.cards/yagi.py— refactored aroundresolve_yagi_elements(): auto or explicit, both producing one element list.auto_yagi_elements()is exposed so the UI can seed the editor. The1=driven / 2=reflector / 3+=directortag scheme is preserved, so per-element loading still targets the right wire and the feed stays on the driven element.ui/yagi_elements_editor.py— an add/remove editor (role, length, boom position) in a checkable "Customise Yagi elements" Advanced box. Enabling it seeds from the auto-design so the user tweaks a working beam rather than an empty table.main_window.py— the box,_build_modelbranch, capture/restore, unit propagation.Compatibility
The auto-design path is byte-for-byte unchanged — existing
test_yagi.pyandtest_loaded_yagi.pypass untouched. (One UI note: the editor's length field shows cm precision, so enabling "customise" then solving without edits can shift a parasitic-sensitive beam by a few tenths of a dB versus the full-precision auto-design — faithful to the entered lengths, not a bug.)Tests
tests/test_yagi_per_element.py(+11): the model validation rules, the auto/explicit resolver, the preserved tag scheme, a custom NEC solve, and the UI seed/build/round-trip + editor min-2. Suite 493 → 504, green locally and in a clean CI-equivalent venv.Follow-up
With per-element control in place, a Yagi designer wizard (target gain / boom length → element table) is now buildable on the existing wizard framework.
🤖 Generated with Claude Code