移動平均 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 ファイルを利用できます。完成したクラスを開くには、次のように入力します。
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"])
Simulink 用への System object の拡張
Simulink で System object を使用するには、System object による移動平均フィルター ブロックの作成(Simulink)を参照してください。