0

(对不起,我的英语不好,我是意大利人)我是 Android 编程新手,我有这个问题:我需要加速度计数据(sqrt(x*x..) 的最大值和最小值)每个“1”秒,如果它们的差值(增量)的绝对值小于 0.4*Gravity_earth,我需要在条件的前 5 秒内获取的数据,然后我计算最大值。如果该值大于 THRESHOLD,我将标记为“非跌倒”或“跌倒”。有人可以简单地解决我的问题吗?谢谢!这是我的解决方案:

public class MainActivity extends Activity implements SensorEventListener{


SensorManager sm;
float acc;  
private float [] sensorData;
float azimuth,pitch,roll;
float omegaMagnitude;
//ArrayList
ArrayList<Float> tutteLeAcc =new ArrayList();
ArrayList<Float> previousAcc=new ArrayList();
Iterator<Float> it;
Iterator<Float> it1;
float accMax;
float accMin;

float accPreviousMax;
float deltaAcc;


   private static final String TAG = "SIMTHR";

   public static final int MSG_C = 3; 
   public static final int MSG_D = 4; 


   WorkerThread mWorkerThread;
   WorkerThread1 mWorkerThread1;

   boolean isRunning = false;
   boolean running;
   Button btnStart,btnStop;
   TextView txtLog;
   int tt = 0;

   boolean caduta;



   final Handler mHandler = new Handler() {
      @Override
      public void handleMessage(Message msg) {
         switch (msg.what) {

         case MSG_C:
            //it=tutteLeAcc.iterator();
            txtLog.setText("");
            txtLog.append("\nAmax: "+Float.toString(accMax)+" Amin:         "+Float.toString(accMin)+" dA: "+Float.toString(deltaAcc));
            tutteLeAcc.clear();

            break;

         case MSG_D:

             txtLog.append("\nPreviousACCmax: "+Float.toString(accPreviousMax)+"\n");
             //previousAcc.clear();

         break;
         }
         caduta=Detection(previousAcc,deltaAcc);
         //previousAcc.clear();
      }
   };


    class WorkerThread extends Thread {

      public Handler mCallerHandler;
      private int nn = 1;

      public WorkerThread(Handler handler) {

       mCallerHandler = handler;
        Log.i(TAG,"create WorkerThread");
      }

  public void run() {
     nn = 0;
     while(running){
     try {
        Log.i(TAG,"WorkerThread inizia qua");
        if (mCallerHandler!=null) {


           accMax=trovaMax(tutteLeAcc);
           accMin=trovaMin(tutteLeAcc);
           deltaAcc=Math.abs(accMax-accMin);
           Thread.sleep(1000);  
           mCallerHandler.obtainMessage(MSG_C).sendToTarget();

           Log.i(TAG,"WorkerThread finisce qua");
        }
     } catch (InterruptedException e) {
        Log.e(TAG,"errore in WorkerThread "+e.toString());
     }
  }
  }


  public synchronized void start() {
     running=true;
     super.start();
     Log.i(TAG,"WorkerThread avviato");
  }

  public synchronized void cancel() {
      running=false;
      Log.i(TAG,"WorkerThread avviato");
   }

}

     class WorkerThread1 extends Thread {

      public Handler mCallerHandler;
      private int nn = 1;

      public WorkerThread1(Handler handler) {
         // salvo l'handler dei messaggi dell'activity chiamante
         mCallerHandler = handler;
         Log.i(TAG,"create WorkerThread1");
      }

      public void run() {

         nn = 0;
         while(running){
         try {
            Log.i(TAG,"WorkerThread1 inizia qua");
            if (mCallerHandler!=null) {

               accPreviousMax=trovaMax(previousAcc);
               Thread.sleep(5000);  
               mCallerHandler.obtainMessage(MSG_D).sendToTarget();

               Log.i(TAG,"WorkerThread finisce qua");
            }
         } catch (InterruptedException e) {
            Log.e(TAG,"errore in WorkerThread "+e.toString());
         }
      }
      }

