FAMOS

シーケンス / 関数に関するFAQ

Q秒としての数値(例100秒)をテキストで分:秒(1:40)の形式で表したい。

A
TimeToText()関数を使用してください。
例)
_sec = 200 ; 時間(秒)
_minsec = TimeToText(_sec, 2) ; 分:秒形式
switch _sec ; テキストの桁合わせ
case 0 to 600-1 ; 10分未満
_minsec = TPart(_minsec, 5, 8)
case 600 to 3600-1 ; 1時間未満
_minsec = TPart(_minsec, 4, 8)
case 3600 to 36000-1 ; 10時間未満
_minsec = TPart(_minsec, 2, 8)
end

製品詳細はこちら

回答を閉じる

Q値が一致するか確認する際、ある程度の範囲をもって一致するか判断したい。

A
if文で範囲内に入っているか判定することもできますが、この用途にはEqual()関数が便利です。
Equal()関数はimc FAMOS Ver 7.2以降のProfessional版が必要です。

例)
A = 2
B = sqrt(2)^2 ; ルート2は無理数。PC上では打ち切り誤差が発生するため2乗しても厳密には2になりません。
Precision15digit = Equal(A, B, 1e-15) ; 一致と判定され、結果は1
Precision16digit = Equal(A, B, 1e-16) ; 不一致と判定され、結果は0

 

製品詳細はこちら

回答を閉じる

Q加速度信号を変位にしたい。

A
Int()関数で積分して下さい。
例)
Velocity = Int(Acceleration) ; 加速度を積分して速度に
Displacement = Int(Velocity) ; 速度を積分して変位に
または
Displacement = Int( Int(Acceleration)) ; 加速度を2回積分して変位に

 

製品詳細はこちら

回答を閉じる

Q位相を0~360度で表示したい。

A
PhaseMod()関数で位相の表示範囲を変換することができます。
PhaseMod()関数はimc FAMOS Ver 7.3以降が必要です。
例)
_fft = FFT(Data)
_fft.P = PhaseMod(_fft.P, "360")
 

 

製品詳細はこちら

回答を閉じる

Q条件に合う名前の変数を抜き出したい。

A
VarGetInit2()関数を使用して下さい。

 

製品詳細はこちら

回答を閉じる

Q複数の条件に合う名前の変数を抜き出したい。

A
VarGetInit2()関数では複数の条件を指定することは出来ないため、複数の条件を1つずつ判定するシーケンスを作成して下さい。
または、この用途にはTxRegexMatch()関数が便利です。TxRegexMatch()関数は、Microsoft .NET Frameworkに実装されている正規表現用パッケージを使用します。正規表現の詳細については、Microsoft .NET Frameworkのドキュメントを参照して下さい。
TxRegexMatch()関数はimc FAMOS Ver 7.2以降が必要です。


例)
; 変数名のサンプル
float_GPS_Latitude = 35.681226
float_GPS_Longitude = 139.766839
Speed = 30
StressTestPoint1 = 10
StressTestPoint2 = 20
StressTestPoint3 = 30
Gear = 3
RPM = 2000

; 変数リストに登録されている変数名をテキスト配列に格納
_nnn = VarGetInit2("Tx*", 1) ; テキスト配列(Tx,Tx1,...)は除外
Tx = TxArrayCreate(0)
for _iii = 1 to _nnn step 1
    Tx = TxArrayInsert(Tx, VarGetName?(_iii), -1)
end

; 変数名に GPS または test を含む変数名
Tx1 = TxRegexMatch(Tx, ".*(GPS|test).*", "", 1)
; 空行を削除
for _iii = TxArrayGetSize(Tx1) to 1 step -1
    if 0 = TLeng(Tx1[_iii])
        Tx1 = TxArrayDelete(Tx1, _iii)
    end
end

; 変数名に GPS または test を含まない変数名
Tx2 = TxRegexMatch(Tx, ".*^(?!.*(GPS|test)).*", "", 1)
; 空行を削除
for _iii = TxArrayGetSize(Tx2) to 1 step -1
    if 0 = TLeng(Tx2[_iii])
        Tx2 = TxArrayDelete(Tx2, _iii)
    end
end

; 変数名に GPS と Latitude を2つとも含む変数名
Tx3 = TxRegexMatch(Tx1, "(?=.*GPS)(?=.*Latitude).*", "", 1)
; 空行を削除
for _iii = TxArrayGetSize(Tx3) to 1 step -1
    if 0 = TLeng(Tx3[_iii])
        Tx3 = TxArrayDelete(Tx3, _iii)
    end
