2011-10-28 74 views
0

我正在嘗試在測試手機(Nexus S)上使用傳感器API加速度計。隨着坐在板凳上的電話什麼都不做,我得到了一些非常奇怪的讀數(附圖)。有沒有其他人看到過這種行爲? Glitches in accel reading?任何想法如何處理它?Android加速計傳感器,異常值/毛刺

package com.example.m6; 

import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.InetAddress; 
import java.util.Calendar; 

import android.app.Activity; 
import android.content.Context; 
import android.content.pm.ActivityInfo; 
import android.graphics.Color; 
import android.hardware.Sensor; 
import android.hardware.SensorEvent; 
import android.hardware.SensorEventListener; 
import android.hardware.SensorManager; 
import android.os.Bundle; 
import android.os.PowerManager; 
import android.view.Window; 
import android.view.WindowManager; 
import android.widget.TextView; 
//import android.widget.Toast; 

public class HelloAndroidActivity extends Activity implements SensorEventListener { 
    private SensorManager sensorManager; 
    private TextView tv; 
    private float accel[] = {0,0,0}; 
    private float gyro[] = {0,0,0}; 


    InetAddress addr; 
    int port   = 1337; 
    DatagramSocket s = null; 
    String out  = ""; 
    PowerManager.WakeLock wl; 

    /** Called when the activity is first created. */ 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     try{ 
      //Lock the screen 
      super.onCreate(savedInstanceState); 
      requestWindowFeature(Window.FEATURE_NO_TITLE); 
      getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 

      //Set up the output screen 
      setContentView(R.layout.main); 
      tv = (TextView) findViewById(R.id.textview); 
      tv.setBackgroundColor(Color.BLACK); 
      tv.setTextColor(Color.GREEN); 

      //Set up the telemetry feed 
      addr = InetAddress.getByName("192.168.0.12"); 
      s = new DatagramSocket(); 

      //Turning off the power management!! 
      PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 
      wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "My Tag"); 
      wl.acquire(); 

      //Set up the sensors 
      sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); 

      out += "Done\n"; 
      tv.setText(out); 

     } catch (Exception e) { 
      out += "\nInit Error:" + e.getMessage() + "\n"; 
      tv.setText(out); 
     } 

    } 

    private static final float NS2S = 1.0f/1000000000.0f; 
    private float timestamp; 

    int down = 0; 
    float tstart = 0; 
    @Override 
    public void onSensorChanged(SensorEvent event) {    

     String type = ""; 
     float dT = 0;  
     if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { 
      if (timestamp != 0) { 
       accel = event.values; 
       dT = (event.timestamp - timestamp); 
       tstart += dT; 
      } 
      timestamp = event.timestamp; 
      type = "G"; 
     } 

     if(event.sensor.getType() == Sensor.TYPE_GYROSCOPE) { 
      if (timestamp != 0) { 
       gyro = event.values; 
       dT = (event.timestamp - timestamp); 
       tstart += dT; 
      } 
      timestamp = event.timestamp; 
      type = "A"; 
     } 

     String out_packet = tstart/1000/1000 + " "+ type + " " + dT + " " + accel[0] + " " + accel[1] + " " + accel[2] + " " + gyro[0] + " " + gyro[1] + " " + gyro[2] + "\n\0"; 

     try{ 
      DatagramPacket p = new DatagramPacket(out_packet.getBytes(),out_packet.length(), addr,port); 
      s.send(p); 
     } 
    catch (Exception e) { 
      out += "Packet send error: " + e.getMessage() + "\n"; 
     } 

     tv.setText(timestamp + "\n" + out); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     out += "on resume\n"; 
     sensorManager.registerListener(this,sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL); 
     sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_NORMAL); 
     tv.setText(out); 
    } 

    @Override 
    protected void onPause() { 
     out += "on pause"; 
     sensorManager.unregisterListener(this); 
     tv.setText(out); 
     super.onStop(); 

    } 

    @Override 
    protected void onDestroy() { 
     out += "on destroy"; 
     wl.release(); 
     tv.setText(out); 
     super.onDestroy(); 
    } 

    @Override 
    public void onAccuracyChanged(Sensor sensor, int accuracy) { 
     // TODO Auto-generated method stub 

    } 
} 
+0

在使用Droid 1時,我沒有注意到任何異常。儘管我總是不得不使用閾值來檢測我想要檢測的(移動序列),並且並未試圖檢測「任何」移動事件。 –

+0

我已添加代碼。希望這會對我正在聽的事件有所幫助。 – MattieG

回答

0

代碼會很好..試試這個演示代碼。我知道它的工作原理和繪製圖。

http://www.5laida.com/docs/android/samples/Sensors.html

我已經在多個設備上測試此代碼..所以,如果顯示了相同的故障,那麼它可能是您的設備。

+0

當然可以!這真是愚蠢。編輯過的問題包括來源。我應該警告你,我主要是C/C++開發人員,我的Java很生疏。所以,它可能我在代碼中做錯了什麼。我只用這種語言沒有直覺。 – MattieG

0

我已經知道發生了什麼事。我需要包括這條線:

 if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE){ 
     return; 
    } 

但是,通過這樣做,我現在沒有從陀螺儀中得到任何值。嗯...

+0

這裏是對這個問題的答案:http://stackoverflow.com/questions/5985514/android-xoom-accelererometer-accuracy-is-always-unreliable/6141875#6141875 – MattieG

+0

我不看事件的來源。準確性或Sensor_Status_unrelaible ..但是event.accuarcy輸出一個數值..所以也許你可以設置一個閾值。看看你的圖表,問題是完整的下降。如果變化是快速而激烈的,你可以隨時用一些if語句排除變更。很難支持所有的設備,特別是當操作系統不同時,而且還會影響物理電話的質量。 – DJPlayer

+0

祝賀解決方案。如果可以,請確保將您的答案標記爲「已接受」,以便其他人可以向您學習成功。乾杯〜 –