TT Lab
开始
学习 学习路径 课程

电子电路入门 — 传感器输入验证

补偿探头就能看到原来的电路吗?

在 TT Lab 中继续学习

目标

把补偿后的屏幕显示准确这一事实,与几乎没有改变原来的电路这一事实,分开验证。读取真实的 ngspice 文件,编写能够重现探头选择依据的 Python CLI。

为什么重要

请在掌握前面的滤波器响应单元,以及 Python 函数、文件、复数、list、dict、异常之后再开始。本实验预计需要 120 分钟。可以在默认的 60 分钟结束之前,用“+时间”延长,最多 180 分钟。会话结束后文件会消失,所以请另行保存需要的代码和报告。本实验只使用理想的 1V 电路仿真,不涉及真实设备、高电压和接地连接。

环境与素材

产出物是 /root/probe-loading/analyze.py。镜像中带有 Python3 和 ngspice42,不需要外部下载或额外权限。把 /opt/lab/fixtures/probe_loading 加入 sys.path,就可以 import simulator。提供的 capture(cfg,新文件夹) 会运行真实的电路,并返回该文件夹的 Path。父文件夹必须已存在,并且不会覆盖已有的输出文件夹。会留下 input.cir、config.json、solver.log、ac.tsv、step.tsv,失败时新产生的证据也不会被删除。

电路结构和数值是前面理论中的理想模型。同一个理想输入,经过各自独立的 Rs,驱动参考 ref 和被测对象 tip。两个节点各自的 DUT 都是 100kΩ∥20pF。探头只接在 tip 一侧。unloaded 没有额外负载,meter=tip;one-x 是 1MΩ∥100pF;active 是 1MΩ∥1pF 并且理想 meter=tip。ten-x 在 tip→meter 之间有 9MΩ∥comp_pf,在 meter→地之间有 1MΩ∥90pF。显示值在 ten-x 中是 meter×10,其余是 meter。

AC 输入是 ac_v 幅度、17 度相位。阶跃在 0 到 1µs 为 0V,之后在 5ns 内上升到 1V,并保持到 50µs。ac_v 只适用于 AC 分析。active 的无限带宽和理想输出,是教学模型,并不是商用产品的规格。

配置契约

config 只接受恰好包含下面 5 个键的 dict。数值只允许 int、float,bool、字符串、NaN、无穷大、超出 float 转换范围,都是 ValueError。数值以 float 返回,kind 是 str,没有补偿时 comp_pf 以 None 返回。不要修改输入。

键 允许的值
kind unloaded、one-x、ten-x、active
rs_ohm 10000 或 50000
comp_pf ten-x 时为 5、10、20;其余只能是 None
dt_s 1.25e-9 或 6.25e-10
ac_v 0.5、1、2

AC 输入与响应契约

read_ac 接收普通文件、最大 1MiB。表头是以空白分隔的 frequency v(in) v(in) v(ref) v(ref) v(tip) v(tip) v(meter) v(meter)。每一对按实部、虚部的顺序。忽略空行,并读取恰好 241 行、每行 9 个有限 float。电压分量绝对值必须在 1e6 以下,输入、ref、tip 的复数幅度必须在 1e-12 以上。meter 可以是 0。频率为正且严格递增,在每个 i=0..240 处,必须与 10*10**(i/40) 在相对 1e-10 或绝对 1e-9 以内相同。请确认 10Hz 到 10MHz 的所有内部网格。内容错误为 ValueError,操作系统的文件错误可以原样传递。返回的是由 9 个 float 组成的 tuple 的 list。

response 验证配置,并按上面的契约接收已验证的 rows。不要修改行,并按相同顺序返回 dict 列表。设 R=Vref/Vin、T=Vtip/Vin、D=倍率*Vmeter/Vin,则各字段如下。

模型与阶跃观测契约

transfer 用 config 检查配置,并接收 0≤freq≤1e9 的有限数值。bool、字符串、超出范围为 ValueError。这个频率范围是理想公式的计算区域,并不表示探头真实的 1GHz 带宽。仿真文件的网格另外限制为上面的 10Hz 到 10MHz。请区分这两个契约,使得即使输出四舍五入导致 10MHz 的端点略微偏大,模型函数也不会拒绝有效的 AC 文件。

