imrishabh18/rp2040-motor-controller
An RP2040-based NEMA17 stepper-motor controller with USB-C programming and PD motor-power negotiation, DRV8825 dual H-bridge drive, current/temperature telemetry, protected power filtering, status RGB LED, buzzer alarm, and optional magnetic encoder.
- Version
- 1.0.41
- License
- unset
- Stars
- 3
scripts/copper_geometry.py
"""Trace segments matching the pinned circuit-json-to-gerber export semantics."""
from shapely.strtree import STRtree
from shapely.ops import unary_union
def subtract_drills(shapes, metadata, barrels, drills, layer_of):
"""Remove drilled-away copper and keep separated physical pieces separate."""
drill_shapes = [g for g, _ in drills]
tree = STRtree(drill_shapes)
new_shapes, new_metadata, mapping = [], [], {}
for i, (shape, meta) in enumerate(zip(shapes, metadata)):
nearby = [drill_shapes[k] for k in tree.query(shape) if layer_of(meta) in drills[k][1]]
cut = shape.difference(unary_union(nearby)) if nearby else shape
pieces = []
def collect(g):
if g.is_empty:
return
if g.geom_type in ('MultiPolygon', 'GeometryCollection'):
for piece in g.geoms:
collect(piece)
elif g.area > 1e-12:
pieces.append(g)
collect(cut)
mapping[i] = list(range(len(new_shapes), len(new_shapes) + len(pieces)))
new_shapes.extend(pieces)
new_metadata.extend([meta] * len(pieces))
return new_shapes, new_metadata, [[n for i in ids for n in mapping[i]] for ids in barrels]
def trace_segments(route):
for a, b in zip(route, route[1:]):
start = end = layer = width = None
if a['route_type'] == 'wire':
start, layer, width = a, a['layer'], a['width']
if b['route_type'] in ('wire', 'via'):
end = b
elif b['route_type'] == 'through_pad':
end = b['start'] if b['start_layer'] == layer else b['end'] if b['end_layer'] == layer else None
elif b['route_type'] == 'wire':
end, layer, width = b, b['layer'], b['width']
if a['route_type'] == 'via':
start = a
elif a['route_type'] == 'through_pad':
start = a['end'] if a['end_layer'] == layer else a['start'] if a['start_layer'] == layer else None
if start is None or end is None or (start['x'] == end['x'] and start['y'] == end['y']):
continue
yield (start['x'], start['y']), (end['x'], end['y']), layer, width
