TT Lab
はじめる
学ぶ 学習パス コース

電子回路入門 — センサー入力の検証

RCを2段つなげば解決する?

TT Labで続きを見る

目標

温室センサー用のフィルターを、次数・負荷・周波数・時間応答で比較し、実際のngspiceの資料を保存した検証CLIを作ります。

なぜ重要なのか

前のエイリアシングの単元と、Pythonの関数・ファイル・複素数・list・dict・例外を理解してから進めてください。ラボは120分を想定しているので、基本の60分が終わる前に、+時間で延長してください。最大は180分で、セッションが終了するとファイルが消えます。必要なコードとレポートを、別に保管してください。実際の機器や物理的な電圧は扱いません。

環境とファイル

成果物は、/root/filter-response/analyze.pyです。Python3とngspice(バージョン42)がイメージにあり、外部からのダウンロードや追加の権限は必要ありません。/opt/lab/fixtures/filter_responseをsys.pathに追加すれば、simulatorをimportできます。提供されるcapture(cfg,新しいフォルダー)は、実際の回路を実行して、出力フォルダーのPathを返します。その中に、input.cir・config.json・solver.log・ac.tsv・pass.tsv・stop.tsv・step.tsvを残します。既存のフォルダーは上書きせず、親はすでにある必要があります。

回路は、理論にある4つの構造そのままです。AC入力は、ac_vの振幅と23度の位相です。ステップ入力は、0–1msに0V、次の1µsで1Vに上昇し、50msまで維持されます。理想バッファーは、無限の帯域幅・無制限の出力の制御電圧源であり、実物のオペアンプではありません。

設定の契約

configは、正確に以下の5つのキーを持つdictだけを受け付けます。数値は、intとfloatだけを受け付け、bool・文字列・NaN・無限大・floatの変換範囲の超過を、ValueErrorで拒否します。数値はfloatで返し、topologyはstr、Qがない場合はNoneを維持します。

キー 許容される値
topology rc1、rc2-loaded、rc2-buffered、sk2のうちの1つ
f0_hz 220または300
q sk2なら0.5、1/math.sqrt(2)、1.4のうちの1つ。他の回路はNoneだけ
dt_s 5e-6または2.5e-6
ac_v 0.5、1、2のうちの1つ

f0_hzは周波数の尺度であり、すべての回路の−3dB周波数を意味しません。R=1000Ω、C=1/(2πRf0_hz)です。sk2だけC1=2qC・C2=C/(2q)で、他は理論のように同じRとCを使います。q=1/sqrt(2)は、JSONに0.7071067811865475と記録します。

ACファイルとボード線図の契約

read_acのkindは、sweep・pass・stopのうちの1つです。ファイルは、通常のファイル、最大1MiBで、ヘッダーは、空白で区切ったfrequency v(in) v(in) v(out) v(out)です。空行は無視します。各データ行は、有限のfloat5個、電圧成分の絶対値≤1e6、複素入力の大きさ≥1e-12です。周波数は、正の数で、厳密に増加しなければなりません。内容のエラーはValueError、OSのファイルエラーは、そのまま伝えてもかまいません。

最初の周波数は、明示した値から1e-8Hz以内、最後は1e-7Hz以内でなければなりません。すべての内部の周波数は、指定した格子と、相対1e-10または絶対1e-9以内で等しくなければなりません。開始・終了だけを検査してはいけません。戻り値は、5個のfloatのtupleのlistです。

bodeは、検証済みのrowsを受け取り、元を変更しません。H=complex(出力の実部,出力の虚部)/complex(入力の実部,入力の虚部)です。各戻りdictのキーは、frequency_hz、h_re、h_im、gain=abs(H)、db=20log10(gain)、phase_deg=degrees(atan2(H.imag,H.real))です。gain=0なら、dbとphase_degはNoneです。リストの順序は維持します。

モデルとステップ観測の契約

transferは、configで設定を検証し、0≤freq≤1e6の有限の数値を受け付けます。p=1j*freq/f0_hzのとき、rc1:1/(1+p)、rc2-loaded:1/(1+3p+p²)、rc2-buffered:1/(1+p)²、sk2:1/(1+p/q+p²)を、complexで返します。

提供されるsimulator.load_step(path)は、time v(in) v(out)のヘッダーの、最大8MiB・データ2–100000行を検証して、3列のtupleのリストを返します。すべての値は有限で、電圧の絶対値≤1e6、時間は0以上・厳密な増加です。最初の時間≤1µs、最後は50msから1e-12秒以内でなければなりません。内容のエラーはValueErrorです。学習者が、このローダーを再実装する必要はありません。

