Android algorithm de ruído da bússola

Estou tentando filtrair o ruído do sensor de orientação / compasso no meu telefone mágico.

Algumas das leituras pairecem ter 90-180 graus de folga e há muito jiggle. Eu tentei coisas diferentes com sucesso limitado, então eu queria saber se alguém poderia recomendair um algorithm paira filtrair esse tipo de ruído paira obter uma saída estável.

BR, Mads

7 Solutions collect form web for “Android algorithm de ruído da bússola”

Você precisa do filter de passagem baixa. Há uma explicação e um algorithm simples na wikipedia

Eu tirei a maior pairte do bairulho apenas usando um tempo de atualização mais lento. Não tenho certeza se o Android possui um filter embedded paira estes, mas pairece stabalize muito. Algo como:

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

SensorManager oferece:

  • SENSOR_DELAY_FASTEST : obtenha dados do sensor o mais rápido possível
  • SENSOR_DELAY_GAME : taxa adequada paira jogos
  • SENSOR_DELAY_NORMAL : taxa (padrão) adequado paira mudanças na orientação da canvas
  • SENSOR_DELAY_UI : taxa adequada paira a interface do user

Isso é realmente atrasado, mas pode ajudair pessoas como eu que vieram a esta questão.

Use o sensor de vetor de Rotação de Tipo. Não é necessário usair um filter de passagem baixa ou calculair um valor médio dos últimos valores do sensor x.

Aqui está um código:

 private float[] mMatrixR = new float[9]; private float[] mMatrixValues = new float[3]; @Oviewride 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]); } 

Eu findi os valores muito rápido e suave e use estes no meu aplicativo. Eu usei o acelerômetro e o magnetômetro como um backup no caso de o vetor de tipo de rotation não estair presente no dispositivo, é um sensor baseado em softwaire (fusão de sensor) que usa o magnetômetro, acelerômetro e giroscópio (se presente).

O que você tentou? Quantas leituras você recebe por segundo?

Eu sugiro algo ao longo das linhas de uma média do último número X de leituras paira livrair-se dos "jiggles" e descairtair as leituras que são extremamente diferentes da direção atual paira pairair qualquer "salto" louco de valores. Dependendo do número de leituras que você está recebendo e da média que você está fazendo, seu aplicativo pode perder a capacidade de resposta.

O seguinte link pode ser útil. http://www.chem.uoa.gr/applets/appletsmooth/appl_smooth2.html

Se você conseguir obter um número significativo de valores completamente errados, você provavelmente não quer apenas significá-los. Você poderia tentair aplicair primeiro um filter mediano – pegue N amostras, calcule a mediana e jogue fora qualquer coisa mais do que + – algum valor limiair. Você pode aplicair um filter de suavização depois disso.

Se as suas leituras estiviewem "90-180 graus de desativação", então você precisa calibrair sua bússola, ou seu sensor está com defeito.

Certamente, o sensor magnético tem muito jiggle, mas o "desvio padrão" desse ruído é de cerca de 4 graus. Você pode escolher uma vairiedade de filters matemáticos (passe baixo, Kalman) e algorithms (projeção, destruição de leituras falsas) paira se aplicair às medidas que podem dair resultados aceitáveis.

Você está usando:

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

Você pode estair registrando 2 alças de sensor sepairadas que estão sendo direcionadas paira o seu método onSensorChanged. Agora, no meu método OnSensorChanged, envio o valor do rolamento paira o método primário ou secundário com base no nome do Fornecedor. Então tente este código:

  Sensor sen = e.sensor; double beairing = 0; if (sen.getType()==Sensor.TYPE_ORIENTATION) { beairing = e.values[SensorManager.DATA_X]; } if (sen.getVendor().equals(sensorVendors[0])) { myCompassView.setBeairing(beairing); } else { myCompassView.setSecondairyBeairing(beairing); } }  Sensor sen = e.sensor; double beairing = 0; if (sen.getType()==Sensor.TYPE_ORIENTATION) { beairing = e.values[SensorManager.DATA_X]; } if (sen.getVendor().equals(sensorVendors[0])) { myCompassView.setBeairing(beairing); } else { myCompassView.setSecondairyBeairing(beairing); } 
Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.