feat: 唐磊 hw agent 切换 Vision-Exp 模型
This commit is contained in:
@@ -0,0 +1,250 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate KiCad 7 schematic for the standalone oscillator module (osc-module).
|
||||
|
||||
Derived from the full loop-detector schematic (loop-detector.kicad_sch):
|
||||
J1 (coil) -> TVS1 -> T1 (matching xfmr) -> Colpitts osc (Q1 + C1/C2/Cc2)
|
||||
-> LM393 squarer (U1) -> F_OUT with pullup R7 -> J2 (VCC/GND/F_OUT)
|
||||
"""
|
||||
import re, uuid, os
|
||||
|
||||
BASE = os.path.dirname(os.path.abspath(__file__))
|
||||
SYM = os.path.join(BASE, "loopdet.kicad_sym")
|
||||
SCH = os.path.join(BASE, "osc-module.kicad_sch")
|
||||
|
||||
def uid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
# ---------- extract lib_symbols from loopdet.kicad_sym ----------
|
||||
data = open(SYM, encoding="utf-8").read()
|
||||
pat = re.compile(r'\(symbol "([^"]+)"')
|
||||
sym_blocks = []
|
||||
for m in pat.finditer(data):
|
||||
prefix = data[:m.start()]
|
||||
d = prefix.count('(') - prefix.count(')')
|
||||
if d == 1:
|
||||
start = m.start()
|
||||
depth = 0
|
||||
j = start
|
||||
while j < len(data):
|
||||
if data[j] == '(':
|
||||
depth += 1
|
||||
elif data[j] == ')':
|
||||
depth -= 1
|
||||
if depth == 0:
|
||||
break
|
||||
j += 1
|
||||
sym_blocks.append(data[start:j+1])
|
||||
|
||||
# keep only the symbols the oscillator module needs
|
||||
WANT = {"C", "COMP", "CONN2", "Q_NPN", "R", "TVS_BI", "XFMR"}
|
||||
def top_name(block):
|
||||
m = re.search(r'\(symbol "([^"]+)"', block)
|
||||
return m.group(1) if m else ""
|
||||
kept = [b for b in sym_blocks if top_name(b) in WANT]
|
||||
|
||||
def _prefix(sym_block):
|
||||
return re.sub(r'\(symbol "([^"]+)"', r'(symbol "loopdet:\1"', sym_block, count=1)
|
||||
|
||||
CONN3 = ''' (symbol "loopdet:CONN3"
|
||||
(pin_numbers hide) (pin_names (offset 0))
|
||||
(in_bom yes)
|
||||
(on_board yes)
|
||||
(property "Reference" "J" (at -2.54 6.35 0) (effects (font (size 1.27 1.27)) (justify left)))
|
||||
(property "Value" "J" (at -2.54 -6.35 0) (effects (font (size 1.27 1.27)) (justify left)))
|
||||
(property "Footprint" "" (at 0 0 0) (effects (font (size 1.27 1.27)) hide))
|
||||
(property "Datasheet" "" (at 0 0 0) (effects (font (size 1.27 1.27)) hide))
|
||||
(symbol "CONN3_0_1"
|
||||
(polyline (pts (xy -3.81 -5.08) (xy -3.81 5.08))
|
||||
(stroke (width 0.254) (type default)) (fill (type none)))
|
||||
(circle (center -2.54 -2.54) (radius 1.27)
|
||||
(stroke (width 0.254) (type default)) (fill (type none)))
|
||||
(circle (center -2.54 0) (radius 1.27)
|
||||
(stroke (width 0.254) (type default)) (fill (type none)))
|
||||
(circle (center -2.54 2.54) (radius 1.27)
|
||||
(stroke (width 0.254) (type default)) (fill (type none)))
|
||||
)
|
||||
(symbol "CONN3_1_1"
|
||||
(pin passive line (at -2.54 -2.54 0) (length 1.27)
|
||||
(name "~" (effects (font (size 1.27 1.27))))
|
||||
(number "1" (effects (font (size 1.27 1.27)))))
|
||||
(pin passive line (at -2.54 0 0) (length 1.27)
|
||||
(name "~" (effects (font (size 1.27 1.27))))
|
||||
(number "2" (effects (font (size 1.27 1.27)))))
|
||||
(pin passive line (at -2.54 2.54 0) (length 1.27)
|
||||
(name "~" (effects (font (size 1.27 1.27))))
|
||||
(number "3" (effects (font (size 1.27 1.27)))))
|
||||
)
|
||||
)'''
|
||||
|
||||
lib_symbols = "(lib_symbols\n" + "\n".join(" " + _prefix(b) for b in kept) + "\n" + CONN3 + "\n)\n"
|
||||
|
||||
# ---------- components ----------
|
||||
# (lib, ref, value, x, y, rot)
|
||||
COMPONENTS = [
|
||||
("CONN2", "J1", "接线圈(3~5匝)", 30, 120, 0),
|
||||
("TVS_BI", "TVS1", "TVS", 55, 120, 0),
|
||||
("XFMR", "T1", "1:1 匹配变压器", 85, 120, 0),
|
||||
("C", "C1", "100~470p", 110, 120, 90),
|
||||
("Q_NPN", "Q1", "S9018", 135, 120, 0),
|
||||
("R", "Rc", "2.2k", 145, 116.2, 0),
|
||||
("R", "Rb1", "100k", 131, 111.5, 90),
|
||||
("R", "Rb2", "47k", 131, 128.5, 90),
|
||||
("R", "Re", "1k", 139, 130, 90),
|
||||
("C", "C2", "100p", 145, 125.5, 90),
|
||||
("C", "Cc2", "10p", 153, 116.2, 0),
|
||||
("COMP", "U1", "LM393", 178, 120, 0),
|
||||
("R", "R3", "10k", 158, 114, 90),
|
||||
("R", "R4", "10k", 158, 130, 90),
|
||||
("R", "R7", "10k 上拉", 196, 114, 0),
|
||||
("CONN3", "J2", "VCC/GND/F_OUT", 225, 120, 0),
|
||||
]
|
||||
|
||||
# ---------- wires ----------
|
||||
WIRES = [
|
||||
# coil side: J1 - TVS1 - T1 primary
|
||||
((27.46, 117.46), (77.38, 117.46)), # A: J1.p1 - TVS1.p1 - T1.p1
|
||||
((52.46, 117.46), (52.46, 120)),
|
||||
((27.46, 122.54), (77.38, 122.54)), # B: J1.p2 - TVS1.p2 - T1.p2
|
||||
((57.54, 122.54), (57.54, 120)),
|
||||
# T1 secondary upper: p3 - C1.p1 - base node
|
||||
((92.62, 117.46), (113, 117.46)),
|
||||
((113, 117.46), (113, 120)),
|
||||
((113, 120), (131, 120)),
|
||||
# T1 secondary lower: p4 - C1.p2 - GND
|
||||
((92.62, 122.54), (107, 122.54)),
|
||||
((107, 122.54), (107, 138)),
|
||||
# VCC bus
|
||||
((95, 105), (245, 105)),
|
||||
((145, 116.2), (145, 105)),
|
||||
((131, 108.96), (131, 105)),
|
||||
((158, 111.46), (158, 105)),
|
||||
((193.46, 114), (193.46, 105)),
|
||||
((222.46, 117.46), (222.46, 105)),
|
||||
# GND bus
|
||||
((95, 138), (245, 138)),
|
||||
((131, 131.04), (131, 138)),
|
||||
((139, 132.54), (139, 138)),
|
||||
((145, 128.04), (145, 138)),
|
||||
((158, 132.54), (158, 138)),
|
||||
((222.46, 122.54), (222.46, 138)),
|
||||
# base node
|
||||
((131, 114.04), (131, 125.96)),
|
||||
# collector
|
||||
((139, 116.2), (150.46, 116.2)),
|
||||
((145, 116.2), (145, 122.96)),
|
||||
# emitter
|
||||
((139, 123.81), (139, 127.46)),
|
||||
# comp in+
|
||||
((155.54, 116.2), (170.38, 116.2)),
|
||||
((170.38, 116.2), (170.38, 117.46)),
|
||||
# vref
|
||||
((158, 116.54), (158, 125.96)),
|
||||
((158, 122.54), (170.38, 122.54)),
|
||||
# comp out -> R7 -> J2
|
||||
((185.62, 120), (185.62, 114)),
|
||||
((185.62, 114), (193.46, 114)),
|
||||
((198.54, 114), (222.46, 114)),
|
||||
((222.46, 114), (222.46, 117.46)),
|
||||
]
|
||||
|
||||
# ---------- net labels ----------
|
||||
LABELS = [
|
||||
("VCC", (95, 105), 0),
|
||||
("GND", (95, 138), 0),
|
||||
("VCC", (222.46, 130.54), 0),
|
||||
("GND", (222.46, 134.96), 0),
|
||||
("F_OUT", (222.46, 112.54), 0),
|
||||
]
|
||||
|
||||
# ---------- texts ----------
|
||||
TEXTS = [
|
||||
("振荡模块原理图 — 板框最小版(从环路车检器全图截取)", (20, 20), 3.5),
|
||||
("信号链:线圈 → TVS1 → T1 匹配变压器 → 考毕兹振荡(Q1) → LM393 整形 → F_OUT", (20, 30), 1.5),
|
||||
("接路面环形线圈(3~5匝,双绞屏蔽线 ≤20m)", (20, 100), 1.27),
|
||||
("【设计说明】", (20, 155), 1.5),
|
||||
("1) 本模块仅含振荡+整形部分,供电 VCC 3.3~5V,输出 F_OUT 为方波(频率 = 谐振频率);", (20, 163), 1.27),
|
||||
("2) 频率计数/判车逻辑由外部 MCU 完成(见主原理图);", (20, 171), 1.27),
|
||||
("3) R7 为 LM393 开漏输出上拉,必须保留;", (20, 179), 1.27),
|
||||
("4) C1 决定谐振频率 f0 ≈ 1/(2π√(L·C1)),20~150kHz(待现场验证);", (20, 187), 1.27),
|
||||
("5) TVS1 保护线圈侧浪涌;T1 隔离耦合抗地环路。", (20, 195), 1.27),
|
||||
]
|
||||
|
||||
# ---------- build ----------
|
||||
def fmt_xy(p):
|
||||
return f"(xy {p[0]:g} {p[1]:g})"
|
||||
|
||||
parts = []
|
||||
ROOT_UUID = uid()
|
||||
parts.append("(kicad_sch")
|
||||
parts.append(" (version 20230121)")
|
||||
parts.append(" (generator eeschema)")
|
||||
parts.append(f" (uuid {ROOT_UUID})")
|
||||
parts.append(' (paper "A4")')
|
||||
parts.append(" (title_block")
|
||||
parts.append(' (title "Oscillator Module")')
|
||||
parts.append(' (date "2026-08-24")')
|
||||
parts.append(' (rev "1.0")')
|
||||
parts.append(' (company "xde")')
|
||||
parts.append(' (comment 1 "LC Osc + LM393 squarer, standalone")')
|
||||
parts.append(" )")
|
||||
parts.append("")
|
||||
parts.append(lib_symbols.rstrip("\n"))
|
||||
parts.append("")
|
||||
PINMAP = {
|
||||
"R": ["1", "2"], "C": ["1", "2"], "TVS_BI": ["1", "2"],
|
||||
"Q_NPN": ["B", "C", "E"], "XFMR": ["1", "2", "3", "4"],
|
||||
"COMP": ["+", "-", "OUT"], "CONN2": ["1", "2"], "CONN3": ["1", "2", "3"],
|
||||
}
|
||||
for lib, ref, value, x, y, rot in COMPONENTS:
|
||||
parts.append(" (symbol")
|
||||
parts.append(f" (lib_id \"loopdet:{lib}\")")
|
||||
parts.append(f" (at {x:g} {y:g} {rot})")
|
||||
parts.append(" (unit 1)")
|
||||
parts.append(" (in_bom yes)")
|
||||
parts.append(" (on_board yes)")
|
||||
parts.append(" (dnp no)")
|
||||
parts.append(f" (uuid {uid()})")
|
||||
parts.append(f" (property \"Reference\" \"{ref}\" (at {x:g} {y+6:g} 0) (effects (font (size 1.27 1.27)) (justify left)))")
|
||||
parts.append(f" (property \"Value\" \"{value}\" (at {x:g} {y-6:g} 0) (effects (font (size 1.27 1.27)) (justify left)))")
|
||||
parts.append(f" (property \"Footprint\" \"\" (at {x:g} {y:g} 0) (effects (font (size 1.27 1.27)) hide))")
|
||||
parts.append(f" (property \"Datasheet\" \"\" (at {x:g} {y:g} 0) (effects (font (size 1.27 1.27)) hide))")
|
||||
for pn in PINMAP[lib]:
|
||||
parts.append(f" (pin \"{pn}\" (uuid {uid()}))")
|
||||
parts.append(" (instances")
|
||||
parts.append(" (project \"osc-module\"")
|
||||
parts.append(f" (path \"/{ROOT_UUID}\"")
|
||||
parts.append(f" (reference \"{ref}\") (unit 1)")
|
||||
parts.append(" )")
|
||||
parts.append(" )")
|
||||
parts.append(" )")
|
||||
parts.append(" )")
|
||||
parts.append("")
|
||||
for p1, p2 in WIRES:
|
||||
parts.append(" (wire")
|
||||
parts.append(f" (pts {fmt_xy(p1)} {fmt_xy(p2)})")
|
||||
parts.append(" (stroke (width 0) (type default))")
|
||||
parts.append(f" (uuid {uid()})")
|
||||
parts.append(" )")
|
||||
parts.append("")
|
||||
for name, pos, ang in LABELS:
|
||||
parts.append(" (label")
|
||||
parts.append(f" \"{name}\" (at {pos[0]:g} {pos[1]:g} {ang})")
|
||||
parts.append(" (effects (font (size 1.27 1.27)) (justify left bottom))")
|
||||
parts.append(f" (uuid {uid()})")
|
||||
parts.append(" )")
|
||||
parts.append("")
|
||||
for s, pos, size in TEXTS:
|
||||
parts.append(" (text")
|
||||
parts.append(f" \"{s}\" (at {pos[0]:g} {pos[1]:g} 0)")
|
||||
parts.append(f" (effects (font (size {size:g} {size:g})))")
|
||||
parts.append(f" (uuid {uid()})")
|
||||
parts.append(" )")
|
||||
parts.append("")
|
||||
parts.append(" (sheet_instances")
|
||||
parts.append(' (path "/" (page "1"))')
|
||||
parts.append(" )")
|
||||
parts.append(")")
|
||||
|
||||
out = "\n".join(parts) + "\n"
|
||||
open(SCH, "w", encoding="utf-8").write(out)
|
||||
print("wrote", SCH, len(out), "bytes")
|
||||
Reference in New Issue
Block a user