Main Content

移動平均 System object の作成

この例では、移動平均フィルターを実装する System object™ の作成方法を説明します。

はじめに

System object は、matlab.System から派生する MATLAB® クラスです。その結果、System object はすべて、以下の標準メソッドを含む共通のパブリック インターフェイスを継承します。

  • setup — オブジェクトを初期化 (通常はシミュレーション開始時)

  • reset — オブジェクトの内部状態をクリアし、既定の初期化後の状態に戻す

  • release — オブジェクト内部で使用されるリソース (メモリ、ハードウェア、OS 固有のリソース) を解放

新しい種類の System object を作成するときは、上記のすべてのメソッドに対して特定の実装を提供し、動作を決定します。

この例では、movingAverageFilter System object を作成して使用します。movingAverageFilter は、過去の WindowLength にある入力サンプルの重みなし平均値を計算する System object です。WindowLength は移動平均ウィンドウの長さです。movingAverageFilter は、単精度および倍精度の 2 次元入力行列を受け入れます。入力行列の各列は、独立した (1 次元) チャネルとして処理されます。入力の最初の次元はチャネルの長さ (または入力フレーム サイズ) を定義します。movingAverageFilter は、時間の経過に伴って各入力チャネルの移動平均を個別に計算します。

System object ファイルの作成

MATLAB の [ホーム] タブで、[新規]、[System object]、[標準] を選択して新しい System object クラスを作成します。System object の基本テンプレートが MATLAB エディターで開き、movingAverageFilter System object の作成手順を示します。

クラス movingAverageFilter の名前を変更し、ファイルを movingAverageFilter.m として保存します。System object を使用可能にするには、MATLAB パス上にあるフォルダーに System object を保存する必要があります。

便宜上、この例では完成した movingAverageFilter System object ファイルを利用できます。完成したクラスを開くには、次のように入力します。

edit movingAverageFilter.m

プロパティの追加

この System object には 4 つのプロパティが必要です。まず、移動平均ウィンドウの長さを制御するパブリック プロパティ WindowLength を追加します。データ処理が開始されると、アルゴリズムはこの値が一定であることに依存するため、このプロパティは調整不可として定義されます。さらに、このプロパティは実数の正の整数のみを受け入れます。入力がこれらの条件を満たすことを確認するには、プロパティ検証を追加します (プロパティ値の検証を参照)。このプロパティの既定値を 5 に設定します。

properties(Nontunable)
    WindowLength (1,1){mustBeInteger,mustBePositive} = 5
end

2 番目に、State および pNumChannels という名前の 2 つのプロパティを追加します。ユーザーはどちらのプロパティにもアクセスしてはならないので、Access = private 属性を使用します。State は移動平均フィルターの状態を保存します。pNumChannels は入力に含まれるチャネル数を保存します。このプロパティの値は、入力に含まれる列数から決定されます。

properties(Access = private)
    State;
    pNumChannels = -1;
end

最後に、FIR 分子係数を保存するプロパティが必要です。pCoefficients という名前のプロパティを追加します。データ処理中に係数が変化することはなく、System object のユーザーが係数にアクセスできないようにする必要があるため、プロパティの属性を Nontunable, Access = private として設定します。

properties(Access = private, Nontunable)
    pCoefficients
end

作成を簡略化するためのコンストラクターの追加

System object コンストラクターは、クラスと同じ名前 (この例では movingAverageFilter) のメソッドです。System object コンストラクターを実装すると、setProperties メソッドを使用して、名前と値のペアを System object に入力することができます。たとえば、コンストラクターを使用すると、ユーザーは次の構文を使用して System object のインスタンスを作成できます。filter = movingAverageFilter('WindowLength',10)。コンストラクターは、その他の目的では使用しないでください。その他のセットアップ タスクはすべて setupImpl メソッドで記述する必要があります。

methods
    function obj = movingAverageFilter(varargin)
        % Support name-value pair arguments when constructing object
        setProperties(obj,nargin,varargin{:})
    end
end

setupImpl での設定と初期化

setupImpl メソッドはオブジェクトを設定し、1 回限りの初期化タスクを実装します。この System object では、フィルター係数、状態、チャネル数を計算するように既定の setupImpl メソッドを変更します。フィルター係数は、指定された WindowLength に基づいて計算されます。フィルターの状態はゼロに初期化されます (入力チャネルごとに WindowLength-1 個の状態があります)。最後に、入力に含まれる列数からチャネル数が特定されます。

