fig(family): 六型号总览图 + PD132T↔PD136HA 档位对齐图;待实测清单 ⑧

- docs/img/family-overview.{svg,png}(tools/plot_family_overview.py)
  面板A 窗长/τ 条形;面板B 检测延迟 vs Δf/f(六型号按各自档0 判据);
  归一化延迟表(@1.1× / @2× / @10× 判据)+ 进入确认与口径脚注
  关键:@10×(强信号) 全部=1 窗 ⇒ 8.2/8.7/10.0/10.9/21.9/27.3ms;@1.1×(近阈值) 7~9 窗 ⇒ M1H 57ms ~ PD136HA 197ms
- docs/img/sens-alignment-pd132t-pd136ha.{svg,png}(tools/plot_sens_alignment.py)
  四档 进入/离开 双段条形 + 同档偏差(−46%~+69%) + 最近档映射 + 换型 4 步 + 两端档无对应警示
- 待实测清单新增 ⑧ 弱信号复测(0.10% 车:PD132T 档1 ≈76ms 应检出 / PD136HA 档1 应检不到)
- 文档接入:cross-model-comparison.md 新增「六型号总览图」节;comparison §5.4 嵌入对齐图;measurement doc §10 加指引
- README tools 段补 3 个绘图脚本;表格校验 0 异常(16 文件)
This commit is contained in:
wangfq
2026-09-11 11:27:58 +08:00
parent 9c88b1d7b0
commit db5e108620
10 changed files with 720 additions and 1 deletions
+140
View File
@@ -0,0 +1,140 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""PD132T ↔ PD136HA 灵敏度档位对齐图(现场调档照着贴)—— 纯 stdlib 手写 SVG
横轴 = Δf/f(进入/离开阈值的相对频偏,%);每档画 进入(实心)+离开(浅色) 两段
偏差 = 同档位号一对一映射的 (H−T)/T;最佳匹配 = 最近的进入阈值
转 PNGchromium --headless=new --disable-gpu --no-sandbox \
--screenshot=docs/img/sens-alignment-pd132t-pd136ha.png --window-size=1500,880 \
file://$PWD/docs/img/sens-alignment-pd132t-pd136ha.svg
"""
W, H = 1500, 1060
FONT = "'Noto Serif CJK SC','Noto Sans CJK SC',sans-serif"
K = 65536.0
out = []
def esc(s):
return s.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
def txt(x, y, s, size=14, fill='#222', anchor='start', weight='normal'):
out.append('<text x="%.1f" y="%.1f" font-size="%s" fill="%s" text-anchor="%s" font-weight="%s" font-family="%s">%s</text>'
% (x, y, size, fill, anchor, weight, FONT, esc(s)))
def line(x1, y1, x2, y2, stroke='#999', w=1.0, dash=None):
d = ' stroke-dasharray="%s"' % dash if dash else ''
out.append('<line x1="%.1f" y1="%.1f" x2="%.1f" y2="%.1f" stroke="%s" stroke-width="%s"%s/>' % (x1, y1, x2, y2, stroke, w, d))
def rect(x, y, w, h, fill='none', stroke='none', rx=2, sw=1.0, op=1.0):
out.append('<rect x="%.1f" y="%.1f" width="%.1f" height="%.1f" rx="%s" fill="%s" fill-opacity="%s" stroke="%s" stroke-width="%s"/>'
% (x, y, w, h, rx, fill, op, stroke, sw))
def note(x, y, w, h, title, lines_, color='#0b6'):
rect(x, y, w, h, '#fbfdff', color, rx=6, sw=1.2, op=0.95)
txt(x + 12, y + 24, title, 14.5, color, weight='bold')
for i, s in enumerate(lines_):
txt(x + 12, y + 48 + i * 21, s, 13, '#333')
T_IN = [300, 60, 32, 21] # PD132T 进入表(档0..3
T_OUT = [60, 32, 21, 14] # PD132T 离开表
H_IN = [162, 81, 54, 28] # PD136HA 进入表
H_OUT = [81, 54, 32, 18] # PD136HA 离开表
ct = lambda v: v / K * 100.0
out.append('<svg xmlns="http://www.w3.org/2000/svg" width="%d" height="%d" viewBox="0 0 %d %d">' % (W, H, W, H))
out.append('<rect width="%d" height="%d" fill="#ffffff"/>' % (W, H))
txt(30, 44, 'PD132T ↔ PD136HA 灵敏度档位对齐图(判据 = 表值/65536 的 Δf/f', 24, '#111', weight='bold')
txt(30, 72, '每档画两段:深色 = 离开阈值(回差下沿),浅色 = 进入阈值(回差上沿);横轴 0~0.5%(线性)', 13, '#555')
line(30, 86, W - 30, 86, '#ddd', 1.2)
# ================== 轴 ==================
AX0, AX1 = 380.0, 1230.0
VMAX = 0.50
ax = lambda v: AX0 + (v / VMAX) * (AX1 - AX0)
GY0, GGH = 118.0, 116.0
for g in [0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5]:
x = ax(g)
line(x, 112, x, 112 + 4 * GGH, '#ececec', 1.0)
txt(x, 112 + 4 * GGH + 22, ('%.2f' % g), 12, '#777', anchor='middle')
txt((AX0 + AX1) / 2, 112 + 4 * GGH + 46, 'Δf/f%)—— 数值越大越钝(越不易触发)', 13, '#555', anchor='middle')
# ================== 四档 ==================
COLT, COLH = '#1565c0', '#e65100'
for i in range(4):
gy = GY0 + i * GGH
viT, voT = ct(T_IN[i]), ct(T_OUT[i])
viH, voH = ct(H_IN[i]), ct(H_OUT[i])
dev = (viH - viT) / viT * 100.0
# 分组背景
if i % 2 == 0:
rect(40, gy - 8, W - 80, GGH - 12, '#fafafa', rx=6, sw=0)
txt(60, gy + 52, '%d' % i, 17, '#111', weight='bold')
# --- PD132T 行 ---
yT = gy + 6
rect(AX0, yT, ax(voT) - AX0, 17, COLT, rx=2, op=0.30)
rect(AX0, yT, ax(viT) - AX0, 17, COLT, rx=2, op=0.85)
txt(AX0 - 10, yT + 14, 'PD132T', 13.5, COLT, anchor='end', weight='bold')
txt(ax(viT) + 8, yT + 14, '进入 %.4f%% 离开 %.4f%%' % (viT, voT), 12.5, COLT)
# --- PD136HA 行 ---
yH = gy + 52
rect(AX0, yH, ax(voH) - AX0, 17, COLH, rx=2, op=0.30)
rect(AX0, yH, ax(viH) - AX0, 17, COLH, rx=2, op=0.85)
txt(AX0 - 10, yH + 14, 'PD136HA', 13.5, COLH, anchor='end', weight='bold')
txt(ax(viH) + 8, yH + 14, '进入 %.4f%%' % viH, 12.5, COLH)
# 同档偏差标注 + 连接线
line(ax(viT), yT + 17, ax(viH), yH, '#999', 1.2, '4,3')
badge_col = '#c1121f' if abs(dev) >= 30 else ('#b8860b' if abs(dev) >= 15 else '#0b6')
txt(AX1 + 16, gy + 40, '同档偏差 %+.0f%%' % dev, 14, badge_col, weight='bold')
# 最佳匹配说明
txt(W - 30, GY0 + 4 * GGH + 10, '最佳匹配:档 1 → 档 2(−10.0%', 13, '#0b6', anchor='end')
txt(W - 30, GY0 + 4 * GGH + 32, '两端档 0 / 3 无对应档 ⇒ 必须复测', 13, '#c1121f', anchor='end')
line(AX1 + 4, 112, AX1 + 4, 112 + 4 * GGH, '#ccc', 1.0)
# ================== 对照表 ==================
TY = 660.0
txt(40, TY, '档位对照表(现场照着贴)', 17, '#111', weight='bold')
COLS = [(60, '档位'), (150, 'PD132T 进入'), (290, 'PD132T 离开'), (430, 'PD136HA 进入'), (570, 'PD136HA 离开'),
(710, '同档偏差'), (860, '等效替代(最近进入阈值)')]
for x, s in COLS:
txt(x, TY + 30, s, 13.5, '#555', weight='bold')
line(40, TY + 40, W - 40, TY + 40, '#ccc', 1.0)
for i in range(4):
y = TY + 66 + i * 36
viT, voT, viH, voH = ct(T_IN[i]), ct(T_OUT[i]), ct(H_IN[i]), ct(H_OUT[i])
dev = (viH - viT) / viT * 100.0
j = min(range(4), key=lambda k: abs(H_IN[k] - T_IN[i]))
dev2 = (ct(H_IN[j]) - viT) / viT * 100.0
txt(60, y, '%d' % i, 14, '#111', weight='bold')
txt(150, y, '%.4f %%' % viT, 13, '#1565c0')
txt(290, y, '%.4f %%' % voT, 13, '#777')
txt(430, y, '%.4f %%' % viH, 13, '#e65100')
txt(570, y, '%.4f %%' % voH, 13, '#777')
txt(710, y, '%+.1f %%' % dev, 13.5, ('#c1121f' if abs(dev) >= 30 else '#b8860b'), weight='bold')
txt(860, y, 'PD136HA 档 %d%+.1f%%' % (j, dev2), 13, '#0b6')
line(40, TY + 66 + 4 * 36 - 16, W - 40, TY + 66 + 4 * 36 - 16, '#ccc', 1.0)
# ================== 脚注 ==================
note(40, TY + 66 + 4 * 36 + 4, 700, 128, '换型动作(4 步)', [
'① 先算目标:原型号档位 → 百分比 = 表值 / 65536',
'② 在新型号表里找最接近的档(偏差 ≤15% 可接受;>30% 必须复测)',
'③ 用 §5.5 公式预估响应:延迟 = (n+1)×窗长(n 由 信号/判据 比决定)',
'④ 强信号车 + 弱信号车各复测 3 次(记录 判据越线→继电器 实测耗时)',
], '#c1121f')
note(760, TY + 66 + 4 * 36 + 4, 700, 128, '两端档位无对应(必须注意)', [
'档0(最钝):PD132T 0.4578% ↔ PD136HA 0.2472%(钝 46%',
' ⇒ 依赖「最钝档防误触发」的现场,换型后须重新评估误触发率',
'档3(最灵敏):PD132T 0.0320% ↔ PD136HA 0.0427%(钝 33%',
' ⇒ 依赖「最高灵敏」的现场,PD136HA 可能检不到弱信号车(§5.5 ⑧)',
], '#e65100')
OPEN = 'docs/img/sens-alignment-pd132t-pd136ha.svg'
out.append('</svg>')
open(OPEN, 'w', encoding='utf-8').write('\n'.join(out))
print('已写出 %s' % OPEN)
for i in range(4):
viT, viH = ct(T_IN[i]), ct(H_IN[i])
j = min(range(4), key=lambda k: abs(H_IN[k] - T_IN[i]))
print('%d: PD132T %.4f%% ↔ PD136HA %.4f%%(同档 %+.1f%%| 最近档 %d%+.1f%%'
% (i, viT, viH, (viH - viT) / viT * 100, j, (ct(H_IN[j]) - viT) / viT * 100))