The source code of all examples is included in the JDroidLib distribution. Using Android's Built-In Sensors
|
package ch.aplu.sensor.list; |
Keep in mind that even if a sensor is part of the installed sensors there is no guarantee that sensor data can be retrieved by an Android app.
Download SensorList app for installation on a smartphone Create QR code to download Android app to your smartphone. Download sources (SensorList.zip). |
2 World and Device Coordinate Systems
To describe the current orientation, we first define a cartesian laboratory coordinate system, also called world coordinate system, because its coordinate axes (x', y', z') are defined with respect to the earth. Imagine a tangential surface at the current location. The z'-axes points to the zenith, the y'-axis to north (tangent to the longitude circle) and the x'-axes to east (tangent to the lattitude circle). Now we fix a second cartesian coordinate system, called the device coordinate system, with the smartphone/tablet. Its origin is used to describe the current location (we put it in the center of the screen). The device coordinate axes (x, y, z) are defined as follows: z is normal to the screen (positive in upward direction), the x- and y-axes lay in the screen surface, where y is parallel to the larger screen side (positive to the front) and x is parallel to the smaller screen side (positive to the right). This situation is shown in the following figure. In the following we only consider the rotational orientation, so the translation of the origins are of no importance.
Device (x, y, z) and World (x',y',z') coordinate system |
For tablets the y-axes is parallel to the smaller side and the x-axes parallel to the larger side. As the name suggests the device coordinate system is fixed with the device and independent of the current orientation of the application. To take into account the current application orientation (portrait, landscape, reverse portrait, reverse landscape) x and y coordinates must be exchanged as appropriate.
The world coordinate system is obviously a three-dimensional rotated device coordinate system and it is well-known from mathematics (see en.wikipedia.org/wiki/Rotation_matrix) that the coordinates (dx, dy, dz) of some arbitrary point P is transformed to the world coordinates (wx, wy, wz) by a matrix multiplication
Transformation from device to world coordinates |
The rotation matrix R has a special property: The inverse matrix is equal to the transpose matrix (R is an orthogonal matrix). So it is easy to reverse the transformation from world to device coordinates.
Now the hardware sensors come into play. If we place two sensors in the mobile phone, an acceleration sensor that measures the current vector of the gravitation acceleration g (vertical) and a magnetic field sensor that measures the current direction of the earth magnetic field B (to north with some inclination), the rotation matrix can be calculated from the measured data. Android's SensorManager class provides the static method getRotationMatrix() that takes the current acceleration and magnetic field vectors and returns the rotation (and inclination) matrix.
The current device rotation is characterized by three angles (also called Euler angles). In the context of mobile devices the three angles are called azimuth (alpha), pitch (phi) and roll (rho) and are defined as seen in the figure above. They can be calculated from the measured gravitational and magnetic field as follows:
Azimuth |
Pitch |
Roll |
These formulas are implemented in the class GGSensor as getAzimuthCalc(), getPitchCalc() and getRollCalc(). Azimuth, pitch and roll may also be retrieved from the rotation matrix with SensorManager.getOrientation().
Azimuth, pitch and roll correspond to the angles used for airplane/rocket orientation.
Sensor values are normally retrieved by applying the event model: The sensor is polled internally using a polling time interval determined by the system that can be modified by a constructor parameter. Whenever the new value is different from the previous one, an event is triggered that invokes the callback method sensorChanged(float[] values, int sensorType) where the new value can be retrieved from the values[] parameter.
In the following example we measure the gravitational acceleration and the magnetic field retrieved from the callback method and determine the rotation matrix. Then we calculate the orientation vector. The main thread displays azimuth, roll and pitch in a application independent coordinate system and also adapted to the current application window orientation.
package ch.aplu.sensor.event; |
We force the display to remain visible by calling setWakeLockEnabled(true). Start the program with different screen orientations to understand the adapted values.
Download SensorEvent app for installation on a smartphone Create QR code to download Android app to your smartphone. Download sources (SensorEvent.zip). |
Some smartphones/tablets contains a so called combo sensor that returns acceleration, magnetic field and orientation (azimuth, pitch, roll). The combo sensor is supported by an older (now deprecated) Android API, but may deliver more accurate values for older devices. The class GGComboSensor is based on this API, so consider to use it, if compatibility with older devices is important. The next example shows how to proceed.
package ch.aplu.sensor.orientation; |
You may compare the values of the two programs on different devices.
Download SensorOrientation app for installation on a smartphone
Create QR code to download Android app to your smartphone.
Download sources (SensorOrientation.zip).
Instead of displaying the values on the mobile device we may transmit them via Bluetooth or Internet to a monitoring station running Java SE. The Android app is running as a Bluetooth server waiting for a client to connect. After connection a data collecting thread measures periodically data from the sensor and transmits time/value pairs via Bluetooth to the client where they are displayed (or processed otherwise). The graphics window is created in no time using the GPanel class from the ch.aplu.util package.
(The sources are part of the JDroidLib distribution.)
RemoteSensor App |
RemoteSensorClient (SE) Execute RemoteSensorClient (for Java SE) locally using WebStart. |
Download RemoteSensor app for installation on a smartphone Create QR code to download Android app to your smartphone. Download sources (RemoteSensor.zip). |