返回的是以 reference、tip、meter 为键的 complex dict。s=2jπf,Ydut=1/100000+s20e-12,R=1/(1+RsYdut)。unloaded 的三个值都是 R。one-x、active 的 Yprobe=1/1e6+sCprobe,Cprobe 分别是 100e-12、1e-12。T=1/(1+Rs(Ydut+Yprobe)),M=T。ten-x 的 Za=1/(1/9e6+scomp_pf1e-12),Zb=1/(1/1e6+s90e-12),T=1/(1+Rs(Ydut+1/(Za+Zb))),M=T*Zb/(Za+Zb)。meter 上还没有应用显示倍率。

提供的 load_step(path) 返回表头为 time v(in) v(ref) v(tip) v(meter) 的 5 列 tuple 列表,要求是普通文件、最大 16MiB。2 到 200000 行,全部是有限数值,电压分量绝对值≤1e6,时间不小于 0 且严格递增,第一个时间≤1ns,最后一个必须与 50µs 在 1e-12 秒以内。内容错误为 ValueError。不需要重新实现这个加载器。

observe 检查配置,并使用 load_step,在 t=1.005e-6+i1e-8(i=0..1999)处,对 ref、tip、meter 做线性插值。时刻恰好相同的行直接读取,外推为 ValueError。返回的有 reference_v、tip_v、display_v(各为 2000 个电压的列表)、grid_step_s=1e-8、observation_end_s=1.005e-6+19991e-8、chain_error_v=max|display−tip|、loading_error_v=max|tip−reference|、display_error_v=max|display−reference|。显示倍率只应用于 display。这是在有限观测网格上的比较,并不是对连续时间整体最大值的证明。

判定与报告契约

assess 验证配置,并接收正常的 response 列表和 observe 报告。不需要重复验证中间报告的结构。下面的要求是本实验声明的设计契约,并不是行业标准的合格线。

analyze(value,folder) 把 config、read_ac(folder/ac.tsv)、response、observe(folder/step.tsv)、assess 连起来。返回的是 schema=1、config、sweep、step、assessment。保留原始配置和文件,错误要传递出去。

条件比较与 CLI 契约

campaign(values,runner) 先验证由 2 到 6 个配置组成的严格 list 的全部内容。所有输入的 dt_s 必须是默认的 1.25e-9,只要有一个不对,就在调用 runner 之前抛出 ValueError。对每个条件,依次执行 runner(基本配置副本)→analyze,以及用只把 dt_s 改为 6.25e-10 的新配置执行 runner→analyze。一个条件结束之后,再转到下一个条件。不要修改原始输入,runner 的错误要传递。

返回的是 schema=1、runs、candidate_indices、scope='ideal-probe-chain-and-loaded-circuit'。runs 按输入顺序,包含 coarse、fine(各自的 analyze 报告)、difference_v(三个电压列表中相同时刻之差的最大值)、converged(difference_v≤1e-5V)。不仅要比较显示值,还要比较 reference_v 和 tip_v。candidate_indices 是已收敛、并且 coarse 与 fine 的 assessment.all_pass 都为 True 的条件的从 0 开始的索引列表。空的候选是正常结果,与运行错误不同。

main(argv) 接收设置列表的 JSON 文件,以及尚不存在的输出文件夹路径。确认参数个数、所有配置和默认 dt 之后,再创建新文件夹。父文件夹必须已存在,并且拒绝已有的文件夹。按 runner 的调用顺序,在 run-00、run-01、…… 中运行提供的 capture。把结果以一行有效的 JSON 输出到 stdout,并返回 0。参数、配置、文件、运行的 Exception,要返回一行 {"error":"analysis_failed"} 和 2,并且不输出 traceback。即使失败,也不要删除已经生成的新证据。import 时不会执行 CLI,只在直接运行时,才以 main 的返回值退出。

请像下面这样用新名称运行提供的 /opt/lab/fixtures/probe_loading/cases.json 中的六个条件。重定向报告时,也要选择不会覆盖已有文件的路径。

