Repository navigation
feat(schematic): join nearby pins under one power symbol - #857
Draft
pauliuszaleckas wants to merge 2 commits into
Draft
pauliuszaleckas wants to merge 2 commits into
pauliuszaleckas wants to merge 2 commits into
Conversation
Copying a pin's endpoint into x/y and picking a rotation by hand is where mistakes slip in (mixelpixx#727). add_power_symbol now also takes reference + pin_number: the symbol lands on the pin's endpoint, unsnapped, and faces away from the body unless rotation is given. Mixed or half-given selectors, missing pins and pins two symbols share are refused before writing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
batch_add_power_symbol ties a list of pins to one rail the way a sheet is drawn by hand: pins facing the same way on one row, within max_gap of a neighbour, get a stub each, a bar and a single symbol. A group whose wires would touch anything else is left apart and says why. add_power_symbol on a pin no longer adds a second symbol when the pin is already on that rail, by net identity, so stacked pins and pins wired to a symbol are covered (mixelpixx#856). Co-Authored-By: Claude Opus 5.5 <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.
Summary
Konnect places one power symbol per pin. Pins that sit close together each get their own symbol: an MCU's VSS and VSSA, or a row of decoupling caps. Their arrows overlap and the values run together (
GNDGND). Stacked pins get a duplicate symbol hidden exactly behind the first.batch_add_power_symbol(insch_batch). It ties a list of pins to one rail the way a sheet is drawn by hand. Pins that face the same way, end on one row and lie withinmax_gapof a neighbour get a stub each, a bar across the stubs, and one power symbol on the bar. Every other pin gets a symbol on its endpoint.add_power_symbolon a pin no longer adds a second symbol when the pin is already onpower_net. It writes nothing and reportsalready_connected.Closes #856
Approach
resolve_power_pin, so a missing or ambiguous pin refuses the whole call before anything is written. Pins sharing an endpoint, such as the VSS pins of an STM32, fold into one point.ExistingPowerasks the net graph whether the pin's net is apower_netsymbol's net. It comparesroot_atidentities, not names. A symbol reached through a wire therefore counts, as well as one on the pin itself. When there are several, the nearest is reported, because every same-named symbol on a sheet is one net.max_gap.stub_lengthoutward from its pin, the bar joins the stub ends, and the symbol sits on the middle stub's end. Junction dots go where a stub meets the bar mid-span, and where a new power pin lands mid-wire.not_joined_reasonnames the obstacle. Without this check a bar could short an unrelated net.Schematic::overwrite. The readback reloads the file and checks every symbol throughplaced_component_readback, every wire by UUID and coordinates, and every junction by position. A mismatch is reported asmutation_outcome_uncertain.Deviations from the issue:
sch_batch, notsch_wiring, becausesch_wiringis at the 20-tool cap (no_toolset_exceeds_max_size).add_power_symbolon U1 pin 35, after a batch had wired the VSS pins to a GND symbol, still added a duplicate.Architectural fit
This reuses
resolve_power_pinandpower_symbol_pinfrom #782,NetGraph(sch_connectivity.rs) for net identity, andfind_t_junctions/pins_mid_segmentfor dots. The symbol-building code fromhandle_add_power_symbolmoved unchanged intoadd_power_symbol_to, so both tools build symbols the same way.sch_batch::error_textbecamepub(crate).Out of scope:
batch_connect_to_net, which still places one label per pin.Branch and dependencies
main381a9a7feat(schematic): join nearby pins under one power symbol381a9a7onto currentmain, force-push, re-run CI, and mark ready.Compatibility and safety
add_power_symbolwithreference+pin_numbernow returns{already_connected: true, power_net, existing_reference, x, y}without writing when the pin is already on the rail. Thex+yform is unchanged, so a caller who wants the duplicate can still place it that way.docs/API_MIGRATIONS.mdgets a new entry, placed above feat(schematic): place add_power_symbol on a named pin #782's. It only adds lines.conflictwhatever pins were named, as for the other placers.symbol_loading_and_erc_preflight_ownership_without_writingnow covers this tool.Validation
Changed tool behavior
power_net,pins: [{reference, pin_number}](minItems 1),max_gap≥ 0 (default 10.16 mm),stub_length> 0 and a multiple of 1.27 (default 2.54 mm).max_gap_decides_who_joinscovers 7.6, 7.62 (inclusive) and 20.32.stale_targetand an ambiguous one isambiguous_target, from #782's resolver. A badstub_lengthor emptypinsisinvalid_argument. Any refusal writes nothing, andrefusals_write_nothingasserts the file is byte-identical..kicad_schis read once (read_consistent), and ownership is checked throughsheet_instance_contextandvalidate_sheet_instance_statebefore any pin is resolved. The power symbol must exist in the sheet or KiCad'spowerlibrary.power:<net>symbols, and touches nothing else. The collision guard keeps every new wire off existing items:BLOCKstays dangling in KiCad's ERC, so it was not joined to GND.mutation_outcome_uncertain.already_connectedand skipped, so no symbols are duplicated;a_stacked_pin_already_on_the_rail_gets_no_second_symbolchecks this.Fixture and oracle
crates/konnect-core/tests/fixtures/power_rows_kicad10.kicad_schwas built through Konnect against stock KiCad libraries and force-resaved withkicad-cli sch upgrade --forceon KiCad 10.0.6. Its README has the provenance, the case table, and KiCad's ERC pin positions, which the tests use as literals.The tests' two calls were run on a copy, and the result was checked with KiCad:
Cases the oracle can only corroborate one way:
BLOCK. Drawn, it would putBLOCKon GND.Negative controls
Run with
cargo test -q --workspace --locked --lib --tests --no-fail-fast, with each guard removed in turn on381a9a7:blockingreturnsNone)a_bar_that_would_touch_a_label_is_not_drawn,a_row_shares_one_symbol_…ExistingPower::atreturnsNone)a_stacked_pin_already_on_the_rail_…,a_pin_wired_to_the_rail_…max_gapsplit (never split a row)a_row_shares_one_symbol_…,max_gap_decides_who_joinsa_row_shares_one_symbol_…(C7.2/C8.2)a_row_shares_one_symbol_…,an_ic_supply_row_…,max_gap_decides_who_joinsa_row_shares_one_symbol_…a_row_shares_one_symbol_…,an_ic_supply_row_…,max_gap_decides_who_joins,a_pin_wired_to_the_rail_…symbol_loading_and_erc_preflight_ownership_without_writingThe ownership test names a pin that does not exist (
C201pin99), so only the ownership-first order reportsconflict.Gate on
381a9a7cargo fmt --all -- --check: cleancargo clippy --workspace --locked --all-targets -- -D warnings: cleancargo test -p konnect-core --locked reliability_contract: 2 passedcargo test --workspace --locked --lib --tests: 2383 passed, 0 failed, 45 ignoredcargo test --workspace --locked --doc: 9 passed, 2 ignoredcargo xtask fix-doc-counts --check: current (21 toolsets, 229 registered, 236 total)CI has not run yet. The branch inherits #782's
docs/API_MIGRATIONS.mdconflict with currentmain(git merge-treeshows only that file), and GitHub starts nopull_requestworkflows on a conflicting PR. The checks will run on the rebuilt branch after #782 merges.Review checklist
upstream/main, has no merge conflicts, and CI passed on this exact head. It does not: it is stacked on feat(schematic): place add_power_symbol on a named pin #782 and will be rebuilt after feat(schematic): place add_power_symbol on a named pin #782 merges.upstream/main, not a release tag (unless this is an approved backport).docs/NAMING_CONVENTIONS.md; public renames include compatibility handling.tool_count,tool-directory.md, DEV.md stats, README count).🤖 Generated with Claude Code