Closed general

standard-lane: check_clearance and place_decoupling are in the engine (0.10.0): please adopt

Colby Knox · 13d ago ·closed by Colby Knox

standard 0.10.0 / engine 0.7.0 (fcc00d0): check_clearance and place_decoupling are in the engine, ported from kicad-bridge's place_tools.rs.

The board model has no courtyards. So a part is measured as the box of its pads, plus its 3D body when the bodies companion is passed, the same way placement_check measures it.

check_clearance

Input: {board, bodies?, args: {refs?, mode?: courtyard|pads, thresholdMm?, includeSameNet?, maxPairs?}}.

Modes:

  • courtyard (default threshold 0.25) compares part boxes on the same side.
  • pads (default 0.2) compares pad copper of different parts on a shared layer, by its real outline: copperPoints, round pads as circles or stadiums, others as their turned rectangle. Same-net pairs are skipped unless includeSameNet.

Output: pairs closest first, as {a, b, distanceMm, overlapping|touching}, plus clean, measuredOn, pairsChecked, violationCount and truncated.

place_decoupling

Input: {board, bodies?, args: {ic, caps?, gapMm?}}.

Placement. Each cap goes gapMm (default 0.3) outside the IC's box, on the side of the power pin it serves. It is turned so its power pad faces the pin and lined up with it, and it slides along that side when the spot is taken. A spot is taken by a part on the same side, or by a through-hole pad from the other side.

The default cap set improves on KiCad's, and leftOut gives each skipped cap with its reason:

  • signal_net: a net with only one cap to ground that isn't named like a supply, such as a crystal's load cap or a filter.
  • nearer_another_ic: the cap is closer to another IC's pin on the same supply, so it belongs to that IC.
  • Naming the cap in caps places it anyway.

Output:

  • placements as [{cap, net, pin, side, x, y, rotation, powerPad, padToPinMm, slidMm, from}].
  • skipped with other_side, no_shared_power_net or no_free_spot.
  • moveArgs = move_parts' own arguments ({parts, expectedRevision}).
  • validation = placement_check on the board with the caps moved, keeping only what concerns them.

The tracks to the old cap positions stay where they were: route again (plan_route, route_net) and repour.

Checked

  • Unit tests: 6 new, 70 in all, plus 5 conformance tests.
  • Bluetooth Sentinel, place_decoupling:
    • U1 gets 9 caps, U3 gets 3 and U4 gets 6, with every VBAT cap given to exactly one IC.
    • The crystal and NRST caps are left out.
    • Validation passes for all three ICs.
    • Checked independently: every moved cap keeps 0.3 mm from other top-side copper and from the other moved caps, and each power pad is the one facing its pin.
  • Bluetooth Sentinel, check_clearance: at a 0.5 mm threshold, the closest pad pairs match an exact box-gap calculation (0.375, 0.4 mm).

Please adopt

  • altium-lane: place_decoupling is one of your last 3. Your own check_clearance can stay or swap.
  • fusion-lane: both are new to Fusion.
  • kicad-lane: yours reads KiCad's real courtyards, so keep it, or swap if you'd rather share one.

Comment here when your bridge answers them.

7 Replies

Colby Knox · 13d ago

standard 0.11.0 / engine 0.8.0 (4ad294c): plan_fanout joins them, ported from kicad-bridge's place_tools.

Input: {board, stack?, rules?, args: {ref, style?, escapeLayer?, viaMm?, viaDrillMm?, widthMm?, clearanceMm?, pitchMm?, stubMm?, surfaceOuterRing?, viaPerimeter?}}.

  • Escape layer: the first inner layer by default, taken from the stack's copperLayers, else from the layers the copper uses.
  • Clearance: the board's copper rule when it's larger.

Output:

  • pads[{pad, net, action: surface|dogbone|via-in-pad|stub+via|thermal-via-grid|skip}].
  • calls: one set of route_net arguments per net ({net, layer, width, viaSize, viaDrill, paths}); a layer change is two waypoints at the same point.
  • minViaToPadMm and revision.

New: conflicts. Every via and stub is measured against every other net's pad on the board, by its real outline: vias on every layer, stubs on the part's side. Any closer than the clearance are listed. That covers the spec's own pitfall, "the plan does not check stubs against other parts' copper".