      // avvio del thread
      public synchronized void start() {
         running=true;
         super.start();
         Log.i(TAG,"WorkerThread avviato");
      }

      public synchronized void cancel() {
          running=false;
          Log.i(TAG,"WorkerThread avviato");
       }

   }


        @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main);
          Log.i(TAG,"Activity ONCREATE");

  sm = (SensorManager)getSystemService(SENSOR_SERVICE);

  sm.registerListener(this,sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL);
  sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL);
  sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_NORMAL);

  // oggetti della User Interface
  btnStart = (Button) findViewById(R.id.btnStart);
  btnStop=(Button)findViewById(R.id.btnStop);
  txtLog = (TextView) findViewById(R.id.txtLog);
  txtLog.setTextColor(Color.WHITE);

  sensorData = new float[9];

  // button per l'avvio del thread
  btnStart.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
          if (mWorkerThread!=null&&mWorkerThread1!=null) {
             mWorkerThread.cancel();
             mWorkerThread1.cancel();
             mWorkerThread = null; mWorkerThread1 = null;
             txtLog.append("\nrichiesto arresto THREAD 1 e 2 #"+Integer.toString(tt)+"\n");
          }
          tt++;
          mWorkerThread = new WorkerThread(mHandler);
          mWorkerThread1 = new WorkerThread1(mHandler);
          mWorkerThread.start(); mWorkerThread1.start();
          isRunning = true;
          txtLog.append("\nrichiesto avvio THREAD 1 e 2\n");
       }
    });

    // button per l'arresto del thread
    btnStop.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
          if (mWorkerThread!=null&&mWorkerThread1!=null) {
             mWorkerThread.cancel();
             mWorkerThread1.cancel();
             mWorkerThread = null; mWorkerThread1 = null;
             txtLog.append("\nrichiesto arresto THREAD 1 e 2\n");
          }
          isRunning = false;
       }
    });

}

      public void Deregistra(){
sm.unregisterListener(this);
       }


         public void Registra(){
sm.registerListener(this,sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL);
           }

           @Override
           public void onSensorChanged(SensorEvent event) {

float [] values = event.values;


synchronized (this) {

        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {

                sensorData[0] = event.values[0];

                sensorData[1] = event.values[1];

                sensorData[2] = event.values[2];


            if ((sensorData[3] != 0)||(sensorData[4] != 0)||(sensorData[5] != 0)
                    ||(sensorData[6] != 0)||(sensorData[7] != 0)||(sensorData[8] != 0))

            {

                     float ax=sensorData[0];
                     float ay=sensorData[1];
                     float az=sensorData[2];



                     acc=(float) Math.sqrt((ax*ax)+(ay*ay)+(az*az));

                     /*
                     tutteLeAcc.add(acc);
                     accMax=trovaMax(tutteLeAcc);
                     accMin=trovaMin(tutteLeAcc);
                     deltaAcc=Math.abs(accMax-accMin);
                       */
                     tutteLeAcc.add(acc);
                     previousAcc.add(acc);

                    }

            }


        else if (event.sensor.getType() == Sensor.TYPE_ORIENTATION ) {


            sensorData [3] = values[0];
            sensorData [4] = values[1];
            sensorData [5] = values[2];


            if ((sensorData[0] != 0)||(sensorData[1] != 0)||(sensorData[2] != 0)
                    ||(sensorData[6] != 0)||(sensorData[7] != 0)||(sensorData[8] != 0))
            {
                    azimuth=sensorData[3];
                    pitch=sensorData[4];
                    roll=sensorData[5];


            }
        }
        else if(event.sensor.getType()==Sensor.TYPE_GYROSCOPE){
            sensorData [6] = values[0];
            sensorData [7] = values[1];
            sensorData [8] = values[2];

            final float gx=sensorData[6];
            final float gy=sensorData[7];
            final float gz=sensorData[8];

            if ((sensorData[0] != 0)||(sensorData[1] != 0)||(sensorData[2] != 0)
                    ||(sensorData[3] != 0)||(sensorData[4] != 0)||(sensorData[5] != 0))
            {

                float axisX = sensorData[6];
                float axisY = sensorData[7];
                float axisZ = sensorData[8];

                // Calculate the angular speed of the sample
                omegaMagnitude = (float) Math.sqrt((axisX*axisX) + (axisY*axisY) + (axisZ*axisZ));


            }
        }

}

}

            public float trovaMin(ArrayList<Float> a){
Iterator<Float> it=a.iterator();
float min=a.get(0);
while(it.hasNext()){
    Float x=it.next();
    if(x<min){
        min=x;}
}
return min;

}

         public float trovaMax(ArrayList<Float> a){
Iterator<Float> it=a.iterator();
float max=a.get(0);
while(it.hasNext()){
    Float x=it.next();
    if(x>max){
        max=x;}
}
return max;

}

          public boolean Detection(ArrayList<Float> accPrec,float delta){
boolean intentional=true, static=true, lying=false;
float am;


if(delta<0.4*SensorManager.GRAVITY_EARTH){
   statico=true;
    Log.v("STATIC?", "yes");

    if(static){
       if(Math.abs(pitch)>=140||Math.abs(pitch)<30){ 
       lying=true;
       Log.v("LYING?", "yes");
       if(allungato){
          am=findMax(accPrec); 
          if(am>2.5*SensorManager.GRAVITY_EARTH||omegaMagnitude>200){
              intentional=true;
              Log.v("INTENTIONAL?", "yes");
          }else{
              intenzionale=false;
              Log.v("INTENTIONAL?", "no");
          }
       }
       }else {
           lying=false;
           Log.v("STANDING?", "yes");
           }
       }
       } else {
           static=false;
           Log.v("STATIC?", "no");
           }

      if(static&&lying&&!intenional)
          return true;

      else return false;
      }

}

