2014-05-14 3 views
0

이머 시브 카드에 game_rotation_vector sensor을 사용하고 싶습니다. 현재 버전의 Glass (XE17)에서는이 센서를 사용할 수 없습니다. 그래서 나는 같은 값을 얻을 수있는 방법을 알고 싶습니다.게임 회전 벡터 센서

실제로 나는 요, 피치 및 방위각 값을 얻고 싶습니다. 나는 현재 그것을하기 위해 rotation_vector 센서를 사용한다. 나는 현재의 학위를 나에게주는 현재의 가치와 시작과의 차이를 계산한다. 그러나 사용자가 흔들면 가로 값이 바뀌고 앱이 나쁜 정도를 계산합니다.

답변

2

글래스에서 오리엔테이션을 관리하기위한 도우미 클래스를 작성했습니다. 그 이유는 내가 여러 번 a Glass app showing real-time transit info의 일부로 계산했기 때문입니다. ,

package com.joulespersecond.oba.glass; 
/** 
* A utility class containing arithmetic and geometry helper methods. 
* 
* (from Glass Compass sample) 
*/ 
public class MathUtils { 

/** 
* Calculates {@code a mod b} in a way that respects negative values (for example, 
* {@code mod(-1, 5) == 4}, rather than {@code -1}). 
* 
* @param a the dividend 
* @param b the divisor 
* @return {@code a mod b} 
*/ 
public static float mod(float a, float b) { 
    return (a % b + b) % b; 
} 
} 

... 및 자북을 보정하는 데 사용되는 LocationHelperhere를 나타낸다 :

/* 
* Copyright (C) 2014 Sean J. Barbeau, University of South Florida 
* 
* 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.joulespersecond.oba.glass; 

import android.content.Context; 
import android.hardware.Sensor; 
import android.hardware.SensorEvent; 
import android.hardware.SensorEventListener; 
import android.hardware.SensorManager; 

import java.util.ArrayList; 

/** 
* Implements a sensor-based orientation helper for Glass, which allows listeners to receive 
* orientation updates 
*/ 
public class OrientationHelper implements SensorEventListener { 

    public interface Listener { 

    /** 
    * Called every time there is an update to the orientation 
    * 
    * @param deltaHeading change in heading from last heading value 
    * @param deltaPitch change in pitch from last pitch value 
    */ 
    void onOrientationChanged(float heading, float pitch, float deltaHeading, float deltaPitch); 
} 

static final String TAG = "OrientationHelper"; 

Context mContext; 

SensorManager mSensorManager; 

private float[] mRotationMatrix = new float[16]; 

private float[] mOrientation = new float[9]; 

private float[] history = new float[2]; 

private float mHeading; 

private float mPitch; 

ArrayList<Listener> mListeners = new ArrayList<Listener>(); 

public OrientationHelper(Context context) { 
    mContext = context; 
    mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE); 
} 

public synchronized void registerListener(Listener listener) { 
    if (!mListeners.contains(listener)) { 
     mListeners.add(listener); 
    } 

    // If this is the first listener, make sure we're monitoring the sensors to provide updates 
    if (mListeners.size() == 1) { 
     mSensorManager.registerListener(this, 
       mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR), 
       SensorManager.SENSOR_DELAY_UI); 
    } 
} 

public synchronized void unregisterListener(Listener listener) { 
    if (mListeners.contains(listener)) { 
     mListeners.remove(listener); 
    } 

    if (mListeners.size() == 0) { 
     mSensorManager.unregisterListener(this); 
    } 
} 

public synchronized void onResume() { 
    mSensorManager.registerListener(this, 
      mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR), 
      SensorManager.SENSOR_DELAY_UI); 
} 

public synchronized void onPause() { 
    mSensorManager.unregisterListener(this); 
} 

@Override 
public void onSensorChanged(SensorEvent event) { 
    if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) { 
     SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values); 
     SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_X, 
       SensorManager.AXIS_Z, mRotationMatrix); 
     SensorManager.getOrientation(mRotationMatrix, mOrientation); 

     mHeading = (float) Math.toDegrees(mOrientation[0]); 
     mPitch = (float) Math.toDegrees(mOrientation[1]); 

     float xDelta = history[0] - mHeading; // Currently unused 
     float yDelta = history[1] - mPitch; 

     history[0] = mHeading; 
     history[1] = mPitch; 

     // Use magnetic field to compute true (geographic) north, if data is available 
     // Note that if Glass doesn't have location info (e.g., it isn't paired and doesn't have a data connection), this should still work, you just can't correct for magnetic north 
     Float magneticDeclination = LocationHelper.getMagneticDeclination(); 
     if (magneticDeclination != null) { 
      mHeading += magneticDeclination; 
     } 

     // Make sure value is between 0-360 
     mHeading = MathUtils.mod(mHeading, 360.0f); 

     for (Listener l : mListeners) { 
      l.onOrientationChanged(mHeading, mPitch, xDelta, yDelta); 
     } 
    } 
} 

@Override 
public void onAccuracyChanged(Sensor sensor, int accuracy) { 
} 
} 

여기 MathUtil.java이다. 위치를 결정할 수없는 경우 (예 : Glass가 페어링되지 않았고 데이터 연결이 없음)이 작업은 계속 진행될 수 있습니다. 자기 북쪽을 수정할 수는 없습니다 (오류는 달라질 수 있습니다. 당신이 세계에있는 곳).

는 방위각이 (호) 때 방향에 따라 뭔가를 다시 그릴 것 View, 피치 변화, 예를 들어, 당신이 리스너 인터페이스를 구현하려는 방향 도우미를 사용하려면

public class MyView extends View implements OrientationHelper.Listener { 

    private float mHeading; 
    private float mPitch; 
    private float mXDelta; 
    private float mYDelta; 
    ... 

    @Override 
    public void onOrientationChanged(float heading, float pitch, float xDelta, float yDelta) { 
     mHeading = heading; 
     mPitch = pitch; 
     mXDelta = xDelta; 
     mYDelta = yDelta; 

     invalidate(); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) {   
     // Draw something based on orientation 
     ... 
    } 

} 

당신이 당신의 서비스 또는 활동에 뷰를 만들 때 리스너를 등록 .. 그리고 : 당신의 활동에 mOrientationHelper.onPause();

mOrientationHelper = new OrientationHelper(this); 
mOrientationHelper.registerListener(mMyView); 

그리고 당신의 활동 onResume()mOrientationHelper.onResume();를 호출센서를 시작/정지하려면을 누르십시오.

Google Glass GDK Compass sample은 Glass에서 방향을 사용하는 또 다른 좋은 예입니다.

이 모든 것은 일반적인 Android에서도 작동합니다. 여기에서 좌표 재 매핑은 Glass의 방향으로 고정됩니다. 오리엔테이션을 변경할 수있는 장치에서 이것을 사용하려면 오리엔테이션에 따라 좌표계를 다시 매핑해야합니다 (자세한 내용은 here 참조).

+0

내 생각에는 좋은 솔루션이지만 GPS가 장착되어 있지 않으므로 Google Glass 앱에서 사용할 수 없습니다 (해당 스마트 폰이있는 스마트 폰과 페어링되지 않았 음) – jan

+0

위에서 설명한 것처럼, LocationHelper는 위치를 사용할 수 없다면 LocationHelper가 null 값을 돌려 주어야한다고 믿습니다. (비록 당신이 세계 어느 곳에 있는지에 따라, 나침반이 자성 북쪽). 또한 Glass가 페어링되지 않은 경우에도 Wi-Fi를 통해 위치 제공 업체를 계속 지원해야한다고 생각합니다. –