2009-12-10 38 views
8

Tôi đang cố gắng lọc nhiễu ra khỏi cảm biến hướng/la bàn trong điện thoại ma thuật của mình.Thuật toán tiếng ồn la bàn Android

Một số bài đọc có vẻ là 90-180 độ và có rất nhiều tiếng lách cách. Tôi đã thử những điều khác nhau với thành công hạn chế, vì vậy tôi đã tự hỏi nếu có ai có thể đề nghị một thuật toán để lọc loại tiếng ồn để có được một đầu ra ổn định.

BR, Mads

Trả lời

14

Bạn cần Bộ lọc thông thấp. Có giải thích và thuật toán đơn giản trên wikipedia

+7

Xem bài đăng trên blog tuyệt vời của Thom Nichols để biết ví dụ về cách triển khai bộ lọc thông thấp - Phần 1 (http://blog.thomnichols.org/2011/08/smoothing-sensor-data-with-a-low -pass-filter) và phần 2 (http://blog.thomnichols.org/2012/06/smoothing-sensor-data-part-2) –

+0

@JimJeffers Triển khai này rất đơn giản và rực rỡ. Trợ giúp rất nhiều. Cảm ơn ! – Shlublu

2

Bạn đã thử gì? Bạn nhận được bao nhiêu bài đọc mỗi giây?

Tôi sẽ đề xuất điều gì đó dọc theo dòng trung bình của số lần đọc X cuối cùng để loại bỏ các "tiếng cười" và vứt bỏ bất kỳ bài đọc nào khác với hướng hiện tại để ngăn chặn bất kỳ "nhảy" điên nào giá trị. Tùy thuộc vào số lượng bài đọc bạn đang nhận được và số tiền trung bình bạn đang làm, ứng dụng của bạn có thể mất phản hồi.

Liên kết sau có thể hữu ích. http://www.chem.uoa.gr/applets/appletsmooth/appl_smooth2.html

1

Nếu bạn nhận được một số lượng đáng kể các giá trị hoàn toàn sai, có thể bạn không muốn chỉ trung bình chúng. Bạn có thể thử áp dụng bộ lọc trung gian trước tiên - lấy N mẫu, tính trung bình và ném ra bất kỳ giá trị nào lớn hơn + - một số giá trị ngưỡng. Bạn có thể áp dụng một bộ lọc làm mịn sau đó.

3

Tôi đã loại bỏ hầu hết tiếng ồn chỉ bằng cách sử dụng thời gian cập nhật chậm hơn. Tôi không chắc liệu Android có tích hợp bộ lọc cho những bộ lọc này hay không, nhưng có vẻ như nó đã bị đánh bại rất nhiều. Một cái gì đó như:

mSensorManager.registerListener( 
    mSensorListener, 
    mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), 
    // SENSOR_DELAY_UI, instead of SENDOR_DELAY_FASTEST (or similar) 
    // seems to iron out a lot of the jitter 
    SensorManager.SENSOR_DELAY_UI 
); 

SensorManager cung cấp:

  • SENSOR_DELAY_FASTEST: có được dữ liệu cảm biến càng nhanh càng tốt
  • SENSOR_DELAY_GAME: tỷ lệ phù hợp cho các trò chơi
  • SENSOR_DELAY_NORMAL: Tốc độ (mặc định) thích hợp cho định hướng màn hình thay đổi
  • SENSOR_DELAY_UI: tỷ lệ phù hợp với giao diện người dùng
0

Nếu số đọc của bạn là "90-180 độ tắt", thì bạn cần phải hiệu chỉnh la bàn hoặc cảm biến của bạn bị lỗi.

Chắc chắn, cảm biến từ tính có nhiều tiếng lách cách, nhưng "độ lệch chuẩn" của nhiễu như vậy là khoảng 4 độ. Bạn có thể chọn một loạt các bộ lọc toán học (thông thấp, Kalman) và các thuật toán (tính trung bình, đọc các bài đọc giả) để áp dụng cho các phép đo có thể cho bạn kết quả chấp nhận được.

0

Bạn có sử dụng:

List<Sensor> sens = mySensorManager.getSensorList(Sensor.TYPE_ORIENTATION); 

Bạn có thể đăng ký 2 tay cầm cảm biến riêng biệt mà đều được hướng dẫn đến phương pháp onSensorChanged của bạn. Bây giờ, trên phương thức onSensorChanged của tôi, tôi đang gửi giá trị vòng bi cho phương thức chính hoặc phụ dựa trên tên Nhà cung cấp.Vì vậy, hãy thử mã này:

Sensor sen = e.sensor; 
    double bearing = 0; 
    if (sen.getType()==Sensor.TYPE_ORIENTATION) { 
     bearing = e.values[SensorManager.DATA_X]; 
    } 
    if (sen.getVendor().equals(sensorVendors[0])) { 
     myCompassView.setBearing(bearing); 
    } else { 
     myCompassView.setSecondaryBearing(bearing); 
    } 
4

Điều này thực sự là muộn nhưng nó có thể giúp những người như tôi đến với câu hỏi này.

Sử dụng loại Cảm biến vector xoay vòng. Không cần sử dụng bộ lọc thông thấp hoặc tính giá trị trung bình của các giá trị cảm biến x cuối cùng.

Dưới đây là một số mã:

private float[] mMatrixR = new float[9]; 
private float[] mMatrixValues = new float[3]; 

@Override 
public void onSensorChanged(SensorEvent event) { 
    switch (event.sensor.getType()) { 
     case Sensor.TYPE_ROTATION_VECTOR: 

      // Get rotation matrix 
      SensorManager.getRotationMatrixFromVector(mMatrixR, event.values); 

      SensorManager.getOrientation(mMatrixR, mMatrixValues); 

      // Use this value in degrees 
      mAzimuth = Math.toDegrees(mMatrixValues[0]); 

    } 

tôi tìm thấy những giá trị rất nhanh và trơn tru và sử dụng chúng trong ứng dụng của tôi. Tôi đã sử dụng gia tốc kế và từ kế làm sao lưu trong trường hợp vector loại xoay không có trong thiết bị, nó là cảm biến dựa trên phần mềm (Sensor fusion) sử dụng từ kế, gia tốc kế và con quay hồi chuyển (nếu có).