Sensor Data for Motion Sensor
The Motion Sensor API processes the data from the Magic Remote and provides several outputs to the host system.
Reference frame
The webOS TV Motion Sensor API processes motions relative to a frame of reference. The device’s frame of reference is represented as X axis, horizontal and positive to the right, Y axis, vertical and positive along the length from the top point of the Magic Remote, and Z axis, positive outwards from the front face of the Magic Remote.
The frame of reference is shown in the following image.
Cursor outputs
The Motion Sensor API takes the calibrated angular velocity and orientation of the Magic Remote as input and maps the angular velocity to the frame that the user perceives as the X and Y axes of the projected screen.
These define the absolute positions of pixel values, x (horizontal) and y (vertical), on the screen.
int x
int y
Motion Outputs
Acceleration
The three-axis accelerometer measures the acceleration of the Magic Remote. Note that the accelerometer measures gravity as acceleration. The Motion Sensor API calibrates the accelerometer data to improve the motion output and will report this acceleration aligned to the coordinate frame of the Magic Remote.
After fusing data with the gyroscope, the Motion Sensor API separates gravity from the acceleration and provides the following acceleration outputs:
//Acceleration of the Magic Remote including gravity (m/s2).
double accelerometer.x,y,z
//Uncalibrated acceleration of the Magic Remote including gravity (m/s2) and the estimated accelerometer bias(m/s2).
double accelerometer.x_uncalibrated, y_uncalibrated, z_uncalibrated, x_bias, y_bias, z_bias
//Gravity portion from the acceleration(m/s2), requires sensor fusion with the gyroscope.
double gravity.x, y, z
//Acceleration of the Magic Remote after the gravity is removed (m/s2).
double linearAcceleration.x, y, z
Angular Velocity
The three-axis gyroscope measures the angular velocity of the Magic Remote. The angular velocity is reported as rotations around the X, Y, and Z axes as shown in the Figure in Reference Frame.
A positive value is reported for counter-clockwise rotations. The Motion Sensor API calibrates the gyroscope data to improve the accuracy and provides the following outputs:
// Angular velocity of the Magic Remote(rad/s).
double gyroscope.x,y,z
// Uncalibrated angular velocity of the Magic Remote (rad/s) and the estimated gyroscope bias(rad/s).
double gyroscopeUncalibrated.x_uncalibrated, y_uncalibrated, z_uncalibrated, x_bias, y_bias, z_bias
Orientation
Fusing data from the accelerometer and gyroscope, the Motion Sensor API provides an estimated orientation of the Magic Remote.
double gameRotationVector.x,y,z,w
The game rotation vector is an orientation output expressed as a quaternion with no specific reference for heading, while the roll and pitch are referenced against gravity. The game rotation vector is used when there is no magnetometer to correct the gyroscope drift in yaw. This is a deliberate omission as specified by Android, aiming at allowing gaming apps to use a smoother representation of the orientation without jumps caused by an instantaneous correction due to magnetic field updates.
In the long term, the output is likely to drift in yaw due to the characteristics of a gyroscope, but this is seen as preferable for this output versus a corrected output using the magnetometer.
Fusing data from the accelerometer and gyroscope, the Motion Sensor API provides an estimated orientation of the Magic Remote.
double gameRotationVector.euler.pitch, roll, yaw
Quaternions can also be provided after conversion into Euler angles. For expression of a rotation, it is easy to do it through the Euler angle, but because the conversion is not easy, it is provided separately.
Classification
Significant Motion Detector
int significantMotion
An event should be raised when a user has taken a motion implying a changed location. A typical use-case is that the sensor power is low (as it can run while the device is asleep) and it alerts the main processing element of the Magic Remote when a change in location is expected.
The Motion Sensor API uses the step detector and its processing based on the accelerometer to determine if the user has taken a significant motion. The detector outputs a value of 1.0 when a motion is detected and reset itself immediately after the event is output. For example, during walking, the detector event will be reported roughly in every five steps.
Configuration of the significant motion detector includes:
- Significant motion step threshold: The number of steps required to trigger the event. The default value is 5 steps.
- Acceleration threshold: A threshold loosely based on the device’s acceleration to trigger significant motion processing. Default value is 10m/s2
Step Detector
int stepDetected
The step detector uses data from the accelerometer to detect steps. It will output a value of 1.0 whenever a step is detected. Configuration of the step detector includes:
allowTime
: Maximum variation of the step period, 180msstepMinTime
: Minimum step period, 300msgroupDelay
: Group delay of the filter. Filtering of accelerometer data is required to ensure accurate detection of steps, particularly if the accelerometer is rotating against gravity. The group delay of the filter is a compromise between responsiveness and error accumulation. A value of 90ms is used.threshold
: Vertical motion threshold in meters. If a vertical motion is smaller than this threshold, it will not be recognized as a step. The value is 3.1mm
Step Counter
int stepCount
It counts the number of steps after the system starts up. The step counter uses the step detector to detect and count steps. It provides more accurate data about steps taken than the step detector. By evaluating the data around each step event, it increases the counting accuracy, and it further possibly reclassifies previous samples as either steps or non-steps, depending upon the patterns perceived.
Step Counter
int stepDetectedLatency
//The number of samples in the past where the peak of the step was detected.
//Valid when stepDetected=1
Normally this information would be provided by a sensor event timestamp, but since no timestamps are provided by the interface,
this value can be used to adjust app timestamps for stepDetected
and stepCount
events if desired.
The webOS TV Magic Remote API (Motion Sensor API) provides a basic operation agenda for the above outputs.
The following table shows the list of sensor types and their event data supported on webOS TV.
Sensor | Sensor event data | Description | Unit of measure |
---|---|---|---|
TYPE_COORDINATE | getSensorEventData().coordinate.x | The x-coordinate of the cursor on the screen when using the remote control | N/A |
TYPE_COORDINATE | getSensorEventData().coordinate.y | The y-coordinate of the cursor on the screen when using the remote control | N/A |
TYPE_ACCELEROMETER | getSensorEventData().accelerometer.x | Acceleration force along the X axis (including gravity) | m/s2 |
TYPE_ACCELEROMETER | getSensorEventData().accelerometer.y | Acceleration force along the Y axis (including gravity) | m/s2 |
TYPE_ACCELEROMETER | getSensorEventData().accelerometer.z | Acceleration force along the Z axis (including gravity) | m/s2 |
TYPE_ACCELEROMETER_UNCALIBRATED | getSensorEventData().accelerometerUncalibrated.x_uncalib | Measured acceleration along the X axis without any bias compensation | m/s2 |
TYPE_ACCELEROMETER_UNCALIBRATED | getSensorEventData().accelerometerUncalibrated.y_uncalib | Measured acceleration along the Y axis without any bias compensation | m/s2 |
TYPE_ACCELEROMETER_UNCALIBRATED | getSensorEventData().accelerometerUncalibrated.z_uncalib | Measured acceleration along the Z axis without any bias compensation | m/s2 |
TYPE_ACCELEROMETER_UNCALIBRATED | getSensorEventData().accelerometerUncalibrated.x_bias | Measured acceleration along the X axis with the estimated bias compensation | m/s2 |
TYPE_ACCELEROMETER_UNCALIBRATED | getSensorEventData().accelerometerUncalibrated.y_bias | Measured acceleration along the Y axis with the estimated bias compensation | m/s2 |
TYPE_ACCELEROMETER_UNCALIBRATED | getSensorEventData().accelerometerUncalibrated.z_bias | Measured acceleration along the Z axis with the estimated bias compensation | m/s2 |
TYPE_GRAVITY | getSensorEventData().gravity.x | Force of gravity along the X axis | m/s2 |
TYPE_GRAVITY | getSensorEventData().gravity.y | Force of gravity along the Y axis | m/s2 |
TYPE_GRAVITY | getSensorEventData().gravity.z | Force of gravity along the Z axis | m/s2 |
TYPE_GYROSCOPE | getSensorEventData().gyroscope.x | Rate of rotation around the X axis | rad/s |
TYPE_GYROSCOPE | getSensorEventData().gyroscope.y | Rate of rotation around the Y axis | rad/s |
TYPE_GYROSCOPE | getSensorEventData().gyroscope.z | Rate of rotation around the Z axis | rad/s |
TYPE_GYROSCOPE_UNCALIBRATED | getSensorEventData().gyroscopeUncalibrated.x_uncalib | Rate of rotation (without drift compensation) around the X axis | rad/s |
TYPE_GYROSCOPE_UNCALIBRATED | getSensorEventData().gyroscopeUncalibrated.y_uncalib | Rate of rotation (without drift compensation) around the Y axis | rad/s |
TYPE_GYROSCOPE_UNCALIBRATED | getSensorEventData().gyroscopeUncalibrated.z_uncalib | Rate of rotation (without drift compensation) around the Z axis | rad/s |
TYPE_GYROSCOPE_UNCALIBRATED | getSensorEventData().gyroscopeUncalibrated.x_bias | Estimated drift around the X axis | rad/s |
TYPE_GYROSCOPE_UNCALIBRATED | getSensorEventData().gyroscopeUncalibrated.y_bias | Estimated drift around the Y axis | rad/s |
TYPE_GYROSCOPE_UNCALIBRATED | getSensorEventData().gyroscopeUncalibrated.z_bias | Estimated drift around the Z axis | rad/s |
TYPE_LINEAR_ACCELERATION | getSensorEventData().linearAcceleration.x | Acceleration force along the X axis (excluding gravity) | m/s2 |
TYPE_LINEAR_ACCELERATION | getSensorEventData().linearAcceleration.y | Acceleration force along the Y axis (excluding gravity) | m/s2 |
TYPE_LINEAR_ACCELERATION | getSensorEventData().linearAcceleration.z | Acceleration force along the Z axis (excluding gravity) | m/s2 |
TYPE_GAME_ROTATION_VECTOR | getSensorEventData().gameRotationVector.x | Rotation vector component along the X axis (x * sin(θ/2)) | Unitless |
TYPE_GAME_ROTATION_VECTOR | getSensorEventData().gameRotationVector.y | Rotation vector component along the Y axis (y * sin(θ/2)) | Unitless |
TYPE_GAME_ROTATION_VECTOR | getSensorEventData().gameRotationVector.z | Rotation vector component along the Z axis (z * sin(θ/2)) | Unitless |
TYPE_GAME_ROTATION_VECTOR | getSensorEventData().gameRotationVector.w | Scalar component of the rotation vector ((cos(θ/2)) | Unitless |
TYPE_GAME_ROTATION_VECTOR | getSensorEventData().gameRotationVector.euler.pitch | Euler Angle (pitch) by transferring Rotation Vector | Angle |
TYPE_GAME_ROTATION_VECTOR | getSensorEventData().gameRotationVector.euler.roll | Euler Angle (roll) by transferring Rotation Vector | Angle |
TYPE_GAME_ROTATION_VECTOR | getSensorEventData().gameRotationVector.euler.yaw | Euler Angle (yaw) by transferring Rotation Vector | Angle |
TYPE_SIGNIFICANT_MOTION | getSensorEventData().motionDetecter.significantMotion | N/A | N/A |
TYPE_STEP_COUNTER | getSensorEventData().pedometer.stepCount | Number of steps taken by the user since the last reboot while the sensor was activated | Steps |
TYPE_STEP_DETECTOR | getSensorEventData().pedometer.stepDetect | N/A | N/A |