@tscircuit/schematic-trace-solver 0.0.119 → 0.0.121

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,498 @@
1
+ {
2
+ "chips": [
3
+ {
4
+ "chipId": "schematic_component_0",
5
+ "center": {
6
+ "x": 0,
7
+ "y": 0
8
+ },
9
+ "width": 3.4000000000000004,
10
+ "height": 7.5,
11
+ "pins": [
12
+ {
13
+ "pinId": "schematic_port_0",
14
+ "x": -1.7000000000000002,
15
+ "y": 1.5000000000000004
16
+ },
17
+ {
18
+ "pinId": "schematic_port_1",
19
+ "x": -1.7000000000000002,
20
+ "y": 0.7500000000000004
21
+ },
22
+ {
23
+ "pinId": "schematic_port_2",
24
+ "x": -1.7000000000000002,
25
+ "y": 0.5000000000000004
26
+ },
27
+ {
28
+ "pinId": "schematic_port_3",
29
+ "x": -1.7000000000000002,
30
+ "y": -0.9500000000000002
31
+ },
32
+ {
33
+ "pinId": "schematic_port_4",
34
+ "x": -1.7000000000000002,
35
+ "y": -1.8500000000000005
36
+ },
37
+ {
38
+ "pinId": "schematic_port_5",
39
+ "x": -1.7000000000000002,
40
+ "y": -1.6000000000000005
41
+ },
42
+ {
43
+ "pinId": "schematic_port_6",
44
+ "x": -1.7000000000000002,
45
+ "y": -2.1000000000000005
46
+ },
47
+ {
48
+ "pinId": "schematic_port_7",
49
+ "x": -1.7000000000000002,
50
+ "y": -2.3500000000000005
51
+ },
52
+ {
53
+ "pinId": "schematic_port_8",
54
+ "x": -1.7000000000000002,
55
+ "y": -2.6000000000000005
56
+ },
57
+ {
58
+ "pinId": "schematic_port_9",
59
+ "x": -1.7000000000000002,
60
+ "y": -0.04999999999999982
61
+ },
62
+ {
63
+ "pinId": "schematic_port_10",
64
+ "x": 1.7000000000000002,
65
+ "y": -2.6950000000000003
66
+ },
67
+ {
68
+ "pinId": "schematic_port_11",
69
+ "x": 1.7000000000000002,
70
+ "y": -1.5450000000000004
71
+ },
72
+ {
73
+ "pinId": "schematic_port_12",
74
+ "x": 1.7000000000000002,
75
+ "y": -0.8950000000000005
76
+ },
77
+ {
78
+ "pinId": "schematic_port_13",
79
+ "x": 1.7000000000000002,
80
+ "y": -0.24500000000000055
81
+ },
82
+ {
83
+ "pinId": "schematic_port_14",
84
+ "x": 1.7000000000000002,
85
+ "y": 0.5549999999999997
86
+ },
87
+ {
88
+ "pinId": "schematic_port_15",
89
+ "x": 1.7000000000000002,
90
+ "y": 2.6950000000000003
91
+ },
92
+ {
93
+ "pinId": "schematic_port_16",
94
+ "x": 1.7000000000000002,
95
+ "y": 1.505
96
+ },
97
+ {
98
+ "pinId": "schematic_port_17",
99
+ "x": 1.7000000000000002,
100
+ "y": 1.255
101
+ },
102
+ {
103
+ "pinId": "schematic_port_18",
104
+ "x": -1.7000000000000002,
105
+ "y": 2.6000000000000005
106
+ }
107
+ ]
108
+ },
109
+ {
110
+ "chipId": "schematic_component_1",
111
+ "center": {
112
+ "x": -10.8,
113
+ "y": 1.4
114
+ },
115
+ "width": 2.3999999999999986,
116
+ "height": 1,
117
+ "pins": [
118
+ {
119
+ "pinId": "schematic_port_19",
120
+ "x": -9.600000000000001,
121
+ "y": 1.7
122
+ },
123
+ {
124
+ "pinId": "schematic_port_20",
125
+ "x": -9.600000000000001,
126
+ "y": 1.5
127
+ },
128
+ {
129
+ "pinId": "schematic_port_21",
130
+ "x": -9.600000000000001,
131
+ "y": 1.2999999999999998
132
+ },
133
+ {
134
+ "pinId": "schematic_port_22",
135
+ "x": -9.600000000000001,
136
+ "y": 1.0999999999999999
137
+ }
138
+ ]
139
+ },
140
+ {
141
+ "chipId": "schematic_component_2",
142
+ "center": {
143
+ "x": -4.5,
144
+ "y": 4.05
145
+ },
146
+ "width": 2.2,
147
+ "height": 0.5999999999999996,
148
+ "pins": [
149
+ {
150
+ "pinId": "schematic_port_23",
151
+ "x": -3.4,
152
+ "y": 4.1499999999999995
153
+ },
154
+ {
155
+ "pinId": "schematic_port_24",
156
+ "x": -3.4,
157
+ "y": 3.9499999999999997
158
+ }
159
+ ]
160
+ },
161
+ {
162
+ "chipId": "schematic_component_3",
163
+ "center": {
164
+ "x": -5.9875,
165
+ "y": 1.45
166
+ },
167
+ "width": 0.9250000000000007,
168
+ "height": 0.7599999999999998,
169
+ "pins": [
170
+ {
171
+ "pinId": "schematic_port_25",
172
+ "x": -6,
173
+ "y": 1.8299999999999998,
174
+ "_facingDirection": "y+"
175
+ },
176
+ {
177
+ "pinId": "schematic_port_26",
178
+ "x": -6,
179
+ "y": 1.07,
180
+ "_facingDirection": "y-"
181
+ }
182
+ ]
183
+ },
184
+ {
185
+ "chipId": "schematic_component_4",
186
+ "center": {
187
+ "x": -2.6375,
188
+ "y": 3.3
189
+ },
190
+ "width": 1.0250000000000004,
191
+ "height": 0.7600000000000007,
192
+ "pins": [
193
+ {
194
+ "pinId": "schematic_port_27",
195
+ "x": -2.7,
196
+ "y": 2.9199999999999995,
197
+ "_facingDirection": "y-"
198
+ },
199
+ {
200
+ "pinId": "schematic_port_28",
201
+ "x": -2.7,
202
+ "y": 3.68,
203
+ "_facingDirection": "y+"
204
+ }
205
+ ]
206
+ },
207
+ {
208
+ "chipId": "schematic_component_5",
209
+ "center": {
210
+ "x": -10.8,
211
+ "y": -3.25
212
+ },
213
+ "width": 2.3000000000000007,
214
+ "height": 1.4000000000000004,
215
+ "pins": [
216
+ {
217
+ "pinId": "schematic_port_29",
218
+ "x": -9.65,
219
+ "y": -2.75
220
+ },
221
+ {
222
+ "pinId": "schematic_port_30",
223
+ "x": -9.65,
224
+ "y": -2.95
225
+ },
226
+ {
227
+ "pinId": "schematic_port_31",
228
+ "x": -9.65,
229
+ "y": -3.15
230
+ },
231
+ {
232
+ "pinId": "schematic_port_32",
233
+ "x": -9.65,
234
+ "y": -3.35
235
+ },
236
+ {
237
+ "pinId": "schematic_port_33",
238
+ "x": -9.65,
239
+ "y": -3.55
240
+ },
241
+ {
242
+ "pinId": "schematic_port_34",
243
+ "x": -9.65,
244
+ "y": -3.75
245
+ }
246
+ ]
247
+ },
248
+ {
249
+ "chipId": "schematic_component_6",
250
+ "center": {
251
+ "x": -2.5,
252
+ "y": -0.05000000000000002
253
+ },
254
+ "width": 0.5999999999999996,
255
+ "height": 0.6799999999999999,
256
+ "pins": [
257
+ {
258
+ "pinId": "schematic_port_35",
259
+ "x": -2.2,
260
+ "y": -0.04999999999999997,
261
+ "_facingDirection": "x+"
262
+ },
263
+ {
264
+ "pinId": "schematic_port_36",
265
+ "x": -2.8,
266
+ "y": -0.05000000000000004,
267
+ "_facingDirection": "x-"
268
+ }
269
+ ]
270
+ },
271
+ {
272
+ "chipId": "schematic_component_7",
273
+ "center": {
274
+ "x": -5.705,
275
+ "y": -2.35
276
+ },
277
+ "width": 1.0899999999999999,
278
+ "height": 0.5999999999999996,
279
+ "pins": [
280
+ {
281
+ "pinId": "schematic_port_37",
282
+ "x": -5.8,
283
+ "y": -2.0500000000000003,
284
+ "_facingDirection": "y+"
285
+ },
286
+ {
287
+ "pinId": "schematic_port_38",
288
+ "x": -5.8,
289
+ "y": -2.65,
290
+ "_facingDirection": "y-"
291
+ }
292
+ ]
293
+ },
294
+ {
295
+ "chipId": "schematic_component_8",
296
+ "center": {
297
+ "x": -4.495,
298
+ "y": -0.75
299
+ },
300
+ "width": 1.2100000000000004,
301
+ "height": 0.6000000000000001,
302
+ "pins": [
303
+ {
304
+ "pinId": "schematic_port_39",
305
+ "x": -4.65,
306
+ "y": -0.44999999999999996,
307
+ "_facingDirection": "y+"
308
+ },
309
+ {
310
+ "pinId": "schematic_port_40",
311
+ "x": -4.65,
312
+ "y": -1.05,
313
+ "_facingDirection": "y-"
314
+ }
315
+ ]
316
+ },
317
+ {
318
+ "chipId": "schematic_component_9",
319
+ "center": {
320
+ "x": 4.35,
321
+ "y": 3.25
322
+ },
323
+ "width": 1.0558250000000005,
324
+ "height": 0.8677407000000006,
325
+ "pins": [
326
+ {
327
+ "pinId": "schematic_port_41",
328
+ "x": 3.8220874999999994,
329
+ "y": 3.2526245499999993
330
+ },
331
+ {
332
+ "pinId": "schematic_port_42",
333
+ "x": 4.8779125,
334
+ "y": 3.24737545
335
+ }
336
+ ]
337
+ }
338
+ ],
339
+ "directConnections": [
340
+ {
341
+ "netId": "R1.pin1 to U1.ILIM",
342
+ "pinIds": [
343
+ "schematic_port_35",
344
+ "schematic_port_9"
345
+ ]
346
+ },
347
+ {
348
+ "netId": "J3.pin4 to R4.pin2",
349
+ "pinIds": [
350
+ "schematic_port_32",
351
+ "schematic_port_38"
352
+ ]
353
+ },
354
+ {
355
+ "netId": "R4.pin2 to U1.INT",
356
+ "pinIds": [
357
+ "schematic_port_38",
358
+ "schematic_port_6"
359
+ ]
360
+ },
361
+ {
362
+ "netId": "J3.pin5 to U1.OTG",
363
+ "pinIds": [
364
+ "schematic_port_33",
365
+ "schematic_port_7"
366
+ ]
367
+ },
368
+ {
369
+ "netId": "J3.pin6 to U1.CE",
370
+ "pinIds": [
371
+ "schematic_port_34",
372
+ "schematic_port_8"
373
+ ]
374
+ },
375
+ {
376
+ "netId": "R5.pin1 to L1.pin2",
377
+ "pinIds": [
378
+ "schematic_port_39",
379
+ "schematic_port_42"
380
+ ]
381
+ }
382
+ ],
383
+ "netConnections": [
384
+ {
385
+ "netId": "GND",
386
+ "netLabelWidth": 0.42,
387
+ "netLabelHeight": 0.48,
388
+ "pinIds": [
389
+ "schematic_port_14",
390
+ "schematic_port_22",
391
+ "schematic_port_24",
392
+ "schematic_port_26",
393
+ "schematic_port_28",
394
+ "schematic_port_36"
395
+ ]
396
+ },
397
+ {
398
+ "netId": "VREF",
399
+ "netLabelWidth": 0.42,
400
+ "netLabelHeight": 0.6,
401
+ "pinIds": [
402
+ "schematic_port_29",
403
+ "schematic_port_37"
404
+ ]
405
+ }
406
+ ],
407
+ "textBoxes": [
408
+ {
409
+ "chipId": "schematic_component_0",
410
+ "center": {
411
+ "x": -0.6400000000000001,
412
+ "y": -3.88
413
+ },
414
+ "width": 1.3199999999999998,
415
+ "height": 0.17999999999999972,
416
+ "text": "BQ25895RTWR"
417
+ },
418
+ {
419
+ "chipId": "schematic_component_0",
420
+ "center": {
421
+ "x": -1.1800000000000002,
422
+ "y": 3.865
423
+ },
424
+ "width": 0.3600000000000001,
425
+ "height": 0.24999999999999956,
426
+ "text": "U1"
427
+ },
428
+ {
429
+ "chipId": "schematic_component_1",
430
+ "center": {
431
+ "x": -11.060000000000002,
432
+ "y": 0.7699999999999999
433
+ },
434
+ "width": 1.08,
435
+ "height": 0.17999999999999994,
436
+ "text": "USB Input"
437
+ },
438
+ {
439
+ "chipId": "schematic_component_1",
440
+ "center": {
441
+ "x": -11.48,
442
+ "y": 2.015
443
+ },
444
+ "width": 0.3600000000000012,
445
+ "height": 0.2500000000000002,
446
+ "text": "J1"
447
+ },
448
+ {
449
+ "chipId": "schematic_component_2",
450
+ "center": {
451
+ "x": -4.66,
452
+ "y": 3.62
453
+ },
454
+ "width": 1.08,
455
+ "height": 0.17999999999999972,
456
+ "text": "Phone OTG"
457
+ },
458
+ {
459
+ "chipId": "schematic_component_2",
460
+ "center": {
461
+ "x": -5.08,
462
+ "y": 4.465
463
+ },
464
+ "width": 0.35999999999999943,
465
+ "height": 0.2499999999999991,
466
+ "text": "J2"
467
+ },
468
+ {
469
+ "chipId": "schematic_component_5",
470
+ "center": {
471
+ "x": -11.31,
472
+ "y": -4.08
473
+ },
474
+ "width": 0.4800000000000004,
475
+ "height": 0.17999999999999972,
476
+ "text": "Host"
477
+ },
478
+ {
479
+ "chipId": "schematic_component_5",
480
+ "center": {
481
+ "x": -11.43,
482
+ "y": -2.4349999999999996
483
+ },
484
+ "width": 0.3600000000000012,
485
+ "height": 0.24999999999999956,
486
+ "text": "J3"
487
+ }
488
+ ],
489
+ "availableNetLabelOrientations": {
490
+ "GND": [
491
+ "y-"
492
+ ],
493
+ "VREF": [
494
+ "y+"
495
+ ]
496
+ },
497
+ "maxMspPairDistance": 20
498
+ }
@@ -0,0 +1,75 @@
1
+ import { expect, test } from "bun:test"
2
+ import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
3
+ import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceLinesSolver"
4
+ import { SCHEMATIC_TRACE_MIN_VISUAL_CENTERLINE_CLEARANCE } from "lib/utils/doesPathCoincideWithTraces"
5
+ import "tests/fixtures/matcher"
6
+ import inputProblem from "./assets/repro-bq25895-cross-net-trace-overlap.input.json"
7
+
8
+ const EPSILON = 1e-6
9
+
10
+ const tracesHaveInsufficientParallelClearance = (
11
+ firstTrace: SolvedTracePath,
12
+ secondTrace: SolvedTracePath,
13
+ ) => {
14
+ for (
15
+ let firstPointIndex = 0;
16
+ firstPointIndex < firstTrace.tracePath.length - 1;
17
+ firstPointIndex++
18
+ ) {
19
+ const firstStart = firstTrace.tracePath[firstPointIndex]!
20
+ const firstEnd = firstTrace.tracePath[firstPointIndex + 1]!
21
+ const firstIsVertical = Math.abs(firstStart.x - firstEnd.x) < EPSILON
22
+ if (!firstIsVertical) continue
23
+
24
+ for (
25
+ let secondPointIndex = 0;
26
+ secondPointIndex < secondTrace.tracePath.length - 1;
27
+ secondPointIndex++
28
+ ) {
29
+ const secondStart = secondTrace.tracePath[secondPointIndex]!
30
+ const secondEnd = secondTrace.tracePath[secondPointIndex + 1]!
31
+ const secondIsVertical = Math.abs(secondStart.x - secondEnd.x) < EPSILON
32
+ if (!secondIsVertical) continue
33
+
34
+ const xSeparation = Math.abs(firstStart.x - secondStart.x)
35
+ const verticalOverlap =
36
+ Math.min(
37
+ Math.max(firstStart.y, firstEnd.y),
38
+ Math.max(secondStart.y, secondEnd.y),
39
+ ) -
40
+ Math.max(
41
+ Math.min(firstStart.y, firstEnd.y),
42
+ Math.min(secondStart.y, secondEnd.y),
43
+ )
44
+
45
+ if (
46
+ xSeparation + EPSILON <
47
+ SCHEMATIC_TRACE_MIN_VISUAL_CENTERLINE_CLEARANCE &&
48
+ verticalOverlap > EPSILON
49
+ ) {
50
+ return true
51
+ }
52
+ }
53
+ }
54
+
55
+ return false
56
+ }
57
+
58
+ test("BQ25895 CE and GND traces keep visible parallel clearance", () => {
59
+ const solver = new SchematicTracePipelineSolver(inputProblem as any)
60
+ solver.solve()
61
+
62
+ const traces = solver.netLabelTraceCollisionSolver!.getOutput().traces
63
+ const ceTraces = traces.filter(
64
+ (trace) => trace.userNetId === "J3.pin6 to U1.CE",
65
+ )
66
+ const groundTraces = traces.filter((trace) => trace.userNetId === "GND")
67
+ const hasInsufficientCeAndGroundClearance = ceTraces.some((ceTrace) =>
68
+ groundTraces.some((groundTrace) =>
69
+ tracesHaveInsufficientParallelClearance(ceTrace, groundTrace),
70
+ ),
71
+ )
72
+
73
+ expect(hasInsufficientCeAndGroundClearance).toBe(false)
74
+ expect(solver).toMatchSolverSnapshot(import.meta.path)
75
+ })
@@ -0,0 +1,84 @@
1
+ import { expect, test } from "bun:test"
2
+ import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
3
+ import type { InputProblem } from "lib/types/InputProblem"
4
+ import "tests/fixtures/matcher"
5
+
6
+ const inputProblem: InputProblem = {
7
+ chips: [
8
+ {
9
+ chipId: "PWR1",
10
+ center: { x: 0, y: 0 },
11
+ width: 2.1,
12
+ height: 1,
13
+ pins: [
14
+ { pinId: "PWR1.EP", x: 1.05, y: 0.2 },
15
+ { pinId: "PWR1.GND", x: -1.05, y: -0.1 },
16
+ ],
17
+ },
18
+ {
19
+ chipId: "R7",
20
+ center: { x: -3, y: -2 },
21
+ width: 0.6,
22
+ height: 0.68,
23
+ pins: [{ pinId: "R7.2", x: -2.7, y: -2, _facingDirection: "x+" }],
24
+ },
25
+ {
26
+ chipId: "C6",
27
+ center: { x: 3, y: -1.5 },
28
+ width: 0.6,
29
+ height: 0.84,
30
+ pins: [{ pinId: "C6.neg", x: 3.3, y: -1.5, _facingDirection: "x+" }],
31
+ },
32
+ {
33
+ chipId: "C7",
34
+ center: { x: 3, y: 0 },
35
+ width: 0.6,
36
+ height: 0.84,
37
+ pins: [{ pinId: "C7.neg", x: 3.3, y: 0, _facingDirection: "x+" }],
38
+ },
39
+ {
40
+ chipId: "LED1",
41
+ center: { x: 4, y: 3.1325 },
42
+ width: 1.13,
43
+ height: 0.915,
44
+ pins: [
45
+ {
46
+ pinId: "LED1.neg",
47
+ x: 4.565,
48
+ y: 3,
49
+ _facingDirection: "x+",
50
+ },
51
+ ],
52
+ },
53
+ ],
54
+ directConnections: [],
55
+ netConnections: [
56
+ {
57
+ netId: "gnd",
58
+ pinIds: ["PWR1.EP", "PWR1.GND", "R7.2", "C6.neg", "C7.neg", "LED1.neg"],
59
+ netLabelWidth: 0.42,
60
+ netLabelHeight: 0.48,
61
+ },
62
+ ],
63
+ textBoxes: [],
64
+ availableNetLabelOrientations: { gnd: ["y-"] },
65
+ maxMspPairDistance: 2.4,
66
+ }
67
+
68
+ test("places a shared capacitor GND label at the lower rail end", () => {
69
+ const solver = new SchematicTracePipelineSolver(inputProblem)
70
+
71
+ solver.solve()
72
+
73
+ const gndLabels = solver
74
+ .netLabelNetLabelCollisionSolver!.getOutput()
75
+ .netLabelPlacements.filter((label) => label.netId === "gnd")
76
+ const capacitorRailLabel = gndLabels.find(
77
+ (label) => Math.abs(label.anchorPoint.x - 3.3) < 1,
78
+ )!
79
+
80
+ expect(capacitorRailLabel.orientation).toBe("y-")
81
+ expect(capacitorRailLabel.anchorPoint.y).toBeCloseTo(-1.5)
82
+ expect(capacitorRailLabel.anchorPoint.x).toBeGreaterThan(3.3)
83
+ expect(solver).toMatchSolverSnapshot(import.meta.path)
84
+ })