リアルタイムでの外れ値の除外

C/C++

[mathjax]
ロボットでデータを計測していると,外れ値と呼ばれる大きなノイズの影響を受けた値が出てきます.
外れ値の影響はデジタルローパスフィルタで除外しきれない場合が多いです. フィルタの次数を大きくすることで,外れ値の影響は小さくすることはできますが,フィルタによる遅延も大きくなるためお勧めできる方法ではありません.

一般的にはこうした外れ値は閾値を超えた値として検出し,除外します.
閾値 (A) とし,時刻 (t_i) における計測値を (x_i) とすれば, (t_{i+1}) における予測値の許容範囲(\hat{x}{i})は次のように書けます.
$$ \hat{x}
{i+1} = x_{i} \pm A $$

ここで, (x_i) がほぼ一定であればいいのですが, 外れ値が出た後に値が大きく変化した場合, 値が更新されなくなってしまいます.
そのため, 外れ値が連続で出た回数を (k) として (\hat{x}{i}) を次のように設定します.
$$ \hat{x}
{i+1} = x_{i} \pm (k+1)*A $$
こうすれば, 外れ値の後に変化した値を検出することができます. ただし, 連続で外れ値が出た場合には, 外れ値であっても, 許容範囲内に入ってしまう恐れがあるので注意する必要があります.

これをCで実装すると次のようになります.
[cpp]
// data array, data[0] is a current value and data[1] is a previous value
int data[2];
int A = 100; // threshold
int k = 0; // count of outliers
for(;;){
data[0] = analogRead(A0); // get a sensor value

if(abs(data[0] – data[1]) > (k+1)*100){
// reject an outlier
data[0] = data[1];
k++;
}else{

/** filter processing **/

data[1] = data[0];
k = 0; // reset the count
}
}
[/cpp]

実際にはフィルタ処理を並行してかけることになると思います.

コメント

タイトルとURLをコピーしました