2014-11-30 5 views
0

Я следующий код, который отлично работает на моем Nexus 5.Android - Как обнаружить изменения в компас степени (Java)

public void onSensorChanged(SensorEvent event) { 
     float degree = Math.round(event.values[0]); 
     displayMsg.setText(String.valueOf(degree)); 
} 

degree содержит направление компаса в. Я хочу сделать это, чтобы обнаружить изменения в направлении. Итак, скажем, если человек идет на север, а затем на 10 градусов вправо. Как только человек меняет направление, я хочу заметить. Кроме того, существуют неопределенности. Так, например, когда человек идет на север, направление не является постоянным 0 градусов. Он будет колебаться между 358 и 2-3 градусами.

Я думал использовать Timer.schedule для хранения градусов каждые 500 мс, а затем сделать

if(Math.abs(degree - storedDegree) > 10) 
    Toast.makeText(this,"Direction Changed",Toast.LENGTH_SHORT).show(); 

Однако этот метод работает из памяти из-за количества потоков, созданных я думаю. Есть ли более умный/лучший способ обнаружения изменений в направлении?


UPDATE

Вот полный код, который я делаю.

Я подсчитываю шаги, и я хочу сохранить направление, в котором выполняются шаги. Как только направление изменяется, скажем, на 10 градусов, счетчик шагов должен сохранить значение, которое он имеет (скажем, в списке массивов), а затем перейти к 0 и перезапустить подсчет.

boolean start = true; 

@Override 
public void onSensorChanged(SensorEvent event) { 
    //------------------------------Compass-------------------------------------- 
    final float degree = Math.round(event.values[0]); 
    displayMsg.setText(String.valueOf(degree)); 
    //--------------------------------------------------------------------------- 

    Sensor sensor = event.sensor; 
    float[] values = event.values; 
    int value = -1; 
    int steps; 

    if (values.length > 0) { 
     value = (int) values[0]; 
    } 

    if(mode.equals("Start")) 
    { 
     if (sensor.getType() == Sensor.TYPE_STEP_COUNTER) 
     { 
      if(start) 
      { 
       count = value; 
       start = false; 
      } 
      steps = value-count; 
      stepCounter.setText("Step Counter Detected : " + steps); 
     } 
    } 
} 
+0

Что не так с тем, что у вас есть?Кажется, что onSensorChanged следует вызывать, когда когда-либо человек меняет направление, а затем вы просто сравниваете текущую степень с сохраненным значением (как вы показали) – nPn

+0

'onSensorChanged' не получает вызов сверхурочно, когда человек меняет направление. он постоянно называется всегда. Проблема с тем, что я предложил, заключается в том, что я использую 'Timer timer = new Timer();' then 'timer.schedule (timerTask, 5000)' method. но у этого метода заканчивается память! – Masster

ответ

1

Я бы использовал фильтр нижних частот, чтобы устранить колебания.

вот код:

protected float[] lowPass(float[] input, float[] output) { 
    if (output == null) return input; 
    for (int i = 0; i < input.length; i++) { 
     output[i] = output[i] + ALPHA * (input[i] - output[i]); 
    } 
    return output; 
} 

Где ALPHA является статического окончательного поплавок ALPHA = 0.25f;

Я также отправлю код для получения «направления». Может быть, это поможет вам:

protected void onResume() { 
    super.onResume(); 
    mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI); 
    mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_UI); 
} 

protected void onPause() { 
    super.onPause(); 
    mSensorManager.unregisterListener(this); 
} 


@Override 
public void onSensorChanged(SensorEvent event) { 
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) 
     mGravity = lowPass(event.values.clone(), mGravity); 
    if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) 
     mGeomagnetic = lowPass(event.values.clone(), mGeomagnetic); 
    if (mGravity != null && mGeomagnetic != null) { 
     float R[] = new float[9]; 
     float I[] = new float[9]; 
     boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic); 
     if (success) { 
      float orientation[] = new float[3]; 
      SensorManager.getOrientation(R, orientation); 
      azimut = orientation[0]; // orientation contains: azimut, pitch and roll 
     } 
    } 

} 

после этого используйте Азимут так:

 if (azimut != null) { 
      canvas.rotate(-azimut * 360/(2 * 3.14159f), centerx, centery); 

      if ((azimut > -0.2) && (azimut < 0.2)) current_direction = "North"; 
      if ((azimut > 1.3) && (azimut < 1.7)) current_direction = "East"; 
      if (((azimut < -2.8) && (azimut > -3.2)) || ((azimut < 3.2) && (azimut > 2.8))) current_direction = "South"; 
      if ((azimut > -1.7) && (azimut < -1.3)) current_direction = "West"; 
     } 
+0

Где бы я точно установил свой mGravity и mGeomagnetic? – Masster

+0

И эти коды - просто другой способ сделать компас. Я хочу обнаружить, когда theres изменение 10 градусов в направлении – Masster

1

Я думаю, ваша проблема больше связана с датчиками и не ваша логика. Вы можете попробовать это, но я не отказываюсь от датчиков. Я знаю, что служба определения местоположения может предоставить вам устройство, несущее (через gps), что также может быть вариантом.

Можете ли вы проверить, что текущая степень изменилась более чем на порог, а затем обновить сохраненное значение с новой степенью?

Один из возможных примеров может быть примерно таким: Идея состоит в том, что, поскольку onSensorChanged вызывается всякий раз, когда значение обновляется, вы можете проверить, является ли разность между текущей степенью и хранимым значением больше определенного порогового значения. Если это принятие меры и сохранение новой степени, если это изменение просто игнорируется.

private float storedDegree; 

public void onSensorChanged(SensorEvent event) { 
    if (sensor.getType() == Sensor.TYPE_ORIENTATION) { 
     float degree = Math.round(event.values[0]); 
     if(Math.abs(degree - storedDegree) > 10) { 
      Toast.makeText(this,"Direction Changed",Toast.LENGTH_SHORT).show(); 
      displayMsg.setText(String.valueOf(degree)); 
      storedDegree = degree; 
     } 
    } 
} 
+0

Не работает !! – Masster

+0

Я имею в виду пример. – nPn

+0

Да, я пробовал это и пробовал много вариантов его тоже – Masster

Смежные вопросы