2016-03-20 19 views
3

私はコンパス方位入力するローパスフィルタを実装しようとしている、と私は一緒にこのようになります基本的な機能入れている:ローパスコンパス平滑おかしな

var smoothing = 0.15; 

function lowPass(degree) { 
    var oldVal = $scope.compassBearing || 0; 
    var smoothedValue = oldVal + smoothing * (degree - oldVal); 
    return smoothedValue; 
} 

を除いて、素晴らしい作品をコンパス方位は北を通過するときのために(すなわち。急に0から359またはその逆に変更されます。

持つようならば誰でも、同様の問題に遭遇して、それが解決されたか?

+0

問題は何ですか? 'smoothValue'は例えば361、-2など? – dannyjolie

+0

スムージングは​​反対側に向かって読みをスムーズにしようとしているので、例えば356→358→0→2にスムージングするのではなく、2つの値を平均してコンパスを速くしようとします反対の方向に回り、新しい価値を満たす。 – opticon

+0

ええ、私はそれを考え出した。ちょうどあなた自身のスクリプトを試して、本当の問題を見ました。例えばからの移行。 359から10までは0を経由するのではなく、「後方に」行く。それは疑問からは分かりませんでした。 – dannyjolie

答えて

4

さんはいつもあなたを言ってみましょう最短経路で滑らかにしたいので、変更が270度から5度の場合北に行くと、値をチェックし、その差が180以上であるかどうかを調べる必要があります。もしそうなら、関数を少し変更してください。

差が-180より小さい場合は、少数の演算子を反転して360を加算します。差が180以上の場合も同様です。最後に結果が360以上か0未満かを確認して修正してください。

function lowPass(degree) { 
    var oldVal = $scope.compassBearing || 0; 
    var smoothedValue; 

    if(oldVal - degree < -180){ 
     // Invert the logic 
     smoothedValue = oldVal - smoothing * (oldVal + 360 - degree); 
     if (smoothedValue < 0){ 
     smoothedValue = smoothedValue + 360; 
     } 
    } else if (oldVal - degree > 180){ 
     smoothedValue = oldVal + (360 + degree - oldVal) * smoothing; 
     if (smoothedValue > 360){ 
     smoothedValue = smoothedValue - 360; 
     } 
    } 
    else { 
     smoothedValue = oldVal + smoothing * (degree - oldVal); 
    } 
    return smoothedValue; 
} 

これは混乱しているようですが、私はちょうどその周りを遊んだ。あなたが必要としていることを願っています。

+0

それがそれでした。私はちょうどそれをやっていたが、あなたは私にそれを打つ。日曜日の冗談は、いくつかの鈍い論理的思考のためになります:) – opticon

1

複雑な数学を活用する場合は、これを行うより洗練された方法があります。基本的に、複素数でコンパス上の点を表すことができます。

enter image description here

あなたが「平均」または2回のコンパス測定値を「スムーズ」にしたい場合は、複雑なドメインにして、角度ドメインに戻って変換することを行うことができます。これにより

、我々は数学JSライブラリを使用することができますし、あなたが持っていた同じ形式で基本的にあなたの機能を残して:あなたはここでそれをいじることができ

var smoothing = .9; 


function lowPass(degree, oldVal) { 
    // var oldVal = $scope.compassBearing || 0; 
    var complexOldVal = math.complex({r:1, phi:oldVal * (math.pi/180)}); 
    var complexNewVal = math.complex({r:1, phi:degree * (math.pi/180)});  
    var complexSmoothedValue = math.chain(complexNewVal) 
            .subtract(complexOldVal) 
            .multiply(smoothing) 
            .add(complexOldVal) 
            .done(); 
    var smoothedValue = math.arg(complexSmoothedValue) * (180/math.pi); 
    if (smoothedValue < 0) { return 360 + smoothedValue; } 
    return smoothedValue; 
} 

document.write(lowPass(20, 30)+'<br>'); 
// 20.99634415156203 
document.write(lowPass(10, 350)+'<br>'); 
// 8.029256754215519 

を:http://jsbin.com/zelokaqoju/edit?html,output

+0

私は、私が実際に私の上にこの解決策を気にすることができることを認めなければなりません。しかし、私が外部の図書館を持ち込み、ラディアンに慣れていない人々のためのコードを疎遠にしていると思うこの単純なアプリケーションの場合、ちょっと残忍かもしれません。まだそれを愛しています:) – dannyjolie

+0

私はあなたのことを聞いて、一般的に同意します...あなたが好きなスムージングをしたい場合は、このアプローチの利点の1つは簡単にスケールです。角度領域で平均化以外の処理を行うと、望ましくない結果につながる可能性があります。 –

+0

すべてのカウントに同意します:Pダニーを選び、純粋に読みやすくするために実装しました。このソリューションはエレガントに見えますが、基本的に私にとってはブラックボックスです! – opticon

関連する問題