measure_stepは、ローダーを使い、t=0.001001+i1e-5(i=0..4899)で、出力電圧を線形補間します。正確な行はそのまま読み、外挿はValueErrorです。返すキーは、samples_v(4900個の電圧)、overshoot_v=max(0,max(samples_v)−1)、settled_at_s、grid_step_s=1e-5、observation_end_s=0.001001+48991e-5です。

settled_at_sは、1.001msの上昇完了を基準にした相対時間です。|電圧−1|>.02である最後の標本の、次のインデックス*1e-5を返します。最後の標本も外ならNone、すべて内側なら0です。これは、観測格子・有限の観測区間での判定であり、連続時間の最大値や、無限時間の安定性の証明ではありません。

判定と分析の契約

assessは、正常な設定、bodeのsweepのリスト、125Hzのwanted dict、875Hzのnuisance dict、measure_stepのstep dictを受け取ります。渡される中間レポートが、上の契約に従うことは前提であり、全体の構造の検証を繰り返す必要はありません。返すキーは、次のとおりです。

analyze(value,folder)は、config、read_ac、bode、measure_step、assessをつなぎます。戻り値は、schema=1、config、sweep、wanted、nuisance、step、assessmentです。ac.tsvはsweep、pass.tsv・stop.tsvはそれぞれpass・stopとして読み、最初の項目をwanted・nuisanceとして使います。元のファイルと元の設定を変更せず、エラーは伝えます。

条件比較とCLIの契約

campaign(values,runner)は、正確にlistの、2–6個の設定を、すべて先に検証します。入力のdt_sは、すべて5e-6でなければなりません。各条件について、runner(基本設定のコピー)→analyze、続けて、dt_sだけを2.5e-6に変えた新しい設定で、runner→analyzeします。1つの条件を終えた後に、次の条件を実行します。runnerの例外は伝え、元の入力は変更しません。

戻り値は、schema=1、runs、candidate_indices、scope='ideal-linear-filters-and-finite-step-observation'です。runsは入力の順で、coarse・fine(それぞれanalyzeのレポート)、difference_v(同じ4900個の時刻の標本の最大絶対差)、converged(差≤1e-5V)を持ちます。candidate_indicesは、収束していて、両方のassessment.all_passがTrueの条件の、0始まりのインデックスのリストです。空の候補は正常な結果であり、実行エラーと区別します。

main(argv)は、設定リストのJSONファイルと、まだ存在しない出力フォルダーのパスを受け取ります。JSONのすべての設定と、既定のdtを確認してから、フォルダーを作ります。親は、すでにある必要があります。runnerの呼び出し順に、run-00、run-01、...の新しいサブフォルダーで、提供されるcaptureを呼び出します。結果をstdoutにJSON1行で出力して、0を返します。引数・設定・ファイル・実行のExceptionなら、{"error":"analysis_failed"}の1行と2を返し、tracebackは出力しません。すでに生成した新しい証拠は、失敗しても消しません。importではCLIを実行せず、直接実行のときだけ、mainの戻り値で終了します。

提供される設定は、/opt/lab/fixtures/filter_response/cases.jsonです。最終ステップで、次のように新しい名前で実行し、レポートと一緒に、元のファイルを確認してください。リダイレクトも、以前のレポートを上書きしないパスを選びます。

python3 /root/filter-response/analyze.py /opt/lab/fixtures/filter_response/cases.json /root/filter-response/trial-01 > /root/filter-response/report-01.json

