PyLTSpiceを使用した自動シミュレーション

PyLTspiceについて

nunobrum氏が開発されているLTspiceが出力するファイルを解釈しPython上で扱えるようにするライブラリです。
ネットリスト(.net)の編集、結果ファイル(.raw)の取得、シミュレーションの自動実行などを行うことができます。

内包されているモジュールを以下に示します。

使用準備

PyLTspiceを使用するにあたってシミュレーションする回路が必要になります。
簡単なオペアンプの回路を用意して実行できることを確認しておきます。

Python環境に関しては以下の通りです。

  • python3.8.10
    • matplotlib
    • numpy
    • PyLTspicev 1.6(頻繁にアップデートが入るのでVer間の互換性に注意)

PyLTspiceはpip install PyLTSpiceで導入可能です。

RawRead

まずはLTSpiceが出力する.rawファイルを読み込むのをやってみようと思います。
先ほど用意したオペアンプ回路のin,outを拾ってきてmatplotlibで出力するというものです。

import matplotlib.pyplot as plt
from PyLTSpice.LTSpice_RawRead import LTSpiceRawRead

#.rawファイルを読み込む。
LTR = LTSpiceRawRead(r'D:\LTspice\opamp\opamp.raw')

#LTspiceで使っているラベル類を抜きだす。
print(LTR.get_trace_names())

#.rawファイルの上のほうの情報を抜き出す。
print(LTR.get_raw_property())

#ラベル値を指定してrawファイルからデータを抜き出す。
V001    = LTR.get_trace("V(n001)")
V002    = LTR.get_trace("V(n002)")
x       = LTR.get_trace('time')

#step実行命令がある場合step番号を取得する。
steps   = LTR.get_steps()

fig = plt.figure()

#グラフのプロット
for step in range(len(steps)):
    plt.plot(x.get_time_axis(step), V001.get_wave(step), label="Vin",color="blue")
    plt.plot(x.get_time_axis(step), V002.get_wave(step), label="Vout",color="red")

plt.legend(fontsize=9)
plt.xlabel("time[s]")
plt.ylabel("voltage[V]")
plt.show()

コードを実行すると以下のような波形がプロットされると思います。

LTSpiceBatch使用例

先ほどのシミュレーションでは.rawファイルを読みだすことができたので少し応用的なことをやってみます。
LTSpiceBatchというモジュールを使用してnetlistファイルを編集しバッチコマンドを実行します。

具体的には、R1を10k,20k,30kと変えたときのVoutの値をプロットするというものです。
LTspiceの.stepコマンドで実行できますが、PyLTspiceの使い方を学ぶ例題としてはとらえてもらえたらと思います。

import matplotlib.pyplot as plt
from PyLTSpice.LTSpiceBatch import SimCommander
from PyLTSpice.LTSpice_RawRead import LTSpiceRawRead

# LTspiceの回路ファイルを読み込む
LTC = SimCommander(r'D:\LTspice\opamp\opamp.asc')
fig = plt.figure()
R1list = ['10k','20k','35k','45k','55k']

for i in R1list:
    #netlistの中身を編集する
    LTC.set_component_value('R1', i) 
    LTC.set_component_value('V1','SINE(0 0.1 1000 0)')
    
    #現在のnetlistの情報でバッチ処理を実行する
    a = LTC.circuit_radic
    run_netlist_file = "{}_{}.net".format(LTC.circuit_radic,i)
    LTC.run(run_filename=run_netlist_file)
    LTC.wait_completion()
    LTR = LTSpiceRawRead(LTC.circuit_radic + '_' +str(i) + '.raw')

    #rawファイルよりプロットに必要な情報を取得する
    V001    = LTR.get_trace("V(n001)")
    V002    = LTR.get_trace("V(n002)")
    x       = LTR.get_trace('time')

    #step実行がある場合回数を取得する
    steps   = LTR.get_steps()
    plt.plot(x.get_time_axis(0), V002.get_wave(0), label="Vout , R2 = "+i,color="red")

#netlistを元に戻す
LTC.reset_netlist() 
plt.plot(x.get_time_axis(0), V001.get_wave(0), label="Vin",color="blue")   
plt.legend(fontsize=9)
plt.xlabel("time[s]")
plt.ylabel("voltage[V]")
plt.show()    


このコードではV(n001)のようにデフォルトネットを参照していますが
ltspice上でネットにラベルを付けておくとプログラム上で参照する際にわかりやすいです。

まとめ

PyLTspiceを触ってみましたが、比較的短いコードで設計の効率化ができると感じました。今回の例では込み入ったことをしていませんが、モデルの切り替えなんかもできます。自分の思いつく限りですが実務だと以下の作業でしょうか?

  • 時間のかかるシミュレーションをレシピ化して自動実行させる
  • 回路のオープンショート解析
  • モデルを切り替えてそれぞれのふるまいを確認する

PyLTspice自体は製作者の方が尽力的にコミットメントされ、機能拡充が進んでいくと思われますので今後とも注目してみていきたいと思います。