end

; 変数名に GPS と Latitude を2つとも含まない変数名
Tx4 = TxRegexMatch(Tx, "^(?!.*(?=.*GPS)(?=.*Latitude)).*", "", 1)
; 空行を削除
for _iii = TxArrayGetSize(Tx4) to 1 step -1
    if 0 = TLeng(Tx4[_iii])
        Tx4 = TxArrayDelete(Tx4, _iii)
    end
end

; 変数名に GPS を含み Latitude を含まない変数名
Tx5 = TxRegexMatch(Tx, "^(?=.*GPS)(?!.*Latitude).*", "", 1)
; 空行を削除
for _iii = TxArrayGetSize(Tx5) to 1 step -1
    if 0 = TLeng(Tx5[_iii])
        Tx5 = TxArrayDelete(Tx5, _iii)
    end
end

del _*

 

製品詳細はこちら

回答を閉じる

Qテキストボックスやマーカーに複数行のテキストを表示したい。

A
テキスト変数に改行を含むテキストを格納して、テキストボックスやマーカーに適用してください。

例)
Data = Mod(ramp(0, 1, 500), 120) ; サンプルデータ
_x = 200 ; マーカーを表示する位置(時間)
_y = Value(Data, _x)

_CRLF = SvToChar(0x0D) + SvToChar(0x0A) ; 改行 CRLF \r\n
_text = "1行目: " + TForm(_x, "F1.1") + _CRLF + "2行目: " + TForm(_y, "F1.1") ; 複数行のテキスト

; カーブウィンドウで表示
CwNewWindow("Cv1", "show")
CwSelectWindow("Cv1")
CwAction("reset")
CwPosition(0,0,640,480)
CwNewChannel("append last axis", Data)
CwNewElement("marker")
CwSelectByIndex("marker", 1)
CwMarkerSet("x.type", 1)
CwMarkerSet("y.type", 1)
CwMarkerSet("x", _x)
CwMarkerSet("y", _y)
CwMarkerSet("text", _text) ; 複数行のテキストをマーカーに表示

del _*

 

製品詳細はこちら

回答を閉じる

Q変数から[測定]名を削除したい。

A

SetMeasurementName()関数で空文字をセットして下さい。

例)
SetMeasurementName(_data, "")

製品詳細はこちら

回答を閉じる

Q極大値、極小値を絶対値が大きい順にトップ10を求めたい。

A

直接求める関数は用意されてないため、下記の様なシーケンスで求めて下さい。

; 極大値、極小値の絶対値が大きい順にTOP10を求める
_sin = sin(ramp(0,0.01,500)*PI2)*ramp(0,0.01,500) ; サンプルデータ作成用
Data = Join(_sin, -Mirror(_sin)*0.8) ; サンプルデータ

_max = xMax( Data, -1e35) ; 極大値のX座標
_min = xMax(-Data, -1e35) ; 極小値のX座標
_x = Sort(Join(_max, _min), 1) ; 昇順で並べた極大値、極小値のX座標
_y = Value(Abs(Data), _x) ; 極大値、極小値の値の絶対値
_sort = Sort(XYof(_x, _y), 6) ; Y値(絶対値)の降順で並べ替え
_xy = XYof(_sort.x, Value(Data, _sort.x)) ; 元のY値でXY波形を作成
TOP10 = CutIndex(_xy, 1, 10) ; 上位10
TOP10Y = TOP10.Y ; 上位10のY値

; カーブウィンドウで表示
CwNewWindow("Cv1", "show")
CwSelectWindow("Cv1")
CwAction("reset")
CwPosition(0,0,640,480)
CwDisplaySet("title", "")
CwNewChannel("append last axis", Data)
CwNewChannel("append last axis", TOP10)
CwLineSet("type", 0)
CwLineSet("symbol", 8)
; マーカーで順位を表示
_th = Max(Data)-(Max(Data)-Min(Data))*0.1
for _iii = 1to 10 step 1
    CwNewElement("marker")
    CwSelectByIndex("marker", _iii)
    CwMarkerSet("x.type", 1)
    CwMarkerSet("y.type", 1)
    CwMarkerSet("x", TOP10[_iii].X)
    CwMarkerSet("y", TOP10[_iii].Y)
    CwMarkerSet("text", _iii)
    if _th < TOP10[_iii].Y
        CwMarkerSet("angle", -45)
    end
