Skip to content

fix(property-positioning): Add positioning rules for 6 IC components (#176)#177

Open
shanemmattner wants to merge 2 commits into
mainfrom
fix/ic-property-positioning
Open

fix(property-positioning): Add positioning rules for 6 IC components (#176)#177
shanemmattner wants to merge 2 commits into
mainfrom
fix/ic-property-positioning

Conversation

@shanemmattner
Copy link
Copy Markdown
Contributor

@shanemmattner shanemmattner commented Nov 18, 2025

Summary

Implements dynamic property positioning that loads positions from KiCAD symbol library files instead of using hard-coded rules. This provides a generic, scalable solution that works for ALL components automatically.

Problem

kicad-sch-api was missing property positioning rules for IC components. When generating schematics with ICs, the library fell back to the resistor pattern (offset +2.54mm, -1.27mm) which is completely inappropriate for large ICs like ESP32-WROOM-32 (40mm × 86mm).

Original approach: Hard-code rules for each IC (not scalable)
New approach: Load positions dynamically from .kicad_sym files (works for everything)

Solution

Generic Dynamic Loading Architecture

Property positions are now extracted from KiCAD symbol library files (.kicad_sym) during symbol loading and cached for performance.

Flow:

  1. Symbol library cache parses .kicad_sym files
  2. Extracts (property "Reference" (at x y rotation) ...) from each symbol
  3. Stores positions in SymbolDefinition.property_positions dict
  4. get_property_position() queries symbol library FIRST
  5. Falls back to hard-coded rules only if symbol not found

Benefits of Dynamic Approach

Works for ALL components - Not just the 6 tested ICs, but thousands of KiCAD components
Zero maintenance - Positions automatically match KiCAD's native placement
Infinitely scalable - New components work without code changes
Backward compatible - Hard-coded rules remain as fallback

Changes

Core Implementation

kicad_sch_api/library/cache.py:

  • Added property_positions: Dict[str, Tuple[float, float, float]] to SymbolDefinition
  • Added _extract_property_position() method to parse (at x y rotation) from properties
  • Extract property positions during symbol parsing in _parse_kicad_symbol_file()

kicad_sch_api/core/property_positioning.py:

  • Added _get_offset_from_symbol_library() to query symbol cache
  • Updated get_property_position() to try symbol library FIRST, fall back to hard-coded rules
  • Removed hard-coded IC rules (no longer needed - positions loaded dynamically)
  • Hard-coded rules for basic components (R, C, L) remain as fallback

tests/unit/test_ic_property_positioning.py:

  • 15 tests verify dynamic loading from symbol libraries
  • Tests confirm positions match KiCAD symbol library files
  • Tests verify symbol library queried before fallback rules

Testing

All 15 dynamic loading tests pass:

ESP32-WROOM-32:  Reference (-12.70, +34.29), Value (+1.27, +34.29) ✅
74LS245:         Reference (-7.62, +16.51), Value (-7.62, -16.51) ✅
MAX3485:         Reference (-6.98, +13.97), Value (+1.91, +13.97) ✅
AMS1117-3.3:     Reference (-3.81, +3.17), Value (0.00, +3.17) ✅
TPS54202DDC:     Reference (-7.62, +6.35), Value (0.00, +6.35) ✅
AO3401A:         Reference (+5.08, +1.91), Value (+5.08, +0.00) ✅

All existing tests pass:

  • 15 rotation-aware positioning tests ✅
  • No regressions in existing functionality ✅

Impact

Before (Hard-coded approach):

  • ❌ Warnings for missing IC rules
  • ❌ Only worked for specific components
  • ❌ Required manual rule addition for each component
  • ❌ Maintenance burden

After (Dynamic loading):

  • ✅ No warnings - positions loaded from symbol libraries
  • ✅ Works for ALL KiCAD components automatically
  • ✅ Zero maintenance - positions always match KiCAD
  • ✅ Scales infinitely - future components work automatically

Example: How It Works

When generating a schematic with ESP32-WROOM-32:

  1. Symbol cache loads RF_Module.kicad_sym
  2. Parses symbol and extracts property positions:
    (property "Reference" "U"
        (at -12.7 34.29 0)  ← Extracted and cached
    
  3. Stores in cache: property_positions["Reference"] = (-12.7, 34.29, 0)
  4. Property positioning queries cache and gets exact KiCAD position
  5. Result: Property text placed exactly where KiCAD would place it

Related


🤖 Generated with Claude Code

Shane Mattner and others added 2 commits November 17, 2025 22:10
Adds property positioning rules for IC components that were falling back
to the resistor pattern, causing property text to be placed incorrectly.

Components added:
- RF_Module:ESP32-WROOM-32 (large RF module, 40mm × 86mm)
- 74xx:74LS245 (SOIC-20W level shifter)
- Interface_UART:MAX3485 (SOIC-8 transceiver)
- Regulator_Linear:AMS1117-3.3 (SOT-223 LDO)
- Regulator_Switching:TPS54202DDC (SOT-23-6 buck converter)
- Transistor_FET:AO3401A (SOT-23 P-FET)

Property positions extracted from KiCAD symbol library files and added to
POSITIONING_RULES dictionary in property_positioning.py.

Changes:
- kicad_sch_api/core/property_positioning.py: Added 6 IC positioning rules
- tests/unit/test_ic_property_positioning.py: 23 unit tests for IC rules
- docs/prd/ic-property-positioning-prd.md: PRD documentation

Fixes #176

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Completely rewrote property positioning to load positions dynamically from
KiCAD symbol library files instead of using hard-coded rules. This provides
a generic, scalable solution that works for ALL components, not just specific ICs.

**How it works:**
1. Symbol library cache extracts property positions from .kicad_sym files
2. Property positions stored in SymbolDefinition.property_positions dict
3. get_property_position() queries symbol library FIRST, falls back to hard-coded rules
4. No hard-coded rules needed for IC components - all loaded dynamically

**Benefits:**
- Works for ANY component in KiCAD symbol libraries (thousands of components)
- No maintenance burden - positions automatically match KiCAD's native placement
- Scales infinitely - new components work automatically
- Hard-coded rules remain as fallback for compatibility

**Changes:**
- kicad_sch_api/library/cache.py:
  - Added property_positions field to SymbolDefinition
  - Added _extract_property_position() method to parse (at x y rotation)
  - Extract property positions during symbol parsing

- kicad_sch_api/core/property_positioning.py:
  - Added _get_offset_from_symbol_library() function
  - Updated get_property_position() to query symbol library first
  - Removed hard-coded IC rules (no longer needed)

- tests/unit/test_ic_property_positioning.py:
  - Rewrote tests to verify dynamic loading
  - 15 tests verify IC positions loaded from symbol libraries
  - All tests pass ✅

**Testing:**
```
ESP32:    Reference (-12.70, +34.29) ✓
74LS245:  Reference (-7.62, +16.51) ✓
MAX3485:  Reference (-6.98, +13.97) ✓
AMS1117:  Reference (-3.81, +3.17) ✓
TPS54202: Reference (-7.62, +6.35) ✓
AO3401A:  Reference (+5.08, +1.91) ✓
```

All positions match KiCAD symbol library files exactly.

Fixes #176

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing IC property positioning rules causes incorrect text placement

1 participant