python3 /root/probe-loading/analyze.py /opt/lab/fixtures/probe_loading/cases.json /root/probe-loading/trial-01 > /root/probe-loading/report-01.json

步骤

  1. 在运行之前验证探头条件:实现 config(value)。检查下面的配置契约,并返回把数值转换为 float 的新 dict。保留原始输入,错误的值以 ValueError 拒绝。
  2. 读取输入和三个节点的复数电压:添加 read_ac(path)。检查下面 9 列、241 行和频率网格的契约,并返回 float tuple 的列表。
  3. 区分屏幕误差与负载误差:添加 response(value,rows)。按下面的格式返回以输入归一化的 reference、tip、display,以及复数比值误差、幅度和相位。
  4. 计算接上探头的电路:添加 transfer(value,freq)。在理论中包含负载的模型里,以 complex 值返回 reference、tip、meter 的传递函数。
  5. 在相同时刻比较三个波形:添加 observe(value,path)。用提供的 load_step 读取波形,并计算指定的 2000 个时刻的三个电压及其最大差。
  6. 区分模型一致与设计适用性:添加 assess(value,sweep,step)。分别判定完整的复数模型验证、100kHz 的测量链与负载要求、阶跃要求、候选资格。
  7. 根据原始文件连接分析报告:添加 analyze(value,folder)。把配置、AC、阶跃的分析与判定连起来,返回连中间结果也保留的报告。
  8. 对照两种精度与真实运行:添加 campaign(values,runner)、main(argv) 和 CLI 入口。先验证全部配置,再选出同时满足基本与精细计算中三个节点的收敛,以及两侧适用性的候选。

参考

评分把使用独立公式和合成文件的函数检查,与真实 ngspice 和单独 CLI 的检查区分开来。不会修改学员的代码和文件夹。如果把默认条件的候选索引硬编码,在其他源电阻、幅度、补偿条件下就会失败。这个模型无法认证真实探头的安全等级、接地、噪声、带宽和温度可靠性。

在运行之前验证探头条件

实现 config(value)。检查下面的配置契约,并返回把数值转换为 float 的新 dict。保留原始输入,错误的值以 ValueError 拒绝。

bool 是 int 的子类型,但并不是这个契约中的数值。补偿 C 只存在于 ten-x。

读取输入和三个节点的复数电压

添加 read_ac(path)。检查下面 9 列、241 行和频率网格的契约,并返回 float tuple 的列表。

参考节点和 tip 也是除法的分母。不仅要检查表头和两端,还要确认所有内部频率。

区分屏幕误差与负载误差

添加 response(value,rows)。按下面的格式返回以输入归一化的 reference、tip、display,以及复数比值误差、幅度和相位。

10 倍显示只应用于 meter。即使幅度比是 1,只要相位不同,复数误差就不是 0。

计算接上探头的电路

添加 transfer(value,freq)。在理论中包含负载的模型里,以 complex 值返回 reference、tip、meter 的传递函数。

即使补偿时间常数相同,探头的输入阻抗也不是无穷大。请计算与 DUT 并联的探头负载。

在相同时刻比较三个波形

添加 observe(value,path)。用提供的 load_step 读取波形,并计算指定的 2000 个时刻的三个电压及其最大差。

不要把输入电压列读成参考电压。原始时间列表只构造一次,就能加快插值查找。

区分模型一致与设计适用性

添加 assess(value,sweep,step)。分别判定完整的复数模型验证、100kHz 的测量链与负载要求、阶跃要求、候选资格。

unloaded 是比较基准。即使误差最小,也不是可以购买或连接的探头候选。

根据原始文件连接分析报告

添加 analyze(value,folder)。把配置、AC、阶跃的分析与判定连起来,返回连中间结果也保留的报告。

如果把 ten-x 换成 unloaded 再交给阶跃分析,屏幕倍率就消失了。请把同一个配置一直传递到底。

对照两种精度与真实运行

添加 campaign(values,runner)、main(argv) 和 CLI 入口。先验证全部配置,再选出同时满足基本与精细计算中三个节点的收敛,以及两侧适用性的候选。

不要用基本计算的成功,去覆盖精细计算中被淘汰的结果。还要检查生成的原始资料与报告是否一致。