Summary
When a <group pcbX={x} pcbY={y}> contains a large chip (e.g. a 12 ×
12 mm RF module) along with a handful of small siblings (decoupling
caps, pull-ups, etc.), the auto-packer can place the chip itself
many millimetres off-board while the small siblings cluster around
the group anchor. The chip "falls off" instead of dominating the
group.
This was concretely reproducible on our project — an InsightSiP
ISP3080-UX 12×12 mm module landed at X=−56.91 on a 50 mm-wide board
(over 30 mm past the left edge) when its region_mcu group
contained ~10 children. Smaller chips (U_CHG DSBGA-8, U_BUCK
SOT-563, etc.) in groups with 3–5 siblings landed cleanly at the
group anchor in the same run.
Repro
<board width="50mm" height="14mm">
<group name="region_mcu" pcbX={-18} pcbY={0}>
{/* ~10 children competing for the anchor — chip is the largest
but the packer pushes it out instead of pinning it to the
anchor and packing the small parts around it. */}
<chip name="U_RF" footprint={largeModuleFootprint /* 12×12 mm */} />
<capacitor name="C7" capacitance="100nF" footprint="0402" />
<capacitor name="C7b" capacitance="100nF" footprint="0402" />
<capacitor name="C7c" capacitance="100nF" footprint="0402" />
<resistor name="R_RST" resistance="10k" footprint="0402" />
<resistor name="R_SDA" resistance="4.7k" footprint="0402" />
<resistor name="R_SCL" resistance="4.7k" footprint="0402" />
<switch name="SW_RST" />
{/* etc. */}
</group>
</board>
Expected: U_RF lands at (−18, 0) (group anchor); small siblings
pack around it with the configured pcbPackGap clearance.
Actual: U_RF ends up at e.g. (−56.91, −12.72) — off-board by
~32 mm — while several small siblings sit clustered at the group
anchor.
Diagnosis
Likely the largest_to_smallest ordering in calculate-packing's
PackSolver2 places U_RF first into the empty space, then small
parts shoulder it out of position when their candidate scores
prefer the anchor zone. The chip's "won" position is then a
candidate the next-iteration adjustment moves further away.
Workaround we ended up using: hand-pin the chip with explicit
pcbX/pcbY (chip then becomes static; small siblings pack around
it correctly). But that defeats the purpose of having an auto-placer.
Suggested investigation
- Reproduce in
tscircuit/core tests with a board similar to the
above and assert U_RF.center.x === -18 (or within a 1 mm
tolerance).
- Trace why the chip gets displaced after initial placement —
PackSolver2's iterative refinement looks like the most likely
suspect.
- A simple guard: if a child's footprint is larger than 50 % of the
group's free area, treat it as static (effectively force the user
to place big-relative-to-group parts explicitly OR bias the
packer to anchor them first and move only small parts around
them).
Why it matters
Every board with a wireless module, a connector, or a similar
"dominant footprint" hits this. With the workaround the layout
becomes a chain of explicit pcbX/pcbY calls, which is what the
auto-placer is supposed to obviate.
Summary
When a
<group pcbX={x} pcbY={y}>contains a large chip (e.g. a 12 ×12 mm RF module) along with a handful of small siblings (decoupling
caps, pull-ups, etc.), the auto-packer can place the chip itself
many millimetres off-board while the small siblings cluster around
the group anchor. The chip "falls off" instead of dominating the
group.
This was concretely reproducible on our project — an InsightSiP
ISP3080-UX 12×12 mm module landed at X=−56.91 on a 50 mm-wide board
(over 30 mm past the left edge) when its
region_mcugroupcontained ~10 children. Smaller chips (
U_CHGDSBGA-8,U_BUCKSOT-563, etc.) in groups with 3–5 siblings landed cleanly at the
group anchor in the same run.
Repro
Expected:
U_RFlands at (−18, 0) (group anchor); small siblingspack around it with the configured
pcbPackGapclearance.Actual:
U_RFends up at e.g. (−56.91, −12.72) — off-board by~32 mm — while several small siblings sit clustered at the group
anchor.
Diagnosis
Likely the
largest_to_smallestordering incalculate-packing'sPackSolver2 places
U_RFfirst into the empty space, then smallparts shoulder it out of position when their candidate scores
prefer the anchor zone. The chip's "won" position is then a
candidate the next-iteration adjustment moves further away.
Workaround we ended up using: hand-pin the chip with explicit
pcbX/pcbY(chip then becomes static; small siblings pack aroundit correctly). But that defeats the purpose of having an auto-placer.
Suggested investigation
tscircuit/coretests with a board similar to theabove and assert
U_RF.center.x === -18(or within a 1 mmtolerance).
PackSolver2's iterative refinement looks like the most likely
suspect.
group's free area, treat it as static (effectively force the user
to place big-relative-to-group parts explicitly OR bias the
packer to anchor them first and move only small parts around
them).
Why it matters
Every board with a wireless module, a connector, or a similar
"dominant footprint" hits this. With the workaround the layout
becomes a chain of explicit pcbX/pcbY calls, which is what the
auto-placer is supposed to obviate.