方向センサーの読み取り値がうまく取得できません。センサーの読み取り値は信頼できないように見えたので、2 つの無料のセンサー テスト アプリ ( Sensor Tester (Dicotomica)とSensor Monitoring (R's Software) ) に対してコードをテストしました。私の測定値は多くの場合、センサー テスト アプリと一致していましたが、ピッチの測定値はほぼ一致していましたが、方位角/ヨーとロールの値が最大 40 度異なる場合がありました。2 つの無料アプリは常に一致しているように見えました。
コードを小さな Android アクティビティに入れましたが、同じ不整合が発生しました。コードは次のとおりです。
public class MainActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private float[] AccelerometerValues;
private float[] MagneticFieldValues;
private float[] RotationMatrix;
private long nextRefreshTime; // used to ensure dump to LogCat occurs no more than 4 times a second
private DecimalFormat df; // used for dumping sensors to LogCat
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager = (SensorManager)getSystemService(android.content.Context.SENSOR_SERVICE);
Sensor SensorAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, SensorAccelerometer, SensorManager.SENSOR_DELAY_UI);
Sensor SensorMagField = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
mSensorManager.registerListener(this, SensorMagField, SensorManager.SENSOR_DELAY_UI);
AccelerometerValues = new float[3];
MagneticFieldValues = new float[3];
RotationMatrix = new float[9];
nextRefreshTime = 0;
df = new DecimalFormat("#.00");
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
System.arraycopy(event.values, 0, AccelerometerValues, 0, AccelerometerValues.length);
else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
System.arraycopy(event.values, 0, MagneticFieldValues, 0, MagneticFieldValues.length);
if (AccelerometerValues != null && MagneticFieldValues != null) {
if(SensorManager.getRotationMatrix(RotationMatrix, null, AccelerometerValues, MagneticFieldValues)) {
float[] OrientationValues = new float[3];
SensorManager.getOrientation(RotationMatrix, OrientationValues);
// chance conventions to match sample apps
if (OrientationValues[0] < 0) OrientationValues[0] += 2*(float)Math.PI;
OrientationValues[2] *= -1;
// dump to logcat 4 times a second
long currentTimeMillis = System.currentTimeMillis();
if (currentTimeMillis > nextRefreshTime) {
nextRefreshTime = currentTimeMillis+250;
Log.i("Sensors", // arrange output so that numbers line up in columns :-)
"(" + AngleToStr(OrientationValues[0]) + "," + AngleToStr(OrientationValues[1]) + "," + AngleToStr(OrientationValues[2])
+ ") ("+FloatToStr(AccelerometerValues[0]) + "," + FloatToStr(AccelerometerValues[1]) + "," + FloatToStr(AccelerometerValues[2])
+ ") ("+FloatToStr(MagneticFieldValues[0]) + "," + FloatToStr(MagneticFieldValues[1]) + "," + FloatToStr(MagneticFieldValues[2])+")");
}
}
}
}
private String AngleToStr(double AngleInRadians) {
String Str = " "+Integer.toString((int)Math.toDegrees(AngleInRadians));
return Str.substring(Str.length() - 3);
}
private String FloatToStr(float flt) {
String Str = " "+df.format(flt);
return Str.substring(Str.length() - 6);
}
@Override
protected void onDestroy() {
super.onDestroy();
mSensorManager.unregisterListener(this);
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) { }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
Jelly Bean 4.1.1 を実行している Galaxy Note 2 を使用しています。誰が私が間違っているのか教えてもらえますか?
2013 年 3 月 24 日更新: 詳細情報。(1) マニフェストで縦向きと横向きの切り替えを無効にしたので、getWindowManager().getDefaultDisplay().getRotation() は常にゼロです。したがって、ここでは remapCoordSystem が役立つとは思いません。これは軸を切り替えるためのものですが、私が見ているエラーは大きなエラーではなく、はるかに微妙です。(2) 精度の感度を確認しましたが、両方のセンサーが高い精度を主張している場合に矛盾が発生します。
私が見ている不一致の例として、上記のコードで (azimuth,pitch,roll) = (235,-52,-11) が得られた場合、2 つの無料アプリは同様の値を示します。しかし、私が (278, -58, -52) を見ると、アプリは (256, -58, -26) を示しています。