FAMOS
FAMOS全般top
└ OROS24ユーザーのための質問コーナー
QOROSで複数回測定したトラッキングデータの平均を求めたい
FAQ ID:o007
高速で回転数を上昇させた場合など、ハードウェアの制約上の理由により設定した回転数のデータを取りこぼしたり、測定毎に回転数データが異なる場合があります。
このようなデータに対して平均を求めたい場合には少し問題があります。
問題とはサンプルした回転数情報が一致しないからです。
例えば、以下のようにデータが並んだ場合です。
RPM1 | DATA1 | RPM2 | DATA2 | |
1000 | 64 | 1000 | 56 | |
1020 | 50 | 1025 | 60 | |
1050 | 52 | 1055 | 58 |
このような場合、FAMOSでは2つの解決方法があります。
- 回転数の値を補間する方法
- 関数"Add"を利用する方法
以下で各方法の説明を行います。
回転数の値を補間する方法
指定した回転数の値を補間して算出して、同じ回転数情報を持たせます。このように処理すれば単純に足し合わせることができます。
関数”XYdt”を利用します。
回転数やデータとしてサンプルの値を使用します。このとき、補間する回転数間隔を 25[rpm] とします。
以下の式でデータを補間します。
NewDATA1 = XYdt( RPM1, DATA1)
NewDATA2 = XYdt( RPM2, DATA2)
RPM1 | DATA1 | RPM2 | DATA2 | |
1000 | 64 | 1000 | 56 | |
1025 | 50.3333 | 1025 | 60 | |
1050 | 52 | 1055 | 58.3333 |
このようにデータを補間すれば、簡単にデータを演算できます。
例えば。平均を求めるためには以下の式を実行させてください。
MeanData = (NewDATA1 + NewDATA2)/2
関数Addを利用する方法
先程、データを補間して指定した回転数間隔の値を算出しましたが、関数"Add" を利用すると測定したデータポイントを全て利用します。
NewDATA1 = XYof( RPM1, DATA1)
NewDATA2 = XYof( RPM1, DATA2)
MeanData = Add( NewDATA1, NewDATA2, 0) /2
RPM1 | DATA1 | RPM2 | DATA2 | RPM | MeanDATA | ||
1000 | 64 | 1000 | 56 | 1000 | 60 | ||
1020 | 50 | 1020 | 5406 | ||||
1025 | 60 | 1025 | 55.1667 | ||||
1050 | 52 | 1050 | 55.1667 | ||||
1055 | 58 | 1055 |
この方法の実用シーケンスを以下に紹介します。
下図は結果の例です。
オリジナルのデータ(data1 & data2)に対して、結果(ResultAve)は全てのデータポイントが含まれます。
注意:
データを加算する際に、関数"Add"は単調増加関数しか扱いことができません。
単調増加でない場合、並べ替えを行う必要があります。
;_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
;_/ OROSトラッキングデータの平均を求めます。
;_/ -------------------------------------------------------------
;_/ 複数回のトラッキング解析を行い、これらの平均データを算出します。
;_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
;変数リストで選択されているデータを処理します。
_k_Total = VarGetInit(1)
;*********************************************************
;
変数リストでどのチャンネルも選択されていない場合にはシーケンスを終了します
;*********************************************************
if _k_Total<=0
_k_ret = BoxMessage( "エラー", "変数リストで処理したい変数を
選択してください","!1")
Delete _k_*
ExitSequence
End
;*********************************************************
;最初のデータを作成します。
;*********************************************************
_k_VarName = VarGetName?(1)
;OROSデータは回転数とデータが別変数となっています。
;回転数の変数名を取得します。
;---------------------------------------------------------
_k_pos = TxWhere( _k_VarName, ":")
_k_GroupName = TPart( _k_VarName, 1, _k_pos)
_k_RPMName = TAdd( _k_GroupName, "回__数プロファイル_タコ1回__数")
;関数ADDの引数は単調増加である必要があるので
;回転数が減少する場合に備えて、ソートします。
;---------------------------------------------------------
Sequence kim_sort <_k_RPMName>, <_k_VarName>, _k_Res1, _k_Res2
ResultAve = XYof( _k_Res1, _k_Res2)
;*********************************************************
;2つ目以降のデータを作成します。
;*********************************************************
_k_Index = 2
While _k_Index <= _k_Total
_k_VarName = VarGetName?( _k_index)
;OROSデータは回転数とデータが別変数となっています。
;回転数の変数名を取得します。
;-----------------------------------------------------
_k_pos = TxWhere( _k_VarName, ":")
_k_GroupName = TPart( _k_VarName, 1, _k_pos)
_k_RPMName = TAdd( _k_GroupName, "回__数プロファイル_タコ1回__数")
;関数ADDの引数は単調増加である必要があるので
;回転数が減少する場合に備えて、ソートします。
;-----------------------------------------------------
Sequence kim_sort <_k_RPMName>, <_k_VarName>, _k_Res1, _k_Res2
_k_TempRes = XYof( _k_Res1, _k_Res2)
ResultAve = Add( ResultAve, _k_TempRes, 0)
_k_Index=_k_Index+1
End
ResultAve = ResultAve / _k_Total
Show ResultAve
delete _k_*
ExitSequence
シーケンスファイル kim_sort
;=======================================================
;
1つの変数を昇順に並べ替え、それに対応してもう1つの変数を並べ替えます。
;【使用方法】
; Sequence DATA1, DATA2, Result1, Result2
_ksort_RPM = PA1
_ksort_Data = PA2
;-------------------------------------------------------
_ksort_tempRPMX = Sort
( _ksort_RPM, 3)
_ksort_cnt=1
_ksort_Result = Leng(0,Leng?(_ksort_RPM))
While _ksort_cnt<=Leng?(_ksort_RPM)
_ksort_temp = Value
( _ksort_Data, _ksort_tempRPMX[_ksort_cnt])
_ksort_Result[_ksort_cnt] = _ksort_temp[1]
_ksort_cnt = _ksort_cnt+1
End
PA3 = Sort( _ksort_RPM, 1)
PA4 = _ksort_Result
Delete _ksort_*
QOROSのピーク検出方法について
FAQ ID:o008
定義
ピーク検出方法は以下に従います。
(1) 中心のスペクトラムが各方向の2つのスペクトラムより大きいこと
(2) 中心のスペクトラムに対して1つ飛ばした値が予め指定したスレッショルドより小さいこと
これはデータの中心とその隣の2点を以下のように定義した場合、
Data[Z-2]・Data[Z-1]・Data[Z]・Data[Z+2]・Data[Z+2]
以下の条件を満たした場合をピークと判断します。
Data[Z-2] < Data[Z] - スレッショルド
Data[Z-1] < Data[Z]
Data[Z+1] < Data[Z]
Data[Z+2] < Data[Z] - スレッショルド
シーケンス
これらをシーケンスで表現します。
;***********************************************
;OROSピーク検出
;***********************************************
;Parametas -------------------------------------
_k_PeakThresh=5
;-----------------------------------------------
_k_i=1+2
_k_Peak = Leng(0,0)
While _k_i<=Leng?(Data)-2
_k_test=0
;---------------------------------------------------------
;条件1;中心のスペクトラムが各方向の2つのスペクトラムより大きいこと
;条件2;中心のスペクトラムに対して1つ飛ばした値が予め指定したスレッショルドより小さいこと
;---------------------------------------------------------
If Data[_k_i-2]> Data[_k_i]-_k_PeakThresh
_k_test=1
End
If Data[_k_i-1]> Data[_k_i]
_k_test=1
End
If Data[_k_i+1]> Data[_k_i]
_k_test=1
End
If Data[_k_i+2]> Data[_k_i]-_k_PeakThresh
_k_test=1
End
;--------------------
If _k_test=0
_k_Peak = Join(_k_Peak, _k_i)
End
_k_i=_k_i+1
End
_k_UnSortY = ValueIndex(data, _k_Peak) ;Peakはピークを検出したインデックス番号(周波数に相当)
_k_TempX = Sort(_k_UnSortY,4) ;ピークのみのデータを大きい順に並べ、そのときのインデックスを取得
_k_TempX = _k_TempX+1 ;ソートした結果はX単位ですのでインデックスに変換します。
_k_PeakX = ValueIndex(_k_Peak, _k_TempX) ;
;Result --------------------------------------------------------
PeakX = (_k_PeakX-1)*XDel?(Data)
PeakY = Sort(_k_UnSortY, 2)
;sweep variable-----------------------------------------
Delete _k_*
上記シーケンスの場合、WHILE文を使用して全データにアクセスしているため、実行時間がかかります。
そこで、FAMOSシーケンスの特徴を活かして以下のように変更します。
;***********************************************
;OROSピーク検出
;***********************************************
;Parametas -------------------------------------
_k_PeakThresh = 5
;-----------------------------------------------
_k_P2 = CutIndex(data, 1 , Leng?(data)-2-2)
_k_P1 = CutIndex(data, 1+1, Leng?(data)-2-1)
_k_P0 = CutIndex(data, 1+2, Leng?(data)-2-0)
_k_F1 = CutIndex(data, 1+3, Leng?(data)-2+1)
_k_F2 = CutIndex(data, 1+4, Leng?(data)-2+2)
_k_P2 = XOff(_k_P2,0)
_k_P1 = XOff(_k_P1,0)
_k_P0 = XOff(_k_P0,0)
_k_F1 = XOff(_k_F1,0)
_k_F2 = XOff(_k_F2,0)
_k_ResP2 = (STri(_k_P0-_k_P2-_k_PeakThresh, 0, 0)+1/2
_k_ResP1 = (STri(_k_P0-_k_P1, 0,0)+1)/2
_k_ResF1 = (STri(_k_P0-_k_F1, 0,0)+1)/2
_k_ResF2 = (STri(_k_P0-_k_F2-_k_PeakThresh, 0, 0)+1)/2
_k_Res = _k_ResP2*_k_ResP1*_k_ResF1*_k_ResF2
_k_Res = Join( Leng(0,2), _k_Res)
_k_Res = Join( _k_Res, Leng(0,2))
_k_Res = XDel( _k_Res, XDel?(Data))
_k_Res2 = SearchLevel(_k_Res, 2, 1, 0, 2, 0, 0, 1)
_k_PeakX = _k_Res2.X ;ピークを検出した周波数
;--------------------------------------
_k_UnSortY = Value(data, _k_PeakX) ;検出したY値
_k_TempX = Sort(_k_UnSortY, 4) ;ピークのみのデータを大きい順に並べ、そのときのインデックスを取得
_k_TempX = _k_TempX+1 ;ソートした結果はX単位ですのでインデックスに変換します。
;Result --------------------------------------------------------
PeakX = ValueIndex(_k_PeakX, _k_TempX) ;
PeakY = Sort(_k_UnSortY, 2)
;sweep variable-----------------------------------------
Delete _k_*
QOROSの最大値検出方法について
FAQ ID:o009
定義
最大値の検出については以下のように定義されています。
最大値とは予め設定したスレッショルドを超えた極大値のことを意味します。
シーケンス
;***********************************************
;OROS最大値検出
;***********************************************
;Parametas -------------------------------------
_k_MaxThresh = 20
;初期値の設定-----------------------------------------------
_k_tempMax = -1E20
_k_tempMin = -1E20
_k_Prev = 0
_k_SampTime = XDel?(Data)
If Data[2]>Data[1]
_k_Prev = 1
End
_k_i=3
MaxiX = Leng(0,0)
MaxiY = Leng(0,0)
While _k_i<=Leng?(Data)
If Data[_k_i]>Data[_k_i-1]
If _k_Prev<>1 _k_Prev=1 ;パターンDU
If Data[_k_i-1]<_k_TempMin
_k_TempMin = Data[_k_i-1]
End
End
Else
If _k_Prev=1
_k_Prev=0 ;パターンUD
If Data[_k_i-1]>_k_TempMax
_k_TempMax = Data[_k_i-1] ;一時的な極大値の更新
_k_TempX = (_k_i-2)*_k_SampTime
End
End
If _k_TempMax-_k_MaxThresh>Data[_k_i]
If _k_TempMax-_k_MaxThresh>_k_TempMin
MaxiX = Join(MaxiX, _k_TempX)
MaxiY = Join(MaxiY, _k_TempMax)
_k_TempMax = -1E20
_k_TempMin = 1E20
End
End
End
_k_i=_k_i+1
End
;------------------------------
;データ処理部
;------------------------------
_k_TempX = Sort( MaxiY, 4) ;データを大きい順に並べ、そのときのインデックスを取得
_k_TempX = _k_TempX+1 ;ソートした結果はX単位ですのでインデックスに変換します。
MaxiX = ValueIndex(MaxiX, _k_TempX) ;Xデータを並べ替えます
MaxiY = Sort( MaxiY, 2) ;Yデータを昇順に並べ替えます
;sweap variable-----------------------------------------
Delete _k_*
Q最大値とピーク値の意味
FAQ ID:o010
OROSにはピーク検出機能と最大値検出機能があります。しかし、これらがどのように違うのか少しわかりにくくなっています。
これらの違いについて実際のデータを処理しながら解説します。
対象データを以下とします。
最大値とピーク値を算出した結果を示します。(スレッショルド=20)
No | 最大値 | ピーク | ||
---|---|---|---|---|
周波数 | 値 | 周波数 | 値 | |
1 | 97.5 | 75.22 | 1900 | 66.22 |
2 | 297.5 | 67.1 | 1300 | 62.95 |
3 | 1900 | 66.22 | 900 | 58.56 |
4 | 502.5 | 65.21 | 1500 | 55.32 |
5 | 1102.5 | 65.13 | 1700 | 49.04 |
6 | 1300 | 62.95 | 415 | 35.33 |
7 | 702.5 | 61.73 | 200 | 33.66 |
8 | 900 | 58.56 | 1727.5 | 29.69 |
9 | 1500 | 55.32 | 780 | 27.5 |
10 | 1700 | 49.04 | - | - |
11 | 415 | 35.33 | - | - |
12 | 200 | 33.66 | - | - |
13 | 1727.5 | 29.69 | - | - |
14 | 780 | 27.5 | - | - |
15 | 1907.5 | 26.25 | - | - |
: | : | : | - | - |
: | : | : | - | - |
51 | 625 | 9.98 | - | - |
52 | 1987.5 | 7.31 | - | - |
結果は周波数が異なっているので、周波数軸をそろえて表示してみます。
No | 最大値 | ピーク | ||
---|---|---|---|---|
周波数 | 値 | 周波数 | 値 | |
1 | 97.5 | 75.22 | - | - |
2 | 297.5 | 67.1 | - | - |
3 | 1900 | 66.22 | 1900 | 66.22 |
4 | 502.5 | 65.21 | - | - |
5 | 1102.5 | 65.13 | - | - |
6 | 1300 | 62.95 | 1300 | 62.95 |
7 | 702.5 | 61.73 | - | - |
8 | 900 | 58.56 | 900 | 58.56 |
9 | 1500 | 55.32 | 1500 | 55.32 |
10 | 1700 | 49.04 | 1700 | 49.04 |
11 | 415 | 35.33 | 415 | 35.33 |
12 | 200 | 33.66 | 200 | 33.66 |
13 | 1727.5 | 29.69 | 1727.5 | 29.69 |
14 | 780 | 27.5 | 780 | 27.5 |
15 | 1907.5 | 26.25 | - | - |
: | : | : | - | - |
: | : | : | - | - |
51 | 625 | 9.98 | - | - |
52 | 1987.5 | 7.31 | - | - |
このように並べるとわかりますが、例えばNo.1、2はピーク検出条件を満たすことができないので検出されません。
97.5Hzが最も大きい値ですが、102.5Hzがスレッショルドより大きいのでピークとしてカウントされません。
従って、一般的なピークという解釈の場合、最大値検出機能を使うほうが理解しやすいと思います。
また、OROSで最大値検出コマンドを実行すると最大値とピークという表示がされます。この表現も少しわかりにくくしている原因の一つで、この場合基本的には最大値を検出し、 ピークと解釈できるデータにはピークと表現しています。
Q縦軸の値をdBからLogに変更したい
FAQ ID:o006
OROSファイル(AE2)に記述されている値がdBとなっています。
従ってLogで表示するためには以下の手順に従ってください。
(1)リニアスケールに変更します。
result = idB( DATA)
ここで、デシベルに変換する際に参照値が設定されている場合があります。
【OROSでの確認】
参照値はOROSの画面に以下のように表示されています。
【FAMOSでの確認】
参照値は変数のプロパティ内のコメント欄に以下のように記述されます。
参照値を考慮して変換する場合には以下の式に従って下さい。
result = idB( DATA) * Yref0dB
(2)軸の表示方法をLogに変更します。
- カーブウィンドウのY軸をダブルクリック。以下のダイアログが表示されます。
- "リニア/ログ"メニューのログを選択します。
注意:
リニアスケールに一度変換すると、(2)のスケールを変更することにより、リニア・dB・ログスケールを自由に切り替えることができます。
Q目盛の表示エリアが大きすぎるので小さくしたい
QOROSのデータを読み込むためにはどうすればよいですか?
Qトラッキングデータを読み込みましたが、X軸が回転数表示されません
FAQ ID:o002
FAMOSにデータを読み込んだだけではX軸は回転数として表示されません。
データを読み込むと以下のように変数がFAMOSに読み込まれます。
この中に”RPM_Profile_Tach_1_RPM”があります。これが回転数データです。
この回転数データとレベルをXY波形として生成してください。
XY波形にするためには2つの方法があります。
1つは以下のように関数を使ってXY波形を新しく生成する方法です。
Gain = XYof( order_teset2:RPM_Profile_Tach_1_RPM, order_test2:Order_Ch__1_Order10)
もう1つの方法はカーブウィンドウの”ウィンドウ設定”を利用する方法です。
こちらの具体的な手順はこちらを参照してください。
何故、回転数データを別にしているのですか?
回転数データ以外に時間データも存在します。ユーザーのニーズに幅広く応えるためにX軸データとY軸データを分離しています。
これらの処理データを重ねて描くことができますか?
処理したデータはXY形式になりますが、通常の変数と同様に扱うことができます。
Qオフライン解析したとき、オンラインの結果と一致しません。
FAQ ID:o003
OROSで測定した時系列波形をFAMOSでオフライン解析しました。この結果はオンラインで計算した結果と異なります。
OROSはオンライン解析時に時系列波形にデジタルフィルターをかけ、これを解析しています。このとき、デジタルフィルターの適用によりデータの最初の部分が安定しない場合があります。そこで、256点分後からデータ解析を開始します。
時系列データをオフラインで解析する場合、この256点分を取り除いてから計算してください。
Example
時系列データから計算した結果とOROSでオンライン解析した結果を比較します。
時系列データは結果がよくわかるようにチャープ信号を入力します。
このデータをFFTした場合、以下のようにピーク周波数が時間とともに移動します。
1ブロック分だけのデータを切り出し、オンライン解析結果と比較します。
res = CutIndex( Data, 256+1, 256+1024)
OFFLine = dB( AmpSpectrumRMS_1( res, 1024, 2, 0, 1))
QウォーターフォールのZ方向を正しく表示させたい
FAQ ID:o004
OROSで解析したウォーターフォールデータのZ方向がセグメント番号で表示されています。正しく表示することはできますか?
OROSデータを読み込んだ場合、ウォーターフォールデータはZ方向のデータを持ちません。セグメント番号で管理しています。
従って、ご指摘のようにそのまま表示すると奥行き方向はセグメント番号で表示されます。
この奥行き方向には回転数や時間などが対応します。これらのデータはX軸がセグメント番号になっています。
ここで、回転数が等間隔になっている場合、Z方向のオフセットとサンプリング間隔を設定すれば正しく表示されます。
通常、緩加速データではこの方法で問題ありません。
OROSは測定時の回転数を記録するため、データ不等間隔になっていますが、データ測定時にユーザーは開始回転数やデルタ回転数を設定しているはずです。従って、回転数に多少の誤差があったとしても仕方がないと考え、これらの値を設定します。
FFTメーカーの製品には自動的にこの補正を行い、設定どおりの回転数を出力しているものもあります。
しかし、実際には上と同じ補正を行っています。
ここで、下図のように回転数の変動が激しい、急加速の場合が問題となります。
この場合、回転数データに対応させたラベリングを行わないといけません。
これを実現するためには、セグメントデータをそれぞれ標準波形に変換して、Z方向のオフセットを指定します。
以下にサンプルシーケンスを示します。
;-----------------------------------------
;データの置き換え
DATA = const_b_wf:Wtf_Spectrum_updown
RPM = const_b_wf:RPM_Profile_Tach_1_RPM
;-----------------------------------------
i=1
;結果を格納する変数
NewData = GrNew()
;---------------------------
;全てのセグメントに対して処理
;---------------------------
While i<=Leng?(Data)/SegLen?(Data)
;セグメントを分解するので名前をつける
Name = TAdd( "segment", Tform(i,"F00"))
<Name> = DATA[i]
;プロパティを設定
SetZOff( <Name>, RPM[i])
SetColor(<Name>, RGB(0,0,0))
SetUnit(<Name>, "RPM", 2)
;グループ変数に追加
GrChanAppend( NewData, <Name>)
Delete <Name>
i=i+1
End
Delete Name
Delete i
注意
Z方向の表示が上図のように表示されない場合、カーブウィンドウメニュー”オプション/3D”を選択して、
データのZ方向を”データのZ座標を加える”を選択してください。