Step problems in landscape mode

I need to read the value of the fundamental tone (how much the phone is tilted back and forth) in both portrait and landscape modes. using the code below in the portrait, I get my value from the value [1] from 0,0 when the phone remains flat with the face up, -90 when standing upright and 180 when it lies on the front of the device. Everything is fine so far ... The problem occurs when the device is in landscape mode. At the moment, I use the value [2] to measure the tilt of the device, but the problem is with the values: 0, when the phone stays flat (OK), rises to 90, when it stands upright (OK), but when I continue to move it falls again below 90 (80, 75, etc.), so I can not distinguish between these two positions, since the values ​​are identical. So, what am I doing wrong, what other values ​​from the sensors can I read to have a complete picture of the tilt device in both landscape and portrait modes?

Same search 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); 

}

+4
source share
1 answer

Sensor.TYPE_ORIENTATION deprecated and should not be used.

Reading the orientation of the device also caused me a headache. Here is the base class that I use for actions that require device 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 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"); } } } 

The orientation looks something 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 michael@mictale.com * */ 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 get the orientation oriented in portrait or landscape mode. I just called it from the constructor, so I can’t tell you what happens when you call it while it is running. You may need to reset the matrix.

+4
source

Source: https://habr.com/ru/post/1335865/


All Articles