Let’s assume I have the phone’s rotation vector from the rotation sensor event.
I’d like to compute the geographic direction the back camera is looking at when holding the phone upright (portrait or landscape).
Related
Some camera apps have a feature where they display a line on the screen which is always parallell to the horizon, no matter how the phone is tilted sideways. By "tilted sideways" I mean rotating the device around an axis that is perpendicular to the screen.
I have tried most of the "normal" rotation functions such as combining the ROTATION_VECTOR sensor with getRotationMatrix() and getOrientation() but none of the resulting axis seem to correspond to the one I'm looking for.
I also tried using only the accelerometer, normalizing all three axis and detecting how much gravity is in the X-axis. This works decently when the device is perfectly upright (i.e not tilted forward/backwards). But as soon as it's tilted forward or backward the measured sideways tilt gets increasingly inaccurate, since gravity is now acting on two axis at the same time.
Any ideas on how to achieve this kind of sideways rotation detection in a way that works even if the phone is tilted/pitched slightly forward/backward?
The result of getRotationMatrix converts from the phone's local coordinate system to the world coordinate system. Its columns are therefore the principal axes of the phone, with the first being the phone's X-axis (the +ve horizontal axis when holding the phone in portrait mode), and the second being the Y.
To obtain the horizon's direction on the phone's screen, the line of intersection between the horizontal plane (world space) and the phone's plane must be found. First find the coordinates of the world Z-axis (pointing to the sky) in the phone's local basis - i.e. transpose(R) * [0, 0, 1]; the XY coordinates of this, given by R[2][0], R[2][1], is the vertical direction in screen-space. The required horizon line direction is then R[2][1], -R[2][0].
When the phone is close to being horizontal, this vector becomes very small in magnitude - the horizon is no-longer well-defined. Simply stop updating the horizon line below some threshold.
I am able to get the orientation of my Android phone using TYPE_ROTATION_VECTOR and am able to get the angles in degrees of the 3 rotation angles. However, how do I set it so the starting orientation of the phone are all 0's? This way, regardless of starting orientation, all the measured orientations will be relative to the starting orientation -- not fixed to magnetic north, and the ground.
I found this page:
http://www.outware.com.au/insights/which-direction-am-i-facing-using-the-sensors-on-your-android-phone-to-record-where-you-are-facing/
and it got this working. Use TYPE_VECTOR_ROTATION with a math class from org.apache. Save you starting sensor reading, it will be a 4-element array of quaternions. Then for future readings, apply the starting reading and then get android's rotation matrix.
I want take photo and try to do it on the inclination of 180 degrees +/- 5 degrees, in other degrees camera should be blocked.
In brief I want force take photo horizontally to floor (or close to it).
What is the easiest way? I should use gyroscope? The problem is that angle must be checked all the time that degree is good.
Use orientation sensor. Framework reports to you when value of sensor is changed, so as long as you keep sensor registered for usage, you will have actual device orientation.
Retrieve SensorManager by calling context.getSystemService(Context.SENSOR_SERVICE). Also look at Android Orientation sensor for rotation the 3D cube
i have come across this code which uses the phones sensors to get the orientation of the device in degrees along the 3 axes... this value is calculated from a 4x4 matrix called rotation matrix.. so i was wondering what kind of data is stored in the rotation matrix ?
the code is similar to the one in this example
Android: Problems calculating the Orientation of the Device
The Wikipedia article about rotation matrices is reasonable. Basically, the rotation matrix tells you how to map a point in one co-ordinate system to a point in a different co-ordinate system. In the context of Android sensors, the rotation matrix is telling you how to map a point from the co-ordinate system of the phone (where the phone itself lies in the x-y plane) to the real world North/East/"Gravity-direction" co-ordinate system.
Android uses either 3x3 or 4x4 rotation matrices. When 4x4, it's the Quaternion representation of a rotation. For the 3x3 case, in terms of the Euler Angles aximuth, pitch and roll, see my answer to 'Compute rotation matrix using the magnetic field' for how those angles are embedded in the rotation matrix (NB: the accepted answer to that question is wrong).
Android provides sensor data in device coordinate system no matter how it is oriented. Is there any way to have sensor data in 'gravity' coordinate system? I mean no matter how the device is oriented I want accelerometer data and orientation in coordinate system where y-axis points toward the sky, x-axis toward the east and z-axis towards south pole.
I took a look at remapCoordinateSystem but seems to be limited to only swapping axis. I guess for orientation I will have to do some low level rotation matrix transformation (or is there any better solution?). But how about acceleration data? Is there any way to have data in relation to coordinate system that is fixed (sort of world coordinate system).
The reason I need this is I'm trying to do some simple motion gestures when phone is in the pocket and it would be easier for me to have all data in coordinates system related to user rather device coordinate system (that will have a little bit different orientation in different user's pockets)
Well you basically get the North orientation when starting - for this you use the accelerometer and the magnetic field sensor to compute orientation (or the deprecated Orientation sensor).
Once you have it you can compute a rotation matrix (Direction Cosine Matrix) from those azimuth, pitch and roll angles. Multiplying your acceleration vector by that matrix will transform your device-frame movements into Earth-frame ones.
As your device will change its orientation as time goes by, you'll need to update it. To do so, retrieve gyroscope's data and update your Direction Cosine Matrix for each new value. You could also get the orientation true value just like the first time, but it's less accurate.
My solution involves DCM, but you could also use quaternions, it's just a matter of choice. Feel free to ask more if needed. I hope this is what you wanted to know !