Main Content

移動平均 System object の作成

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

はじめに

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

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

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

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

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

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

System object ファイルの作成

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

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

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

editmovingAverageFilter.m

プロパティの追加

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

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

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) pCoefficientsend

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

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

methodsfunctionobj = movingAverageFilter(varargin)% Support name-value pair arguments when constructing objectsetProperties(obj,nargin,varargin{:})endend

setupImplでの設定と初期化

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

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

functionsetupImpl(obj,x)% Perform one-time calculations, such as computing constantsobj.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を変更します。

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

リセットと解放

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

functionresetImpl(obj)% Initialize / reset discrete-state propertiesobj.State(:) = 0;endfunctionreleaseImpl(obj) obj.pNumChannels = -1;end

入力の検証

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

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

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

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

functions = saveObjectImpl(obj) s = saveObjectImpl@matlab.System(obj);ifisLocked(obj) s.pCoefficients = obj.pCoefficients; s.pNumChannels = obj.pNumChannels;endend

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

functionloadObjectImpl(obj,s,wasLocked)ifwasLocked obj.pCoefficients = s.pCoefficients; obj.pNumChannels = s.pNumChannels;endloadObjectImpl@matlab.System(obj,s,wasLocked);end

MATLAB でのmovingAverageFilterの使用

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

movingAverageFilter = movingAverageFilter('WindowLength',10); t = (1:250)'; signal = randn(250,1); smoothedSignal = movingAverageFilter(signal); plot(t,signal,t,smoothedSignal); legend(["Input","Smoothed input"])

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

Simulink 用への System object の拡張

Simulink で System object を使用するには、System object による移動平均フィルター ブロックの作成(Simulink)を参照してください。