2012-11-08 60 views
13

Tôi đang cố gắng lập trình một la bàn với Android bằng cách sử dụng bộ cảm biến và cảm biến từ trường, giờ đây tôi tự hỏi làm thế nào để có được góc đúng cho la bàn của tôi.La bàn trong Android

Tôi đọc các giá trị của gia tốc kế và cảm biến từ trường trong "accele" và "magne" tương ứng. Để có được góc, tôi thực hiện như sau:

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 
          .... 

Sau đó, tôi sử dụng một ma trận xoay để đưa kim của tôi:

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

Bây giờ, tài liệu của getOrientation nói, định hướng đó [0] nên xoay vòng quanh trục z. Tài liệu cho TYPE_ORIENTATION quy định rằng "Phương vị, góc giữa hướng bắc từ và trục y, xung quanh trục z (0 đến 359). 0 = North, 90 = East, 180 = South, 270 = West".

Phương vị của tôi tuy nhiên không nằm trong khoảng từ 0 đến 359, nhưng đúng khoảng -2 đến 2. Độ phương vị chính xác từ getOrientation là gì và làm cách nào để chuyển đổi góc sang góc?

Trả lời

20

Sử dụng sau đây để chuyển đổi từ góc phương vị sẵn theo rađian (-PI , + PI) để độ (0, 360) tên

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

biến được sử dụng để thuận tiện ;-)

+0

thanks :) Chính xác thì câu lệnh if cuối cùng là gì? – user1809923

+0

Math.toDegrees() sẽ cho bạn góc từ -180 đến 180 từ góc radi -PI và + PI. Điều này chỉ đặt mọi thứ theo hướng tích cực. – rgrocha

+0

Đây là câu trả lời đúng. –

2

Tôi thấy điều này trong ApiDemos của google:

/* 
* 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(); 
     } 
    } 
} 

Như bạn có thể nhìn thấy bạn làm được những độ giữa 0-360

+0

sẽ tuyệt vời nếu bạn giải thích :) – user1809923

+0

Ok, tôi sẽ chỉnh sửa câu trả lời của mình. –

+0

hi, đó là một cách tiếp cận thú vị, tuy nhiên tôi nghĩ rằng điều này có thể không chính xác lắm, vì tôi chỉ ước tính -2 đến 2. – user1809923

7

Đoạn mã có thể nhận được từ https://github.com/iutinvg/compass

Không sử dụng nội dung không được chấp nhận, áp dụng bộ lọc thông thấp.

+0

các tiêu chí để quyết định 'alpha cuối cùng alpha = 0.97f;' Bạn đã sử dụng 0,97 làm hằng số bộ lọc, google đã sử dụng 0.8. – DeltaCap

+1

Nó sẽ ảnh hưởng đến vận tốc quay mũi tên. Vì vậy, sự lựa chọn được dựa trên cảm giác thị giác: chuyển động trơn tru hơn. – iutinvg

Các vấn đề liên quan