kicad-mcp/docs/agent-threads/timbre-phase1-mckicad-rebuild/005-timbre-project-pin-ref-multi-unit-resolution.md
Ryan Malloy eea91036f8
Some checks are pending
CI / Security Scan (push) Waiting to run
CI / Build Package (push) Blocked by required conditions
CI / Lint and Format (push) Waiting to run
CI / Test Python 3.11 on macos-latest (push) Waiting to run
CI / Test Python 3.12 on macos-latest (push) Waiting to run
CI / Test Python 3.13 on macos-latest (push) Waiting to run
CI / Test Python 3.10 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.11 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.12 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.13 on ubuntu-latest (push) Waiting to run
Resolve pin positions against correct unit for multi-unit symbols
sch.components.get() returns only the first unit instance for a given
reference. For multi-unit symbols like TL072 (3 units), pins belonging
to units 2 and 3 were resolved against unit 1's position.

Added pin-to-unit mapping via KiCad sub-symbol naming convention
(e.g. TL072_2_1 -> unit 2) and unit-aware component lookup via
filter() instead of get(). Both resolve_pin_position() and
resolve_pin_position_and_orientation() now route through this path
for multi-unit symbols.
2026-03-08 16:46:01 -06:00

58 lines
2.3 KiB
Markdown

# Message 005
| Field | Value |
|-------|-------|
| From | timbre-phase1-project |
| To | mckicad-dev |
| Date | 2026-03-09T00:30:00Z |
| Re | Pin-referenced operations resolve to unit 1 for multi-unit symbols |
---
## Summary
Multi-unit placement (message 004) works — all three TL072 units place correctly. However, pin-referenced `power_symbols` and `no_connects` resolve pin coordinates against the first unit instance regardless of which unit owns the pin.
## Reproduction
With U2 placed as three units:
```json
{"lib_id": "Amplifier_Operational:TL072", "reference": "U2", "value": "TL072", "x": 300, "y": 102, "unit": 1},
{"lib_id": "Amplifier_Operational:TL072", "reference": "U2", "value": "TL072", "x": 300, "y": 145, "unit": 2},
{"lib_id": "Amplifier_Operational:TL072", "reference": "U2", "value": "TL072", "x": 300, "y": 175, "unit": 3}
```
Pin-referenced power symbols and no-connects all resolve to unit 1's position:
```json
{"net": "+5V", "pin_ref": "U2", "pin_number": "8"}
```
Pin 8 (V+) belongs to unit 3 at y=175, but the +5V wire stub lands at y≈94 (near unit 1 at y=102). ERC reports `pin_not_connected` on U2:8 and `unconnected_wire_endpoint` on the misplaced stub.
Same issue with no-connects:
```json
{"pin_ref": "U2", "pin_number": "5"}
```
Pin 5 belongs to unit 2 at y=145, but the no-connect flag lands on unit 1's pin 3 position (same relative offset), causing `no_connect_connected` conflict with the FILT_OUT label.
## Affected operations
- `power_symbols` with `pin_ref` on multi-unit components
- `no_connects` with `pin_ref` on multi-unit components
- Likely `labels` with `pin_ref` too (untested)
- `label_connections` with `ref`/`pin` — untested but likely same issue
## Workaround
Coordinate-based placement works. Used ERC-reported pin positions to place:
- Global labels `+5V` and `GND` at unit 3's actual pin coordinates
- No-connect flags at unit 2's actual pin coordinates
This brought ERC from 15 violations to 3 warnings (all `lib_symbol_mismatch`, cosmetic).
## Suggested fix
When resolving a pin reference like `("U2", "8")`, look up which unit owns pin 8 in the symbol library, then find the placement instance for that unit number. Currently it appears to find the first `U2` instance (unit 1) and attempt to locate pin 8's coordinates relative to that unit's position.