end
del _*

製品詳細はこちら

回答を閉じる

QXY波形の移動平均を求めたい。

A

MvMean()関数はXY波形をサポートしていないため、下記のようなシーケンスで求めて下さい。

例)
LOAD sintest?
Data = XYof(sintest5, sintest2) ; サンプルデータ

; https://www.toyo.co.jp/mecha/faq/detail/id=2885
_Xsort = Sort(Data.X, 1) ;X軸データを単調増加へ
_Ysort = Value(Data.Y, Sort(Data.X, 3)) ;Y軸データを単調増加へ

_dx = 0.5 ; Xの刻み幅
_x0 = Floor(Min(Data.X) / _dx + 1) * _dx ; Xの開始値。最小値をXの刻み幅で丸め
_xend = Floor(Max(Data.X) / _dx) * _dx ; Xの終了値。最大値をXの刻み幅で丸め

_loop = (_xend - _x0) / _dx ; 区間数
Result = ramp(_x0+_dx/2, _dx, _loop) ; 結果を保存する変数(切り出し範囲の中央にプロット)
_index1 = PosiEx2(_Xsort, _x0, 0, 4) ; (最初の)切り出し開始位置
for _iii = 1 to _loop step 1
    _x = _dx*_iii + _x0 ; Yを切り出したい範囲のXの終了値
    _index2 =  PosiEx2(_Xsort, _x, 0, 4) ; 切り出し終了位置
    _Ycut = CutIndex(_Ysort, _index1, _index2) ; 切り出し
    _Ymean = Mean(_Ycut) ; 平均
    Result[_iii] = _Ymean ; 結果を保存
    _index1 = _index2 + 1 ; 切り出し開始位置更新
end
SetUnit(Result, Unit?

製品詳細はこちら

回答を閉じる

Q変数名にアルファベットを連番で追加したい。(例. Data_A, Data_B, Data_C, ...)

A

SvToChar()関数でASCIIコードを文字に変換することによりアルファベットを連番で作成できます。
大文字A~ZはASCIIコードで65~90、小文字a~zは97~122になります。

例)
for _iii = 1 to 5 step 1
    _name = "Data_" + SvToChar(64+_iii) ; アルファベットA,B,...を付加した変数名
    <_name> = ... ; ファイルから読み込んだデータなどを代入
end

アルファベットではなく数値を文字として追加したい場合は
https://www.toyo.co.jp/mecha/faq/detail/id=13204
https://www.toyo.co.jp/mecha/faq/detail/id=14240
を参照して下さい。

製品詳細はこちら

回答を閉じる

Qシーケンスのパスを取得したい。

A

GetOption("Dir.CurrentSequence")関数を使用して下さい。

製品詳細はこちら

回答を閉じる

Q50Hz, 100Vrms(振幅141V)のサイン波をFFT()関数でFFTした結果が50Hzの所で約70.7Vにしかならない。

A

FFT()関数のスペクトルの高さは時系列波形の振幅の1/2になります。振幅値(ピーク値)で見るにはSPEC()関数を使用して下さい。実効値(RMS値)で見る場合はSPEC()関数の結果を√2分の1倍するか、AmpSpectrumRMS()関数を使用して下さい。
AmpSpectrumRMS()関数はProfessional 版以上が必要です。

製品詳細はこちら

回答を閉じる

Q波形の時間差を求めたい。

A

SearchLevel()関数により立ち上がり位置を求めて、その差を取ることで求められます。

例)
下図のような波形の立ち上がり位置(2Vになる点)から波形の時間差を求めるサンプルシーケンスを示します。



_data1 = slope1
_data2 = slope2
_th = 2 ; 立ち上がりのしきい値
_sl1 = SearchLevel(_data1, 2, _th, 0, 2, 0, 0, 1)
_sl2 = SearchLevel(_data2, 2, _th, 0, 2, 0, 0, 1)
dt = _sl2.X - _sl1.X ; 波形の時間差(ピーク毎)
dt_mean = Mean(dt) ; 波形の時間差(平均)

製品詳細はこちら

回答を閉じる

QX軸の値が減少していくXY波形を等間隔波形(標準データ形式)にリサンプリングしたい。

A

Mirror()関数で反転させることによりXYdt()関数で等間隔にリサンプリングできます。

