簡體   English   中英

游戲旋轉矢量傳感器

[英]Game rotation vector sensor

我想在沉浸式卡片中使用game_rotation_vector傳感器 當前版本的Glass(XE17)不提供此傳感器。 所以我想知道如何獲得相同的值。

實際上我想獲得偏航,俯仰和方位角值。 我目前使用rotation_vector傳感器來做到這一點。 我計算了開始值和當前值之間的差值,它給出了當前的度數。 但是當用戶搖動水平值時,我的應用程序會計算出不好的程度。

我寫了一個幫助類來管理Glass的方向,因為我作為Glass應用程序的一部分計算它幾次, 顯示實時傳輸信息

/*
 * 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:

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;
}
}

... 此處顯示用於校正磁北的LocationHelper 如果無法確定位置(例如,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 = new OrientationHelper(this);
mOrientationHelper.registerListener(mMyView);

並調用mOrientationHelper.onResume(); 在你的Activity onResume()mOrientationHelper.onPause(); 在您的Activity onPause()中啟動/停止傳感器。

Google Glass GDK Compass示例是如何在Glass上使用方向的另一個很好的示例。

所有這些都適用於一般的Android,除了這里的坐標重新映射固定為Glass的方向。 要在可以更改方向的設備上使用此功能,您需要根據方向重新映射坐標系,這將在此處討論。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM