繁体   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