0

(英語が下手ですみません、私はイタリア人です)私はAndroidプログラミングの初心者で、この問題があります:「1」ごとに加速度計データ(sqrt(x * x ..)の最大値と最小値)が必要です秒であり、それらの差 (デルタ) の絶対値が < 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

どのサンプルがどの秒に取得されたかを正確に知る方法はありません。ただし、加速度計の更新を取得する頻度を固定することで近似できます。

1 秒間に 50 サンプル (50 Hz) を要求するとします。

このため

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

Android センサー遅延定数 (つまり、SensorManager.SENSOR_DELAY_NORMAL) を使用しないでください。これらはベンダー デバイスによって異なります。

ここで、0 から 50 までの単純なカウンターを実行するだけです (他の方法はありません :()

これがお役に立てば幸いです。

于 2013-01-07T14:57:27.927 に答える