横向模式下的俯仰问题

发布于 2024-10-12 07:23:12 字数 1423 浏览 8 评论 0原文

我需要读取纵向和横向模式下的俯仰值(手机前后倾斜的程度)。使用肖像中的以下代码,当手机面朝上平放时,我从 value[1] 中获取值 0.0,直立时为 -90,平放在设备面上时为 180。到目前为止一切都很好... 当设备处于横向模式时就会出现问题。此时,我正在使用值 [2] 来测量设备倾斜度,但问题在于值:当手机平放时(正常)为 0,当手机直立时(正常)上升为 90,但是当我继续时运动值再次下降到 90 以下(80、75 等),所以基本上我无法区分这两个位置,因为值是相同的。 那么,我做错了什么,我可以从传感器读取哪些其他值,以便在横向和纵向模式下获得设备倾斜的全貌?

与此处相同的问题:http://groups.google。 com/group/android-beginners/browse_thread/thread/c691bbac3e294c7c?pli=1

我有以下代码:

private void ReadOrientationSensor(){
 final SensorManager sensorManager;

 final TextView text = (TextView) this.findViewById(R.id.TextView01);

sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);


SensorEventListener listener = new SensorEventListener() {

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

    @Override
    public void onSensorChanged(SensorEvent event) {
        float x,y,z;
        x=event.values[0];
        y=event.values[1];
        z=event.values[2];


        //text.setText(String.valueOf(event.values[0]));
        text.setText("x: " + x + " y: " + y + " z: " + z);


        }

    };

        sensorManager.registerListener(listener, sensor,SensorManager.SENSOR_DELAY_FASTEST);

}

I need to read the pitch value (how much the phone is tilted backwards and forwards) both in portrait and landscape modes. using the code bellow in portrait I get my value from value[1] with 0.0 when phone stay laying flat with face up, -90 when standing upright and 180 when lying flat on the device face. All great till now...
The problem comes when the device is in landscape mode. At this point I'm using value[2] to measure device tilt, but the problem is with the values : 0 when the phone stay laying flat (OK) rise to 90 when it is standing upright (OK), but when I continue the movement the value drop again below 90 (80, 75, etc...), so basically I can't differentiate between these 2 positions as the values are identical.
So, what I'm doing wrong, what other values from the sensors I can read in order to have a full picture of the device tilt both in landscape and portrait mode ?

Same questoion as here: http://groups.google.com/group/android-beginners/browse_thread/thread/c691bbac3e294c7c?pli=1

I Have the following code :

private void ReadOrientationSensor(){
 final SensorManager sensorManager;

 final TextView text = (TextView) this.findViewById(R.id.TextView01);

sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);


SensorEventListener listener = new SensorEventListener() {

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

    @Override
    public void onSensorChanged(SensorEvent event) {
        float x,y,z;
        x=event.values[0];
        y=event.values[1];
        z=event.values[2];


        //text.setText(String.valueOf(event.values[0]));
        text.setText("x: " + x + " y: " + y + " z: " + z);


        }

    };

        sensorManager.registerListener(listener, sensor,SensorManager.SENSOR_DELAY_FASTEST);

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

隐诗 2024-10-19 07:23:12

Sensor.TYPE_ORIENTATION 已弃用,不应使用。

阅读设备方向也让我有些头痛。下面是我用于需要设备方向的活动的基类:

public abstract class SensorActivity extends Activity implements SensorEventListener {

private SensorManager sensorManager;

private final float[] accelerometerValues = new float[3];

private final float[] R = new float[9];

private final float[] I = new float[9];

private final float[] orientation = new float[3];

private final float[] remappedR = new float[9];

private final List<HasOrientation> observers = new ArrayList<HasOrientation>();

private int x;

private int y;

protected SensorActivity() {
    this(SensorManager.AXIS_X, SensorManager.AXIS_Y);
}

/**
 * Initializes a new instance.
 * 
 */
protected SensorActivity(int x, int y) {
    setAxisMapping(x, y);
}

/**
 * The parameters specify how to map the axes of the device to the axes of
 * the sensor coordinate system.
 *  
 * The device coordinate system has its x-axis pointing from left to right along the
 * display, the y-axis is pointing up along the display and the z-axis is pointing
 * upward.
 * 
 * The <code>x</code> parameter defines the direction of the sensor coordinate system's
 * x-axis in device coordinates. The <code>y</code> parameter defines the direction of 
 * the sensor coordinate system's y-axis in device coordinates.
 * 
 * For example, if the device is laying on a flat table with the display pointing up,
 * specify <code>SensorManager.AXIS_X</code> as the <code>x</code> parameter and
 * <code>SensorManager.AXIS_Y</code> as the <code>y</code> parameter.
 * If the device is mounted in a car in landscape mode,
 * specify <code>SensorManager.AXIS_Z</code> as the <code>x</code> parameter and
 * <code>SensorManager.AXIS_MINUS_X</code> as the <code>y</code> parameter.
 * 
 * @param x specifies how to map the x-axis of the device.
 * @param y specifies how to map the y-axis of the device.
 */
public void setAxisMapping(int x, int y) {
    this.x = x;
    this.y = y;     
}

/**
 * Registers an orientation observer.
 * 
 * @param hasOrientation is the observer to register.
 */
protected void register(HasOrientation hasOrientation) {
    observers.add(hasOrientation);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);        
}