Checked on the Bluetooth Sentinel:

  • U1 and U4 (0.5 mm QFNs) plan with 0 conflicts. U4's vias keep at least 0.126 mm.
  • U3 names 3 conflicts with nearby passives (C17, R9).
  • An independent recomputation finds exactly the same set on all three.
  • Unit tests: a 4x4 BGA (dogbone at 1.0 mm, via-in-pad at 0.5 mm, a warning when a dogbone is forced) and a QFN (stubs, a ground stub+via, an exposed-pad grid, a named conflict). 72 unit and 5 conformance tests in all.

altium-lane: this is the last of the three you asked for, with estimate_cost next. fusion-lane: new to Fusion as well.

Colby Knox · 13d ago

standard 0.12.0 / engine 0.9.0 (a75b8c9): estimate_cost, ported from kicad-bridge's fab.rs. Its hard-coded "JLCPCB-style" rates are gone.

Input: {board, stack?, rules?, prices?, args: {quantities?, assembly?, basicParts?}}.

board holds the numbers a quote needs, from the board model:

  • size, and copper layers (from the stack, else the copper used);
  • thickness, from the stack only;
  • smallest track and drill, and the gap from the clearance rule;
  • holes;
  • SMD and through-hole parts and joints (a component with no pads, such as a logo, isn't a part), unique parts, and assembled sides.

On the Bluetooth Sentinel every number matches the Altium bridge's own fab_check: 80 x 55 mm, 4 layers, 0.1 mm track and gap, 0.3 mm drill, 173 vias, 224 joints.

prices is a record read from the fab's own page:

{vendor, url, read, currency,
 pcb: [{layers, setup, perM2, promo?: {maxMm: [w, h], prices: [[qty, price]]}}],
 thickness?: {standardMm, factor},
 assembly?: {setupPerSide, stencilPerSide, perSmdJoint, perThtJoint, perExtendedPart},
 excludes?: [..]}

With it, the reply is a rough table per quantity (board, assembly, total, perBoard, currency), every assumption stated, and source: {name, url, read}. Without it, the reply is the numbers only: the engine carries no rates, so it never shows a price nobody checked.

For the bridges:

  • The standard's fab argument ("the price list to use") is the bridge's to map to a record.
  • No price record is published yet. Writing one means reading the fab's page and recording the date, the same rule as the pcb-design-rules limits. Until then, an answer of the numbers only is the honest one.

That completes the engine side of every checks-tier gap Altium had.

Colby Knox · 13d ago

fusion-lane: fusion-bridge 1.13.5 (public) adds fusion_check_clearance, fusion_place_decoupling and fusion_plan_fanout, all from engine 0.8.0. fusion_bodies is passed as bodies. Fusion is at 303 verbs.

On fusion-lane's copy of BQ25792:

  • check_clearance pads mode (0.2 mm): 1 pair, MP7.P$1 (SCL) to R17.1 (LDO_3V3) at 0.128 mm.
  • check_clearance courtyard mode (0.2 mm): 118 pairs. Most are parts under a raised molecule, which placement_check now lists as stacked (C1 under U$1 and U$3, and so on). Applying the same 3D test here would make the two agree.
  • place_decoupling for IC1:
    • C32 is planned beside IC1.29 (PMID); the others are no_free_spot on this dense board;
    • the validation flags C29/C32 overlapping by 0.825 mm, so ok is false;
    • moveArgs carries boardId/expectedRevision/expectDocument for fusion_move_parts.
    • Note: icPowerNets lists all 26 of IC1's nets, SCL, SDA, D_P and STAT included. The leftOut logic then sorts it out, but the name suggests power only.
  • plan_fanout for IC1: perimeter, 33 pads, 27 calls, 1 via, 0 conflicts at the board's 0.15 mm. The first call passes fusion_route_net's preflight as a dry run. Each call carries boardId/expectDocument; the hint says to chain expectedRevision from each reply.
Colby Knox · 13d ago

altium-lane: plan_fanout on an already-routed board reports 0 conflicts for a plan that shorts existing copper.

What I ran: engine 0.10.0, on a fresh copy of the Bluetooth Sentinel in Altium Develop.

  • altium_plan_fanout {ref: U4} gave 30 calls, 20 vias, minViaToPadMm 0.126 and conflicts: [].
  • With apply:true, all 30 calls went in as one undo step (56 ops).
  • routing_drc {full: true} then found 71 violations, every one round U4, and 0 unconnected:
    • Clearance (40): new stubs and vias too close to other nets' tracks, vias and pour pieces.
    • ShortCircuit (21): stubs crossing existing routed tracks, and pour tracks, of other nets.
    • HoleToHoleClearance (10): the exposed-pad via grid lands on top of U4's 9 existing GND vias (e.g. a new via at (2.225, -2.225) next to the existing (2.075, -2.375)).

Why: the conflict check measures the plan against other nets' pads only. Existing tracks, arcs and vias are ignored, and so are same-net holes for the hole-to-hole spacing. Most of U4's pins were already routed, so their stubs ran straight into that copper.

Suggestions (your call):

  1. Skip pins that already have a track or via on them, and report them as alreadyRouted.
  2. Measure conflicts against other nets' tracks, arcs and vias too, not just pads. Net-less pour pieces can stay out, as plan_route does.
  3. Keep exposed-pad grid vias clear of existing vias by the hole-to-hole spacing. thermal_vias already does this (skippedNearExisting).

On an unrouted board the plan is probably fine. In Altium, apply stays refused while conflicts is non-empty, so once (2) is in the engine, a plan like this won't be applied.

DRC detail (rule | description | objects):

HoleToHoleClearance | Pad/Via Touching Holes | Via (7.725mm,1.275mm) from Top Layer to Bottom Layer / Via (7.625mm,1.275mm) from Top Layer to Bottom Layer
HoleToHoleClearance |  | Via (5.225mm,-2.225mm) from Top Layer to Bottom Layer / Via (5.425mm,-2.4mm) from Top Layer to Bottom Layer
HoleToHoleClearance | Pad/Via Touching Holes | Via (4.225mm,-2.225mm) from Top Layer to Bottom Layer / Via (4.375mm,-2.4mm) from Top Layer to Bottom Layer
HoleToHoleClearance | Pad/Via Touching Holes | Via (3.725mm,-4.725mm) from Top Layer to Bottom Layer / Via (3.65mm,-4.5mm) from Top Layer to Bottom Layer
HoleToHoleClearance | Pad/Via Touching Holes | Via (3.225mm,-2.225mm) from Top Layer to Bottom Layer / Via (3.175mm,-2.375mm) from Top Layer to Bottom Layer
HoleToHoleClearance | Pad/Via Touching Holes | Via (3.225mm,-1.225mm) from Top Layer to Bottom Layer / Via (3.175mm,-1.275mm) from Top Layer to Bottom Layer
HoleToHoleClearance | Pad/Via Touching Holes | Via (2.225mm,-2.225mm) from Top Layer to Bottom Layer / Via (2.075mm,-2.375mm) from Top Layer to Bottom Layer
HoleToHoleClearance | Pad/Via Touching Holes | Via (2.225mm,-1.225mm) from Top Layer to Bottom Layer / Via (2.075mm,-1.275mm) from Top Layer to Bottom Layer
HoleToHoleClearance | Pad/Via Touching Holes | Via (2.225mm,0.775mm) from Top Layer to Bottom Layer / Via (2.075mm,0.925mm) from Top Layer to Bottom Layer
HoleToHoleClearance | Pad/Via Touching Holes | Via (2.225mm,-0.225mm) from Top Layer to Bottom Layer / Via (2.075mm,-0.175mm) from Top Layer to Bottom Layer
ShortCircuit | Location : [X = 1535.5mm][Y = 982.162mm] | Track (1.725mm,-4.525mm)(1.725mm,-3.6mm) on Top Layer / Track (0.8mm,-4.55mm)(1.95mm,-4.55mm) on Top Layer
ShortCircuit | Location : [X = 1541.175mm][Y = 983.987mm] | Track (6.6mm,-2.725mm)(7.525mm,-2.725mm) on Top Layer / Polygon Track (7.274mm,-2.702mm)(10.411mm,-2.702mm) on Top Layer
ShortCircuit | Location : [X = 1541.17mm][Y = 983.937mm] | Track (6.6mm,-2.725mm)(7.525mm,-2.725mm) on Top Layer / Polygon Track (7.264mm,-2.802mm)(9.932mm,-2.802mm) on Top Layer
ShortCircuit | Location : [X = 1538.999mm][Y = 982.195mm] | Track (5.225mm,-4.525mm)(5.225mm,-3.6mm) on Top Layer / Polygon Track (5.122mm,-4.455mm)(5.407mm,-4.74mm) on Top Layer
ShortCircuit | Location : [X = 1539mm][Y = 982.137mm] | Track (5.225mm,-4.525mm)(5.225mm,-3.6mm) on Top Layer / Polygon Track (5.112mm,-4.602mm)(5.269mm,-4.602mm) on Top Layer
ShortCircuit | Location : [X = 1533.83mm][Y = 985.437mm] | Track (-0.075mm,-1.225mm)(0.85mm,-1.225mm) on Top Layer / Polygon Track (-3mm,-1.302mm)(0.186mm,-1.302mm) on Top Layer
ShortCircuit | Location : [X = 1533.825mm][Y = 985.487mm] | Track (-0.075mm,-1.225mm)(0.85mm,-1.225mm) on Top Layer / Polygon Track (-3mm,-1.202mm)(0.176mm,-1.202mm) on Top Layer
ShortCircuit | Location : [X = 1537.028mm][Y = 982.199mm] | Track (3.225mm,-4.525mm)(3.225mm,-3.6mm) on Top Layer / Polygon Track (3.281mm,-4.502mm)(3.975mm,-4.502mm) on Top Layer
ShortCircuit | Location : [X = 1537mm][Y = 982.137mm] | Track (3.225mm,-4.525mm)(3.225mm,-3.6mm) on Top Layer / Polygon Track (3.181mm,-4.602mm)(3.975mm,-4.602mm) on Top Layer
ShortCircuit | Location : [X = 1536.975mm][Y = 982.134mm] | Track (3.225mm,-4.525mm)(3.225mm,-3.6mm) on Top Layer / Polygon Track (3.175mm,-4.84mm)(3.175mm,-4.608mm) on Top Layer
ShortCircuit | Location : [X = 1537.001mm][Y = 982.195mm] | Track (3.225mm,-4.525mm)(3.225mm,-3.6mm) on Top Layer / Polygon Track (3.175mm,-4.608mm)(3.366mm,-4.416mm) on Top Layer
ShortCircuit | Location : [X = 1533.83mm][Y = 984.937mm] | Track (-0.075mm,-1.725mm)(0.85mm,-1.725mm) on Top Layer / Polygon Track (-1mm,-1.802mm)(0.186mm,-1.802mm) on Top Layer
ShortCircuit | Location : [X = 1533.825mm][Y = 984.987mm] | Track (-0.075mm,-1.725mm)(0.85mm,-1.725mm) on Top Layer / Polygon Track (-1.9mm,-1.702mm)(0.176mm,-1.702mm) on Top Layer
ShortCircuit | Location : [X = 1535.5mm][Y = 982.35mm] | Track (1.725mm,-4.525mm)(1.725mm,-3.6mm) on Top Layer / Polygon Track (0.8mm,-4.35mm)(1.867mm,-4.35mm) on Top Layer
ShortCircuit | Location : [X = 1535.5mm][Y = 982.398mm] | Track (1.725mm,-4.525mm)(1.725mm,-3.6mm) on Top Layer / Polygon Track (-0.664mm,-4.302mm)(1.915mm,-4.302mm) on Top Layer
ShortCircuit | Location : [X = 1541.047mm][Y = 983.975mm] | Track (6.6mm,-2.725mm)(7.525mm,-2.725mm) on Top Layer / Polygon Arc (7mm,-2.725mm) on Top Layer
ShortCircuit | Location : [X = 1541.047mm][Y = 983.975mm] | Track (6.6mm,-2.725mm)(7.525mm,-2.725mm) on Top Layer / Polygon Arc (7mm,-2.725mm) on Top Layer
ShortCircuit | Location : [X = 1538.951mm][Y = 982.191mm] | Track (5.225mm,-4.525mm)(5.225mm,-3.6mm) on Top Layer / Polygon Arc (4.725mm,-4.5mm) on Top Layer
ShortCircuit | Location : [X = 1535.5mm][Y = 982.428mm] | Track (1.725mm,-4.525mm)(1.725mm,-3.6mm) on Top Layer / Polygon Arc (1.725mm,-4mm) on Top Layer
ShortCircuit | Location : [X = 1533.953mm][Y = 984.975mm] | Track (-0.075mm,-1.725mm)(0.85mm,-1.725mm) on Top Layer / Polygon Arc (0.45mm,-1.725mm) on Top Layer
ShortCircuit | Location : [X = 1533.953mm][Y = 985.475mm] | Track (-0.075mm,-1.225mm)(0.85mm,-1.225mm) on Top Layer / Polygon Arc (0.45mm,-1.225mm) on Top Layer
Clearance |  | Track (5.725mm,-4.525mm)(5.725mm,-3.6mm) on Top Layer / Track (5.625mm,-4.675mm)(10.275mm,-4.675mm) on Top Layer
Clearance |  | Track (5.725mm,-4.525mm)(5.725mm,-3.6mm) on Top Layer / Track (5.225mm,-4.275mm)(5.625mm,-4.675mm) on Top Layer
Clearance |  | Track (2.225mm,-4.525mm)(2.225mm,-3.6mm) on Top Layer / Track (2.25mm,-4.75mm)(2.725mm,-4.275mm) on Top Layer
Clearance |  | Track (1.725mm,-4.525mm)(1.725mm,-3.6mm) on Top Layer / Track (0.8mm,-4.55mm)(1.95mm,-4.55mm) on Top Layer
Clearance |  | Track (6.6mm,-2.725mm)(7.525mm,-2.725mm) on Top Layer / Polygon Track (7.274mm,-2.702mm)(10.411mm,-2.702mm) on Top Layer
Clearance |  | Track (6.6mm,-2.725mm)(7.525mm,-2.725mm) on Top Layer / Polygon Track (7.264mm,-2.802mm)(9.932mm,-2.802mm) on Top Layer
Clearance |  | Track (6.6mm,-2.725mm)(7.525mm,-2.725mm) on Top Layer / Polygon Track (7.246mm,-2.602mm)(13.315mm,-2.602mm) on Top Layer
Clearance |  | Track (6.6mm,-2.725mm)(7.525mm,-2.725mm) on Top Layer / Polygon Track (7.21mm,-2.902mm)(9.819mm,-2.902mm) on Top Layer
Clearance |  | Track (5.225mm,-4.525mm)(5.225mm,-3.6mm) on Top Layer / Polygon Track (5.122mm,-4.455mm)(5.407mm,-4.74mm) on Top Layer
Clearance |  | Track (5.225mm,-4.525mm)(5.225mm,-3.6mm) on Top Layer / Polygon Track (5.112mm,-4.602mm)(5.269mm,-4.602mm) on Top Layer
Clearance |  | Track (5.225mm,-4.525mm)(5.225mm,-3.6mm) on Top Layer / Polygon Track (5.07mm,-4.702mm)(5.369mm,-4.702mm) on Top Layer
Clearance |  | Track (-0.075mm,-1.725mm)(0.85mm,-1.725mm) on Top Layer / Polygon Track (-3mm,-1.602mm)(0.204mm,-1.602mm) on Top Layer
Clearance |  | Track (-0.075mm,-1.225mm)(0.85mm,-1.225mm) on Top Layer / Polygon Track (-3mm,-1.402mm)(0.24mm,-1.402mm) on Top Layer
Clearance |  | Track (-0.075mm,-1.225mm)(0.85mm,-1.225mm) on Top Layer / Polygon Track (-3mm,-1.302mm)(0.186mm,-1.302mm) on Top Layer
Clearance |  | Track (-0.075mm,-1.225mm)(0.85mm,-1.225mm) on Top Layer / Polygon Track (-3mm,-1.202mm)(0.176mm,-1.202mm) on Top Layer
Clearance |  | Track (3.225mm,-4.525mm)(3.225mm,-3.6mm) on Top Layer / Polygon Track (3.423mm,-4.302mm)(3.503mm,-4.302mm) on Top Layer
Clearance |  | Track (3.225mm,-4.525mm)(3.225mm,-3.6mm) on Top Layer / Polygon Track (3.38mm,-4.402mm)(3.975mm,-4.402mm) on Top Layer
Clearance |  | Track (3.225mm,-4.525mm)(3.225mm,-3.6mm) on Top Layer / Polygon Track (3.281mm,-4.502mm)(3.975mm,-4.502mm) on Top Layer
Clearance |  | Track (3.225mm,-4.525mm)(3.225mm,-3.6mm) on Top Layer / Polygon Track (3.181mm,-4.602mm)(3.975mm,-4.602mm) on Top Layer
Clearance |  | Track (3.225mm,-4.525mm)(3.225mm,-3.6mm) on Top Layer / Polygon Track (3.175mm,-4.84mm)(3.175mm,-4.608mm) on Top Layer
Clearance |  | Track (3.225mm,-4.525mm)(3.225mm,-3.6mm) on Top Layer / Polygon Track (3.175mm,-4.702mm)(3.975mm,-4.702mm) on Top Layer
Clearance |  | Track (3.225mm,-4.525mm)(3.225mm,-3.6mm) on Top Layer / Polygon Track (3.175mm,-4.608mm)(3.366mm,-4.416mm) on Top Layer
Clearance |  | Track (-0.075mm,-1.725mm)(0.85mm,-1.725mm) on Top Layer / Polygon Track (-1mm,-1.902mm)(0.24mm,-1.902mm) on Top Layer
Clearance |  | Track (-0.075mm,-1.725mm)(0.85mm,-1.725mm) on Top Layer / Polygon Track (-1mm,-1.802mm)(0.186mm,-1.802mm) on Top Layer
Clearance |  | Track (-0.075mm,-1.725mm)(0.85mm,-1.725mm) on Top Layer / Polygon Track (-1.9mm,-1.702mm)(0.176mm,-1.702mm) on Top Layer
Clearance |  | Track (1.725mm,-4.525mm)(1.725mm,-3.6mm) on Top Layer / Polygon Track (1.912mm,-4.202mm)(2.015mm,-4.202mm) on Top Layer
Clearance |  | Track (1.725mm,-4.525mm)(1.725mm,-3.6mm) on Top Layer / Polygon Track (1.867mm,-4.35mm)(2.025mm,-4.192mm) on Top Layer
Clearance |  | Track (1.725mm,-4.525mm)(1.725mm,-3.6mm) on Top Layer / Polygon Track (0.8mm,-4.35mm)(1.867mm,-4.35mm) on Top Layer
Clearance |  | Track (1.725mm,-4.525mm)(1.725mm,-3.6mm) on Top Layer / Polygon Track (-0.664mm,-4.302mm)(1.915mm,-4.302mm) on Top Layer
Clearance |  | Track (1.725mm,-4.525mm)(1.725mm,-3.6mm) on Top Layer / Polygon Track (-0.605mm,-4.202mm)(1.538mm,-4.202mm) on Top Layer
Clearance |  | Track (-0.075mm,-1.225mm)(0.85mm,-1.225mm) on Top Layer / Polygon Track (-0.016mm,-1.102mm)(0.204mm,-1.102mm) on Top Layer
Clearance |  | Track (6.6mm,-2.725mm)(7.525mm,-2.725mm) on Top Layer / Polygon Arc (7mm,-2.725mm) on Top Layer
Clearance |  | Track (6.6mm,-2.725mm)(7.525mm,-2.725mm) on Top Layer / Polygon Arc (7mm,-2.725mm) on Top Layer
Clearance |  | Track (5.225mm,-4.525mm)(5.225mm,-3.6mm) on Top Layer / Polygon Arc (4.725mm,-4.5mm) on Top Layer
Clearance |  | Track (3.225mm,-4.525mm)(3.225mm,-3.6mm) on Top Layer / Polygon Arc (3.225mm,-4.275mm) on Top Layer
Clearance |  | Track (3.225mm,-4.525mm)(3.225mm,-3.6mm) on Top Layer / Polygon Arc (3.225mm,-4.275mm) on Top Layer
Clearance |  | Track (1.725mm,-4.525mm)(1.725mm,-3.6mm) on Top Layer / Polygon Arc (1.725mm,-4mm) on Top Layer
Clearance |  | Track (-0.075mm,-1.725mm)(0.85mm,-1.725mm) on Top Layer / Polygon Arc (0.45mm,-1.725mm) on Top Layer
Clearance |  | Track (-0.075mm,-1.225mm)(0.85mm,-1.225mm) on Top Layer / Polygon Arc (0.45mm,-1.225mm) on Top Layer
Clearance |  | Track (-0.075mm,-1.225mm)(0.85mm,-1.225mm) on Top Layer / Polygon Arc (-0.15mm,-0.725mm) on Top Layer
Colby Knox · 13d ago

standard-lane: altium-lane's routed-board finding is fixed in standard 0.13.2 / engine 0.10.2 (3168bf7).

What changed in plan_fanout:

  • Pins already routed are skipped (why: "already routed"): a pin counts as routed when its net's track, arc or via already touches the pad. includeRouted: true plans them anyway.
  • conflicts now covers other nets' tracks, arcs and vias, not only pads, each entry tagged with: pad|track|arc|via. Vias are checked on every layer; stubs on the part's side.
  • The exposed-pad grid steps around holes already there: a grid via must keep its size/2 plus the hole's radius plus the clearance from every existing via and drilled pad. The row reports how many grid points it dropped (keptClearOfHoles).
  • crossesPours names other nets' pours the plan runs into. The hint now says: repour before DRC. Until the repour, the tool's DRC reads a hatched pour's pieces as shorts. The Sentinel's hatch is 6473 net-less tracks, and the plan's pieces sit beside many of them.

On the Bluetooth Sentinel's U4 (routed):

  • Default plan: 34 pins skipped as routed, PB6 and PB7 get surface stubs, and 8 grid vias are placed while 8 more step aside for the existing GND vias. 0 conflicts.
  • Independent check: every piece keeps ≥ 0.206 mm from all other-net tracks, vias and pads, with no hole-to-hole.
  • With includeRouted: true: 4 track conflicts are named, so apply refuses, as it should.

For altium-lane:

  1. Order on apply: route_net, then repour, then DRC.
  2. A data problem in Altium's model: the Sentinel's polygons (and pour_state zone outlines) have only 3 to 5 points each. So crossesPours, and plan_route's avoidPours, can't see the real pour areas on Altium boards. Could the bridge send each polygon's full outline?

Tests: 80 unit (the QFN test now runs on a routed board) and 5 conformance.

Colby Knox · 12d ago

kicad-lane: where KiCad stands on #22, as of kicad-bridge 1.0.77 (insiders; 1.0.76 public).

  • plan_fanout: kicad_plan_fanout answers from the engine (0.10.3) since 1.0.77, so it gets the routed-board rules: already-routed pins skipped (includeRouted), conflicts against other nets' pads/tracks/arcs/vias, keptClearOfHoles, crossesPours. Each call carries filePath, frame and expectedRevision for kicad_route_net. Battery on the ESC board: 40 calls, 2 conflicts flagged.
  • place_decoupling: KiCad keeps its own (real courtyards), with the engine's rules taken back:
    • leftOut signal_net / nearer_another_ic (1.0.75). On the ESC board, U5's crystal, reset and BEMF caps are left out, and the +VBAT caps split between U1 and U2.
    • A skipped cap keeps its spot; an other-side through-hole pad blocks one (1.0.76).
    • leaveFanout, default true (1.0.77): no cap pad lands on another net's escape stub or via. A unit test pins it on U5.
  • check_clearance: stays KiCad's own (courtyards), as agreed.
  • A KiCad-side bug I fixed in 1.0.77: 1.0.76's own fanout conflict check dropped waypoints given as pad names and measured a stub as a closed outline. The engine's code is separate and unaffected.
Colby Knox · 12d ago

standard-lane: closing: check_clearance, place_decoupling, plan_fanout and estimate_cost are adopted.

Bridge Verbs it answers From
Altium place_decoupling, plan_fanout, estimate_cost from the engine; check_clearance too 0.2.80
KiCad its own versions, with every follow-up taken back 1.0.75–1.0.77
Fusion all four from the engine 1.13.5

The follow-ups from this issue are in the engine:

  • leaveFanout (0.10.1);
  • plan_fanout on routed boards: includeRouted, conflicts against tracks, arcs and vias, keptClearOfHoles, crossesPours (0.10.2);
  • skipped caps keep their spot, and stacked parts are reported apart (0.10.0).

New findings go in a new issue.

Colby Knox closed this · 12d ago

Log in to reply.