例)
_x = (1 - Ramp(0, 0.1, 11)^2) * 1 'V'
_y = (10 - Ramp(0, 0.1, 11)) * 1 'A'
Data = XYof(_x, _y) ; サンプルデータ

_dt = 0.1 ; リサンプリング時間
Data_ND = XYdt(Mirror(Data.x), Mirror(Data.y), _dt) ; 等間隔にリサンプリングした波形

; カーブウィンドウに表示
CwNewWindow("Cv1", "show")
CwSelectWindow("Cv1")
CwAction("reset")
CwPosition(0,0,640,480)
CwDisplaySet("grid", 1)
CwSelectByIndex("X-axis", 1)
CwAxisSet("ticks.option", 4)
CwAxisSet("ticks.spacing", 0.1)
CwNewChannel("append last axis", Data)
CwLineSet("symbol", 1)
CwNewChannel("append last axis", Data_ND)
CwLineSet("symbol", 8)

製品詳細はこちら

回答を閉じる

Q波形の一部を一定値や別の波形で置換したい

A

標準波形の場合はRepl()関数とReplIndex()関数、XY波形の場合はReplIndex()関数で波形の置換ができます。

例)

; 標準波形の置換
_t = ramp(0, 0.001, 1000) * PI2
data = sin(_t) ; サンプルデータ

_replace = Cut(data, 0.1, 0.3) ; 置換範囲(時間で指定)
_replace = _replace * 0 + 0.2 ; 置換したい波形
new_data = Repl(data, _replace) ; 置換

; カーブウィンドウで表示
CwNewWindow("Cv1", "show")
CwSelectWindow("Cv1")
CwAction("reset")
CwPosition(0,0,480,480)
CwNewChannel("append last axis", data)
CwNewChannel("append last axis", new_data)
CwLineSet("width.screen", 0.5)

; XY波形の置換
_t = ramp(0, 0.001, 500) * PI2
data_xy = XYof(sin(_t), cos(_t)) ; サンプルデータ。半円

_start_index = 50 ; 置換範囲(インデックスで指定)
_end_index = 100
_replace = CutIndex(data_xy, _start_index, _end_index)
_replace.Y = _replace.Y * 0 + 0.2 ; 置換したい波形
new_data_xy = ReplIndex(data_xy, _replace, _start_index) ; 置換

; カーブウィンドウで表示
CwNewWindow("Cv2", "show")
CwSelectWindow("Cv2")
CwAction("reset")
CwPosition(480,0,480,480)
CwNewChannel("append last axis", data_xy)
CwNewChannel("append last axis", new_data_xy)
CwLineSet("width.screen", 0.5)

製品詳細はこちら

回答を閉じる

Q0以外の最小値を求めたい。

A

Sort()関数で並べ替えた後、0以外になる最初の数値を調べることで求めることができます。

例)
Data = (ASin(Sin(ramp(0, 0.1, 50) * PI2 * 1 - PI/2)) / PI + 0.5) * 2 ; サンプルデータ。三角波。
_sort = Sort(Data, 1) ; 昇順にソート
MinExcept0 = 0 ; 0以外の最小値。見つからなかった場合は0。
; foreach VALUE列挙タイプはVer7.3以降が必要。7.2まではSAMPLE列挙タイプ, while文などで。
foreach VALUE _v IN _sort
  if 0 < _v
    MinExcept0 = _v
    break
  end
end

製品詳細はこちら

回答を閉じる

QFFT()関数で計算したFFT結果を複素数計算したい。

A

Rect()関数でMP(Magnitude-Phase)形式からRI(Real-Imaginary)形式に変換した後、実部、虚部に対して計算して下さい。

製品詳細はこちら

回答を閉じる

Qフィルター関数の特性を確認したい。

A

フィルター関数の特性はインパルス波形をフィルターしてFFTすることで確認できます。

例)
サンプルシーケンスをFAMOSで実行して下さい。
FiltLP_特性確認.seq

製品詳細はこちら

回答を閉じる

Q時間軸が不等間隔なXY波形をフィルターやFFT解析したい。

A

XYdt()関数でXY波形を希望のサンプリング時間でリサンプリングをして標準波形に変換してから適用して下さい。

例)
data2 = XYdt(data.X, data.Y, 0.001) ; XY波形dataを0.001s(=1kHz)でリサンプリング
filt = FiltLP(data2, 0, 0, 4, 100) ; 100Hzのローパスを適用

製品詳細はこちら

回答を閉じる