メインコンテンツ

Python Code ブロックを使用してローパス フィルターの Python コードを Simulink に統合

この例では、Python Code ブロックを使用してネイティブ Python コードを Simulink に統合する方法を示します。Python Code ブロックは、Python コードをブロック ダイアログに直接インポートするか書き込むために使用します。

この例では、Python Code ブロックを使用して、1 次ローパス フィルターの実装を定義するネイティブ Python コードを Simulink に統合します。フィルターはラプラス領域において次の方程式で定義されています。

H(s)=(ωcutofffs+ωcutoff)

ここで、ωcutoff はカットオフ周波数です。

このフィルターは、時間領域においては双一次 (Tustin) 変換を使用して次のように表現できます。

yk=(1-α1+α)yk-1+(α1+α)[uk+uk-1],

α=(ωcutoffTs2),

ここで、

ykyk-1 は現在とその前のタイム ステップのフィルター出力です。

ukuk-1 は現在とその前のタイム ステップのフィルター入力です。

Ts はサンプル時間です。

ネイティブ Python コードを使用したフィルターの定義

Python クラス FirstOrderLowPassFilter を使用してローパス フィルターの実装を定義する次の Python コード ファイル firstOrderLowPassFilter.py について考えます。クラスには、cutoff_frequencysample_timeprevious_inputprevious_output の 4 つのプロパティがあります。クラス コンストラクターは、cutoff_frequencysample_time を入力として受け取り、previous_inputprevious_output0 として初期化します。computeFilterOutput メソッドは、input_value から信号値を受け取り、指定されたカットオフ周波数とサンプル時間に基づいて信号をフィルター処理するための計算を実行します。

class FirstOrderLowPassFilter:
    def __init__(self, cutoff_frequency, sample_time):
        self.cutoff_frequency = cutoff_frequency
        self.sample_time = sample_time
        self.previous_input = 0.0
        self.previous_output = 0.0

    def computeFilterOutput(self, input_value):
        alpha = (3.14 * self.cutoff_frequency * self.sample_time)
        
        output = ((1 - alpha) / (1 + alpha)) * self.previous_output + ((alpha) / (1 + alpha)) * (input_value + self.previous_input)
        
        self.previous_output = output
        self.previous_input = input_value
        
        return output

Python Code ブロックを使用した Simulink へのフィルターの統合

Python コード ブロックを含む Simulink モデル simulationFilterModel.slx を開きます。このブロックは、ローパス フィルターの Python 実装を Simulink に統合し、フィルター処理された信号をタイム ステップごとに出力します。ブロックはスカラー入力を受け入れ、フィルター処理された信号とノイズを含む信号の 2 つの要素を含むバス信号を出力します。ブロック ダイアログでフィルターのカットオフ周波数とサンプル時間を指定できます。

open_system("simulationFilterModel");

ブロック ダイアログを開くには、Python Code ブロックをダブルクリックするか、ブロックを選択して "Ctrl + U" を押します。ブロック ダイアログには、[初期化][出力][終了] の 3 つのコード ペインがあります。これらのペインで、シミュレーションのそれぞれの段階の Python コードを指定できます。[端子とパラメーター] テーブルで、状態を格納するためのブロック インターフェイス、パラメーター、Python の永続オブジェクトを指定できます。

createBus.m スクリプトを実行して、ブロック出力のバス オブジェクトを初期化します。

createBus;

[端子とパラメーター] テーブルの [追加] ボタンを使用して、この Python Code ブロックのインターフェイスを指定します。double 型のスカラー入力を受け取り、スクリプトで filterOutput として定義されているバス型を出力するようにブロックを構成します。cutoffFrequencyfilterSampleTime をブロックのパラメーターとして指定します。フィルター オブジェクトを格納してシミュレーション タイム ステップ間で状態を保持するために、PythonObject 型を使用して Persistent 変数を指定します。

ports_and_parameters.png

[初期化] ペインを使用して、firstOrderLowPassFilter.py ファイルから Python コードをインポートし、カットオフ周波数とサンプル時間のパラメーターをもつフィルター オブジェクトを作成します。

from firstOrderLowPassFiler import FirstOrderLowPassFilter
filterObject = FirstOrderLowPassFilter(cutoff_frequency=cutoffFrequency, sample_time=filterSampleTime) 

[出力] ペインを使用して、各タイム ステップのアクションを指定します。フィルター処理された信号を現在の入力に基づいて計算する filterObject を指定します。バス要素の名前に一致するキーをもつ Python ディクショナリを定義して、ブロックのバス出力を定義します。

filteredSignal = filterObject.computeFilterOutput(noisySignal)

filterOutput = {
    'FilteredSignal': filteredSignal,
    'NoisySignal': noisySignal
}

ブロック ダイアログで [適用] ボタンと [OK] ボタンをクリックします。これにより、ブロック ダイアログが閉じます。

Python Code ブロックをダブルクリックして、パラメーター フィールドを含むブロック マスクを開きます。フィルターに対して、目的のサンプル時間とカットオフ周波数を指定します。

block_mask.png

Simulink モデルをコンパイルします。

simulation_model.png

モデルのシミュレーション

これで、Python Code ブロックをもつモデルをシミュレートできます。ノイズのある信号を入力し、ブロックに指定されたサンプル時間とカットオフ周波数に基づいて、フィルター ブロックから出力されるフィルター処理された信号を観察します。

model = 'simulationFilterModel';
simData = sim(model);

figure(1);
plot(simData.yout{2}.Values,'--r','LineWidth',1)
hold on 
plot(simData.yout{1}.Values,'g','LineWidth',2)
grid minor 
xlabel('Time')
ylabel('Signal Value')
title('Filter Simulation')
legend('Noisy Signal', 'Filtered Signal')

Figure contains an axes object. The axes object with title Filter Simulation, xlabel Time, ylabel Signal Value contains 2 objects of type stair. These objects represent Noisy Signal, Filtered Signal.

参考