2012-11-08 8 views
13

私は、加速度計と磁場センサーを使用してAndroid搭載のコンパスをプログラミングしようとしていますが、コンパスの正しい角度を取得する方法は不思議です。Androidのコンパス

私は加速度センサーと磁界センサーの値をそれぞれ "accele"と "magne"で読みました。角度を取得するには、私は次の手順を実行します。

float R[] = new float[9]; 
float I[] = new float[9]; 
boolean success = SensorManager.getRotationMatrix(R, I, accele, magne); 
     if(success) { 
      float orientation[] = new float[3]; 
      SensorManager.getOrientation(R, orientation); 
      azimuth = orientation[0]; // contains azimuth, pitch, roll 
          .... 

その後、私は私の針を入れて回転行列を使用します。

rotation.setRotate(azimuth, compass.getWidth()/2, compass.getHeight()/2); 
canvas.drawBitmap(needle, rotation, null); 

、getOrientationのドキュメントは、その方向性を述べている[0] z軸回りの回転でなければなりません。 TYPE_ORIENTATIONのドキュメントには、 「方位、磁北方向とy軸の間の角度、z軸(0〜359)、0 =北、90 =東、180 =南、270 =西」と記載されています。

私の方位角は0と359の間ではなく、むしろ-2から2の間です。getOrientationの方位角はどういうもので、どのように角度に変換できますか?

答えて

20

に0の間で学位を得るか見ることができるように度(0、+ PI)、360)便宜のために使用

float azimuthInRadians = orientation[0]; 
float azimuthInDegress = (float)Math.toDegrees(azimuthInRadians); 
if (azimuthInDegress < 0.0f) { 
    azimuthInDegress += 360.0f; 
} 

変数名;-)

+0

ありがとう:)最後のif文は正確に何ですか? – user1809923

+0

Math.toDegrees()は、-PIと+ PIラジアンの角度から-180と180の間の角度を与えます。これはすべてを正の方向に向けるだけです。 – rgrocha

+0

これは正しい答えです。 –

2

私はGoogleのApiDemosでこれを見つけた:

/* 
* Copyright (C) 2007 The Android Open Source Project 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

package com.example.android.apis.graphics; 

import android.app.Activity; 
import android.content.Context; 
import android.graphics.*; 
import android.hardware.SensorListener; 
import android.hardware.SensorManager; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.os.SystemClock; 
import android.util.Config; 
import android.util.Log; 
import android.view.View; 

public class Compass extends GraphicsActivity { 

    private static final String TAG = "Compass"; 

    private SensorManager mSensorManager; 
    private SampleView mView; 
    private float[] mValues; 

    private final SensorListener mListener = new SensorListener() { 

     public void onSensorChanged(int sensor, float[] values) { 
      if (Config.LOGD) Log.d(TAG, "sensorChanged (" + values[0] + ", " + values[1] + ", " + values[2] + ")"); 
      mValues = values; 
      if (mView != null) { 
       mView.invalidate(); 
      } 
     } 

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

     } 
    }; 

    @Override 
    protected void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 
     mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); 
     mView = new SampleView(this); 
     setContentView(mView); 
    } 

    @Override 
    protected void onResume() 
    { 
     if (Config.LOGD) Log.d(TAG, "onResume"); 
     super.onResume(); 
     mSensorManager.registerListener(mListener, 
       SensorManager.SENSOR_ORIENTATION, 
       SensorManager.SENSOR_DELAY_GAME); 
    } 

    @Override 
    protected void onStop() 
    { 
     if (Config.LOGD) Log.d(TAG, "onStop"); 
     mSensorManager.unregisterListener(mListener); 
     super.onStop(); 
    } 

    private class SampleView extends View { 
     private Paint mPaint = new Paint(); 
     private Path mPath = new Path(); 
     private boolean mAnimate; 
     private long mNextTime; 

     public SampleView(Context context) { 
      super(context); 

      // Construct a wedge-shaped path 
      mPath.moveTo(0, -50); 
      mPath.lineTo(-20, 60); 
      mPath.lineTo(0, 50); 
      mPath.lineTo(20, 60); 
      mPath.close(); 
     } 

     @Override protected void onDraw(Canvas canvas) { 
      Paint paint = mPaint; 

      canvas.drawColor(Color.WHITE); 

      paint.setAntiAlias(true); 
      paint.setColor(Color.BLACK); 
      paint.setStyle(Paint.Style.FILL); 

      int w = canvas.getWidth(); 
      int h = canvas.getHeight(); 
      int cx = w/2; 
      int cy = h/2; 

      canvas.translate(cx, cy); 
      if (mValues != null) {    
       canvas.rotate(-mValues[0]); 
      } 
      canvas.drawPath(mPath, mPaint); 
     } 

     @Override 
     protected void onAttachedToWindow() { 
      mAnimate = true; 
      super.onAttachedToWindow(); 
     } 

     @Override 
     protected void onDetachedFromWindow() { 
      mAnimate = false; 
      super.onDetachedFromWindow(); 
     } 
    } 
} 

あなたは-PI(ラジアンで与えられた方位から変換するには、以下を使用して360

+0

あなたが説明した場合、それは素晴らしいだろう:) – user1809923

+0

私は自分の答えを編集します。 –

+0

こんにちは、それは興味深いアプローチですが、私はちょうど-2から2と推定しているので、これはあまり正確ではないかもしれないと思います。 – user1809923

7

コードスニペットを入手できましたhttps://github.com/iutinvg/compass

ローパスフィルタを適用しています。

+0

final float alpha = 0.97f;を決定する基準は フィルタ定数としてはgoogle 0.8を使用しています。 – DeltaCap

+1

矢印の回転速度に影響します。だから選択は視覚に基づいている:よりスムーズな動き。 – iutinvg

関連する問題