@Override
protected void onResume() {
    super.onResume();

    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI);
    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);             
}

@Override
protected void onPause() {
    sensorManager.unregisterListener(this);

    super.onPause();
}

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

public void onSensorChanged(SensorEvent event) {        
    switch(event.sensor.getType())
    {
    case Sensor.TYPE_ACCELEROMETER:
        System.arraycopy(event.values, 0, accelerometerValues, 0, accelerometerValues.length);
        break;

    case Sensor.TYPE_MAGNETIC_FIELD:            
        if (SensorManager.getRotationMatrix(R, I, accelerometerValues, event.values)) {                             
            if (SensorManager.remapCoordinateSystem(R, x, y, remappedR)) {
                SensorManager.getOrientation(remappedR, orientation);

                for (HasOrientation observer : observers) {
                    observer.onOrientation(Orientation.fromRadians(orientation));
                }
            }
        }
        break;

    default:
        throw new IllegalArgumentException("unknown sensor type");
    }       
}   
}

方向如下:

/**
 * An angular direction vector.
 * 
 * The vector consists of three angles {azimuth, pitch, roll}. Within a body-fixed
 * cartesian system, the values of these angles define rotations of the three body axes.
 * 
 * All angles are in degrees.
 * 
 * @author [email protected]
 *
 */
public class Orientation {

/**
 * Represents the angle to rotate the up axis. 
 */
public float azimuth;

/**
 * Represents the angle to rotate the axis pointing right.
 */
public float pitch;

/**
 * Represents the angle to rotate the forward axis. 
 */
public float roll;

/**
 * Initializes an instance that is empty.
 */
public Orientation() {  
}

/**
 * Initializes an instance from the specified rotation values in degrees.
 *  
 * @param azimuth is the azimuth angle.
 * @param pitch is the pitch angle.
 * @param roll is the roll angle.
 */
public Orientation(float azimuth, float pitch, float roll) {
    this.azimuth = azimuth;
    this.pitch = pitch;
    this.roll = roll;
}

/**
 * Sets the current values to match the specified orientation.
 * 
 * @param o is the orientation to copy.
 */
public void setTo(Orientation o) {
    this.azimuth = o.azimuth;
    this.pitch = o.pitch;
    this.roll = o.roll;     
}

/**
 * Normalizes the current instance.
 * 
 * Limits the azimuth to [0...360] and pitch and roll to [-180...180]. 
 */
public void normalize() {
    azimuth = Angle.normalize(azimuth);
    pitch = Angle.tilt(pitch);
    roll = Angle.tilt(roll);
}

/**
 * Creates a new vector from an array of radian values in the form
 * [azimuth, pitch, roll].
 * 
 * This method is useful to fill sensor data into a vector.
 * 
 * @param vec is the array of radians.
 * @return the vector.
 */
public static Orientation fromRadians(float[] vec) {
    return new Orientation((float)Math.toDegrees(vec[0]), (float)Math.toDegrees(vec[1]), 
            (float)Math.toDegrees(vec[2]));
}

@Override
public String toString() {
    return "{a=" + azimuth + ", p=" + pitch + ", r=" + roll + "}";
}
}

您需要调用 setAxisMapping() 来接收与纵向或横向模式对齐的方向。我只从构造函数中调用它,因此我无法告诉您在活动运行时调用它时会发生什么。您可能必须重置矩阵。

Sensor.TYPE_ORIENTATION is deprecated and should not be used.

Reading the device orientation gave me some headache as well. Here is a base class that I am using for activities that need the device's orientation:

public abstract class SensorActivity extends Activity implements SensorEventListener {

private SensorManager sensorManager;

private final float[] accelerometerValues = new float[3];

private final float[] R = new float[9];

private final float[] I = new float[9];

private final float[] orientation = new float[3];

private final float[] remappedR = new float[9];

private final List<HasOrientation> observers = new ArrayList<HasOrientation>();

private int x;

private int y;

protected SensorActivity() {
    this(SensorManager.AXIS_X, SensorManager.AXIS_Y);
}

/**
 * Initializes a new instance.
 * 
 */
protected SensorActivity(int x, int y) {
    setAxisMapping(x, y);
}

/**
 * The parameters specify how to map the axes of the device to the axes of
 * the sensor coordinate system.
 *  
 * The device coordinate system has its x-axis pointing from left to right along the
 * display, the y-axis is pointing up along the display and the z-axis is pointing
 * upward.
 * 
 * The <code>x</code> parameter defines the direction of the sensor coordinate system's
 * x-axis in device coordinates. The <code>y</code> parameter defines the direction of 
 * the sensor coordinate system's y-axis in device coordinates.
 * 
 * For example, if the device is laying on a flat table with the display pointing up,
 * specify <code>SensorManager.AXIS_X</code> as the <code>x</code> parameter and
 * <code>SensorManager.AXIS_Y</code> as the <code>y</code> parameter.
 * If the device is mounted in a car in landscape mode,
 * specify <code>SensorManager.AXIS_Z</code> as the <code>x</code> parameter and
 * <code>SensorManager.AXIS_MINUS_X</code> as the <code>y</code> parameter.
 * 
 * @param x specifies how to map the x-axis of the device.
 * @param y specifies how to map the y-axis of the device.
 */
public void setAxisMapping(int x, int y) {
    this.x = x;
    this.y = y;     
}

/**
 * Registers an orientation observer.
 * 
 * @param hasOrientation is the observer to register.
 */
protected void register(HasOrientation hasOrientation) {
    observers.add(hasOrientation);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);        
}

@Override
protected void onResume() {
    super.onResume();

    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI);
    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);             
}

@Override
protected void onPause() {
    sensorManager.unregisterListener(this);

    super.onPause();
}

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

public void onSensorChanged(SensorEvent event) {        
    switch(event.sensor.getType())
    {
    case Sensor.TYPE_ACCELEROMETER:
        System.arraycopy(event.values, 0, accelerometerValues, 0, accelerometerValues.length);
        break;

    case Sensor.TYPE_MAGNETIC_FIELD:            
        if (SensorManager.getRotationMatrix(R, I, accelerometerValues, event.values)) {                             
            if (SensorManager.remapCoordinateSystem(R, x, y, remappedR)) {
                SensorManager.getOrientation(remappedR, orientation);

                for (HasOrientation observer : observers) {
                    observer.onOrientation(Orientation.fromRadians(orientation));
                }
            }
        }
        break;

    default:
        throw new IllegalArgumentException("unknown sensor type");
    }       
}   
}

Orientation goes like this:

/**
 * An angular direction vector.
 * 
 * The vector consists of three angles {azimuth, pitch, roll}. Within a body-fixed
 * cartesian system, the values of these angles define rotations of the three body axes.
 * 
 * All angles are in degrees.
 * 
 * @author [email protected]
 *
 */
public class Orientation {

/**
 * Represents the angle to rotate the up axis. 
 */
public float azimuth;

/**
 * Represents the angle to rotate the axis pointing right.
 */
public float pitch;

/**
 * Represents the angle to rotate the forward axis. 
 */
public float roll;

/**
 * Initializes an instance that is empty.
 */
public Orientation() {  
}

/**
 * Initializes an instance from the specified rotation values in degrees.
 *  
 * @param azimuth is the azimuth angle.
 * @param pitch is the pitch angle.
 * @param roll is the roll angle.
 */
public Orientation(float azimuth, float pitch, float roll) {
    this.azimuth = azimuth;
    this.pitch = pitch;
    this.roll = roll;
}

/**
 * Sets the current values to match the specified orientation.
 * 
 * @param o is the orientation to copy.
 */
public void setTo(Orientation o) {
    this.azimuth = o.azimuth;
    this.pitch = o.pitch;
    this.roll = o.roll;     
}

/**
 * Normalizes the current instance.
 * 
 * Limits the azimuth to [0...360] and pitch and roll to [-180...180]. 
 */
public void normalize() {
    azimuth = Angle.normalize(azimuth);
    pitch = Angle.tilt(pitch);
    roll = Angle.tilt(roll);
}

/**
 * Creates a new vector from an array of radian values in the form
 * [azimuth, pitch, roll].
 * 
 * This method is useful to fill sensor data into a vector.
 * 
 * @param vec is the array of radians.
 * @return the vector.
 */
public static Orientation fromRadians(float[] vec) {
    return new Orientation((float)Math.toDegrees(vec[0]), (float)Math.toDegrees(vec[1]), 
            (float)Math.toDegrees(vec[2]));
}

@Override
public String toString() {
    return "{a=" + azimuth + ", p=" + pitch + ", r=" + roll + "}";
}
}

You need to call setAxisMapping() to receive the orientation aligned to either portrait or landscape mode. I only called it from within the constructor so I cannot tell you what happens when you call it while the activity is running. You might have to reset the matrixes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文