2016-03-20 15 views
3

Ben pusula yatak girişi için bir alçak geçirgen filtre uygulamak çalışıyorum ve ben birlikte şöyle bir temel işlevi koyduk:Alçak geçiren pusula yumuşatma garabeti

var smoothing = 0.15; 

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

dışında büyük İşleri pusula taşıyan kuzey geçtiğinde için (yani. aniden 0'dan 359 veya tersi olarak değişir.

Has eğer öyleyse herkes, benzer bir sorunu çalıştırmak ve bu çözüldü nasıl?

+0

sorun nedir? "smoothValue", ör. 361, -2, vb? – dannyjolie

+0

Yumuşatma, okumayı diğer tarafa 'pürüzsüz' yapmaya çalışır - yani, 356 -> 358 -> 0 -> 2'den geçişi yumuşatmak yerine, iki değeri ortalama olarak pusulaya getirmeye çalışır. Yeni değerlerle buluşmak için ters yönde dönüyor. – opticon

+0

Evet, bunu düşündüm. Sadece senaryonuzu kendim denedim ve gerçek sorununu gördün. Örn. 359'dan 10'a, 0'dan değil, “geriye” gider. Sorudan belli değildi. – dannyjolie

cevap

4

hep seni diyelim En kısa yoldan pürüzsüz hale getirilmesini istiyorsanız, eğer değişim 270 dereceden 5'e kadar ise derece, kuzeyden geçer, sonra değerleri kontrol etmek ve aralarındaki farkın 180'den fazla olup olmadığını görmek zorundasınız. Eğer öyleyse, fonksiyonu biraz değiştirin.

Fark -180'den küçükse, birkaç operatörü ters çevirin ve karışıma 360 ekleyin. Aynı fark, 180'den büyükse aynı şekilde devam eder. Son olarak sonucun 360'dan fazla veya 0'dan küçük olup olmadığını kontrol edin ve düzeltin.

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; 
} 

Karmaşık görünüyor, ama ben sadece onunla oynadım. Umarım ihtiyacın olan şey budur.

+0

Müthiş çözümünü çözmek için trig kullanır. Bu yaptı. Sadece bunu dalga geçiyordum ama sen beni dövüyordun. Pazar hangovers bazı bodur mantıksal düşünme için yaparlar :) – opticon

1

Karmaşık matematikten yararlanırsanız bunu yapmanın daha zarif bir yolu vardır. Temel olarak, karmaşık bir sayı ile pusula üzerinde bir nokta temsil edebilir.

enter image description here

sen "ortalama" veya iki pusula okumalarını "pürüzsüz" istiyorsanız, karmaşık etki alanındaki ve sonra açı etki alanına geri dönüştürmek yapabilir. Bununla

, size sahip olduğunu math js kitaplığı kullanan ve aynı formda temelde işlev bırakabilirsiniz:

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 

Burada onunla oynama işini: http://jsbin.com/zelokaqoju/edit?html,output

+0

Kabul etmeliyim, gerçekten bu çözüm üzerinde benimkini aşabilirim. Ama bu basit bir uygulama için harici bir kütüphane getirmeyi düşünüyorum ve radyanla tanıdık olmayanlar için kodu yabancılaştırmak biraz aşırı olabilir. Yine de onu seviyorum :) – dannyjolie

+0

Seni duyuyorum ve genel olarak kabul ediyorum ... Bu yaklaşımın avantajlarından biri, meraklı yumuşatma yapmak istiyorsanız kolayca ölçeklendirilebilmesi. Açı alanındaki ortalamadan başka bir şey yapmak, istenmeyen sonuçlara yol açabilir. –

+0

Tüm sayılarda katılıyorum: P Danca'yı aldı ve okunabilirlik için tamamen uyguladı. Bu çözüm zarif görünüyor, ama aslında benim için kara bir kutu! – opticon