ステップ

  1. 回路条件を先に検証する: /root/filter-response/analyze.pyに、config(value)を実装します。以下の5つのキーの設定を検証し、数値をfloatに正規化した新しいdictを返します。不正な値はValueErrorで、元の入力は変更しません。
  2. 複素電圧の5つの列を読む: read_ac(path,kind="sweep")を追加します。以下のファイル・格子の契約を検査した後、周波数・入力の実部・入力の虚部・出力の実部・出力の虚部のtupleのlistを返します。
  3. 入力の振幅と位相を取り除く: bode(rows)を追加します。検証済みの各行から、複素の出力/入力を求め、周波数・複素ゲイン・大きさ・dB・位相のリストを、以下の形式で返します。
  4. 負荷を含む伝達関数を計算する: transfer(cfg,freq)を追加します。設定と周波数を検証し、理論の4つの回路の伝達関数を、complexで返します。
  5. 最後の帯域離脱を見つける: measure_step(path)を追加します。提供されるload_stepで元の波形を読み、指定した4900個の時刻で、出力電圧を線形補間します。オーバーシュート電圧・整定時点・観測格子・標本を返します。
  6. 周波数と時間の要求を一緒に判定する: assess(cfg,sweep,wanted,nuisance,step)を追加します。すべてのAC点の複素モデル誤差、2つの要求周波数のゲイン、ステップのオーバーシュート・整定の要求を、別々に計算し、最終的なANDを返します。
  7. ファイルから検証レポートを作る: analyze(value,folder)を追加します。設定と、AC3ファイル・ステップ1ファイルを読んで、全体の分析と判定をつなぎます。エラーは、成功のレポートに変えず、そのまま伝えます。
  8. 2つの計算精度と、実際のCLIをつなぐ: campaign(values,runner)、main(argv)、CLIのエントリーポイントを追加します。すべての設定を検証した後、各回路を5µs・2.5µsで実行し、収束と、両方の設計判定を満たした条件だけを選びます。

参考

採点は、一時ファイルの純粋関数の検査と、実際のngspice・別のCLIの実行を、区別して行います。学習者のコードとフォルダーは変更しません。数値の表をハードコードすると、別の入力振幅・周波数・負荷条件で失敗します。今回の選択は、理想的な線形モデルの中での候補です。実際のアンプの電源・帯域幅・スルーレート・ノイズ・部品の公差・温度の信頼性は、別の検証が必要です。

回路条件を先に検証する

/root/filter-response/analyze.pyに、config(value)を実装します。以下の5つのキーの設定を検証し、数値をfloatに正規化した新しいdictを返します。不正な値はValueErrorで、元の入力は変更しません。

回路の種類ごとに、Qの意味が違います。文字列・boolを、数値のように受け取りません。

複素電圧の5つの列を読む

read_ac(path,kind="sweep")を追加します。以下のファイル・格子の契約を検査した後、周波数・入力の実部・入力の虚部・出力の実部・出力の虚部のtupleのlistを返します。

同じヘッダーが2回出てくる理由は、複素数だからです。開始と終了が合っていても、途中の格子が間違っていることがあります。

入力の振幅と位相を取り除く

bode(rows)を追加します。検証済みの各行から、複素の出力/入力を求め、周波数・複素ゲイン・大きさ・dB・位相のリストを、以下の形式で返します。

20log10とatan2の象限を確認してください。入力の位相23度を、フィルターの位相に残しません。

負荷を含む伝達関数を計算する

transfer(cfg,freq)を追加します。設定と周波数を検証し、理論の4つの回路の伝達関数を、complexで返します。

直接接続は、分母のpの係数が3です。バッファーで分離した場合の2と区別してください。

最後の帯域離脱を見つける

measure_step(path)を追加します。提供されるload_stepで元の波形を読み、指定した4900個の時刻で、出力電圧を線形補間します。オーバーシュート電圧・整定時点・観測格子・標本を返します。

最初に帯域に入った時刻より後で、もう一度外に出たことがあるかどうかが重要です。最後まで外ならnullです。

周波数と時間の要求を一緒に判定する

assess(cfg,sweep,wanted,nuisance,step)を追加します。すべてのAC点の複素モデル誤差、2つの要求周波数のゲイン、ステップのオーバーシュート・整定の要求を、別々に計算し、最終的なANDを返します。

大きさだけが同じで位相が間違っている応答も、モデルの不一致です。AC2点だけを通過すれば時間を省略する実装は、間違いです。

ファイルから検証レポートを作る

analyze(value,folder)を追加します。設定と、AC3ファイル・ステップ1ファイルを読んで、全体の分析と判定をつなぎます。エラーは、成功のレポートに変えず、そのまま伝えます。

元の波形を保存し、中間の結果もレポートに残して、計算を追跡できるようにします。

2つの計算精度と、実際のCLIをつなぐ

campaign(values,runner)、main(argv)、CLIのエントリーポイントを追加します。すべての設定を検証した後、各回路を5µs・2.5µsで実行し、収束と、両方の設計判定を満たした条件だけを選びます。

実行の失敗と、空の候補を区別します。既存の証拠フォルダーを上書きせず、実際の呼び出しと保存したレポートを、一緒に検査します。