4

2 回答 2

0

没有确切的方法可以告诉哪个样本是哪一秒获得的。但是您可以通过固定获得加速度计更新的频率来近似它。

假设我们第二次请求 50 个样本(50 赫兹)

为了这

sm.registerListener(this,sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),50000000);

不要使用 android 传感器延迟常量(即 SensorManager.SENSOR_DELAY_NORMAL),它们对于不同的供应商设备是不同的。

现在只需运行一个简单的计数器 0 到 50(没有其他方法 :()

我希望这可以帮助你。

于 2013-01-07T14:57:27.927 回答
0

我的建议是以最大可能的频率运行传感器: sm.registerListener(this,sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_FASTEST); 因为无论如何,设备在任何情况下都没有严格遵守数字指示的速率;此外,仅从 API v.2.3 起才支持“数字”速率。然后,您应该像这样编写 onSensorChanged 方法。评论:您检查当前时间是否大于 latestSensorChange + DELTASENSOR(即您希望在 Sensor 值之间等待的毫秒数)。

 @Override
public void onSensorChanged(SensorEvent event) {
    float[] values = event.values;
    long Now = System.currentTimeMillis();
    if (Now > (latestSensorChange + DELTASENSOR)) {

/*            if ((mDbHelper.getOldVal(BreathDbAdapter.IDX_X) != values[BreathDbAdapter.IDX_X]) ||
                    (mDbHelper.getOldVal(BreathDbAdapter.IDX_Y)!= values[BreathDbAdapter.IDX_Y]) ||
                    (mDbHelper.getOldVal(BreathDbAdapter.IDX_Z)!= values[BreathDbAdapter.IDX_Z])) {

  */
        msg = "Accelerometer: " + values[0]
                + ", " + values[1] + ", " + values[2] + " at " + Now + " (EndTime =" + EndTime +")";
        mTextViewAccelerometer.setText(msg);
        Log.v(TAG, msg );
        latestSensorChange = Now;
        if (Now > EndTime) {
            Log.v(TAG,"Fine del Test at " + Now);
            finish();
        }
    }

请让我知道它是否有帮助 (sennò ti vengo a cercare perchè sono Italiano anch'io :-) ) Checco

于 2013-05-15T16:38:58.993 回答