setupImpl メソッドおよびすべての Impl メソッドでは、メソッド属性 Access = protected を設定しなければなりません。System object のユーザーがこれらのメソッドを直接呼び出すことはないためです。代わりに、System object のバックエンドが、他のユーザー向け関数を使用してこれらのメソッドを呼び出します。

function setupImpl(obj,x)
    % Perform one-time calculations, such as computing constants
    obj.pNumChannels = size(x,2);
    obj.pCoefficients = ones(1,obj.WindowLength)/obj.WindowLength;
    obj.State = zeros(obj.WindowLength-1,obj.pNumChannels,'like',x);
end

stepImpl でのアルゴリズムの定義

オブジェクトのアルゴリズムは stepImpl メソッドで定義されます。stepImpl 内のアルゴリズムは、System object のユーザーがコマンド ラインでオブジェクトを呼び出したときに実行されます。この例では、関数 filterを使用して、出力を計算し、オブジェクトの状態値を更新するように stepImpl を変更します。

function y = stepImpl(obj,u)
    [y,obj.State] = filter(obj.pCoefficients,1,u,obj.State);
end

リセットと解放

状態リセット方程式は resetImpl メソッドで定義されます。この例では、状態をゼロにリセットします。さらに、releaseImpl メソッドを追加する必要があります。[エディター] ツールストリップから、[メソッドの挿入]、[リソースの解放] を選択します。releaseImpl メソッドが System object に追加されます。releaseImpl を変更してチャネル数を -1 に設定します。これにより、新しい入力をフィルターで使用できます。

function resetImpl(obj)
    % Initialize / reset discrete-state properties
    obj.State(:) = 0;
end
function releaseImpl(obj)
    obj.pNumChannels = -1;
end

入力の検証

System object への入力を検証するには、validateInputsImpl メソッドを実装しなければなりません。このメソッドは、初期化時およびその後の呼び出しで入力属性 (次元、データ型、実数/複素数など) が変化するたびに入力を検証します。ツールストリップから、[メソッドの挿入]、[入力の検証] を選択します。新しく挿入された validateInputsImpl メソッドで、validateattributes を呼び出して、入力が浮動小数点データを含む 2 次元行列であることを確認します。

function validateInputsImpl(~, u)
    validateattributes(u,{'double','single'}, {'2d',...
        'nonsparse'},'','input');
end

オブジェクトの保存と読み込み

saveObjectImpl は、System object のインスタンスを保存するときに MAT ファイルに保存されるプロパティ値と状態値を定義します。System object クラスに saveObjectImpl メソッドを定義しない場合、パブリック プロパティと DiscreteState 属性をもつプロパティのみが保存されます。[メソッドの挿入]、[MAT ファイルに保存] を選択します。オブジェクトがロックされた場合に係数とチャネル数が保存されるように saveObjectImpl を変更します。

function s = saveObjectImpl(obj)
    s = saveObjectImpl@matlab.System(obj);
    if isLocked(obj)
        s.pCoefficients = obj.pCoefficients;
        s.pNumChannels = obj.pNumChannels;
    end
end

loadObjectImpl は、保存されたオブジェクトの読み込み方法を定義するため、saveObjectImpl のコンパニオンです。保存されたオブジェクトを読み込むと、オブジェクトは同じロック状態で読み込まれます。[メソッドの挿入]、[MAT ファイルからの読み込み] を選択します。オブジェクトがロックされた場合に係数とチャネル数が読み込まれるように、loadObjectImpl を変更します。

function loadObjectImpl(obj,s,wasLocked)
    if wasLocked
        obj.pCoefficients = s.pCoefficients;
        obj.pNumChannels = s.pNumChannels;
    end
    loadObjectImpl@matlab.System(obj,s,wasLocked);
end

MATLAB での movingAverageFilter の使用

System object の定義が完了したので、MATLAB でオブジェクトを使用できます。たとえば、movingAverageFilter を使用して、ノイズを含むパルス シーケンスからノイズを除去します。

movingAverageFilter = movingAverageFilter('WindowLength',10);

t = (1:250)';
signal = randn(250,1);
smoothedSignal = movingAverageFilter(signal);

plot(t,signal,t,smoothedSignal);
legend(["Input","Smoothed Signal"])

Figure contains an axes object. The axes object contains 2 objects of type line. These objects represent Input, Smoothed Signal.

Simulink 用への System object の拡張

Simulink® で System object を使用するには、を参照してください。