Home | History | Annotate | Download | only in hardware
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.hardware;
     18 
     19 /**
     20  * This class represents a {@link android.hardware.Sensor Sensor} event and
     21  * holds informations such as the sensor's type, the time-stamp, accuracy and of
     22  * course the sensor's {@link SensorEvent#values data}.
     23  *
     24  * <p>
     25  * <u>Definition of the coordinate system used by the SensorEvent API.</u>
     26  * </p>
     27  *
     28  * <p>
     29  * The coordinate-system is defined relative to the screen of the phone in its
     30  * default orientation. The axes are not swapped when the device's screen
     31  * orientation changes.
     32  * </p>
     33  *
     34  * <p>
     35  * The X axis is horizontal and points to the right, the Y axis is vertical and
     36  * points up and the Z axis points towards the outside of the front face of the
     37  * screen. In this system, coordinates behind the screen have negative Z values.
     38  * </p>
     39  *
     40  * <p>
     41  * <center><img src="../../../images/axis_device.png"
     42  * alt="Sensors coordinate-system diagram." border="0" /></center>
     43  * </p>
     44  *
     45  * <p>
     46  * <b>Note:</b> This coordinate system is different from the one used in the
     47  * Android 2D APIs where the origin is in the top-left corner.
     48  * </p>
     49  *
     50  * @see SensorManager
     51  * @see SensorEvent
     52  * @see Sensor
     53  *
     54  */
     55 
     56 public class SensorEvent {
     57     /**
     58      * <p>
     59      * The length and contents of the {@link #values values} array depends on
     60      * which {@link android.hardware.Sensor sensor} type is being monitored (see
     61      * also {@link SensorEvent} for a definition of the coordinate system used).
     62      * </p>
     63      *
     64      * <h4>{@link android.hardware.Sensor#TYPE_ACCELEROMETER
     65      * Sensor.TYPE_ACCELEROMETER}:</h4> All values are in SI units (m/s^2)
     66      *
     67      * <ul>
     68      * <li> values[0]: Acceleration minus Gx on the x-axis </li>
     69      * <li> values[1]: Acceleration minus Gy on the y-axis </li>
     70      * <li> values[2]: Acceleration minus Gz on the z-axis </li>
     71      * </ul>
     72      *
     73      * <p>
     74      * A sensor of this type measures the acceleration applied to the device
     75      * (<b>Ad</b>). Conceptually, it does so by measuring forces applied to the
     76      * sensor itself (<b>Fs</b>) using the relation:
     77      * </p>
     78      *
     79      * <b><center>Ad = - &#8721;Fs / mass</center></b>
     80      *
     81      * <p>
     82      * In particular, the force of gravity is always influencing the measured
     83      * acceleration:
     84      * </p>
     85      *
     86      * <b><center>Ad = -g - &#8721;F / mass</center></b>
     87      *
     88      * <p>
     89      * For this reason, when the device is sitting on a table (and obviously not
     90      * accelerating), the accelerometer reads a magnitude of <b>g</b> = 9.81
     91      * m/s^2
     92      * </p>
     93      *
     94      * <p>
     95      * Similarly, when the device is in free-fall and therefore dangerously
     96      * accelerating towards to ground at 9.81 m/s^2, its accelerometer reads a
     97      * magnitude of 0 m/s^2.
     98      * </p>
     99      *
    100      * <p>
    101      * It should be apparent that in order to measure the real acceleration of
    102      * the device, the contribution of the force of gravity must be eliminated.
    103      * This can be achieved by applying a <i>high-pass</i> filter. Conversely, a
    104      * <i>low-pass</i> filter can be used to isolate the force of gravity.
    105      * </p>
    106      *
    107      * <pre class="prettyprint">
    108      *
    109      *     public void onSensorChanged(SensorEvent event)
    110      *     {
    111      *          // alpha is calculated as t / (t + dT)
    112      *          // with t, the low-pass filter's time-constant
    113      *          // and dT, the event delivery rate
    114      *
    115      *          final float alpha = 0.8;
    116      *
    117      *          gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
    118      *          gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
    119      *          gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];
    120      *
    121      *          linear_acceleration[0] = event.values[0] - gravity[0];
    122      *          linear_acceleration[1] = event.values[1] - gravity[1];
    123      *          linear_acceleration[2] = event.values[2] - gravity[2];
    124      *     }
    125      * </pre>
    126      *
    127      * <p>
    128      * <u>Examples</u>:
    129      * <ul>
    130      * <li>When the device lies flat on a table and is pushed on its left side
    131      * toward the right, the x acceleration value is positive.</li>
    132      *
    133      * <li>When the device lies flat on a table, the acceleration value is
    134      * +9.81, which correspond to the acceleration of the device (0 m/s^2) minus
    135      * the force of gravity (-9.81 m/s^2).</li>
    136      *
    137      * <li>When the device lies flat on a table and is pushed toward the sky
    138      * with an acceleration of A m/s^2, the acceleration value is equal to
    139      * A+9.81 which correspond to the acceleration of the device (+A m/s^2)
    140      * minus the force of gravity (-9.81 m/s^2).</li>
    141      * </ul>
    142      *
    143      *
    144      * <h4>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD
    145      * Sensor.TYPE_MAGNETIC_FIELD}:</h4>
    146      * All values are in micro-Tesla (uT) and measure the ambient magnetic field
    147      * in the X, Y and Z axis.
    148      *
    149      * <h4>{@link android.hardware.Sensor#TYPE_GYROSCOPE Sensor.TYPE_GYROSCOPE}:
    150      * </h4> All values are in radians/second and measure the rate of rotation
    151      * around the device's local X, Y and Z axis. The coordinate system is the
    152      * same as is used for the acceleration sensor. Rotation is positive in the
    153      * counter-clockwise direction. That is, an observer looking from some
    154      * positive location on the x, y or z axis at a device positioned on the
    155      * origin would report positive rotation if the device appeared to be
    156      * rotating counter clockwise. Note that this is the standard mathematical
    157      * definition of positive rotation and does not agree with the definition of
    158      * roll given earlier.
    159      * <ul>
    160      * <li> values[0]: Angular speed around the x-axis </li>
    161      * <li> values[1]: Angular speed around the y-axis </li>
    162      * <li> values[2]: Angular speed around the z-axis </li>
    163      * </ul>
    164      * <p>
    165      * Typically the output of the gyroscope is integrated over time to
    166      * calculate a rotation describing the change of angles over the timestep,
    167      * for example:
    168      * </p>
    169      *
    170      * <pre class="prettyprint">
    171      *     private static final float NS2S = 1.0f / 1000000000.0f;
    172      *     private final float[] deltaRotationVector = new float[4]();
    173      *     private float timestamp;
    174      *
    175      *     public void onSensorChanged(SensorEvent event) {
    176      *          // This timestep's delta rotation to be multiplied by the current rotation
    177      *          // after computing it from the gyro sample data.
    178      *          if (timestamp != 0) {
    179      *              final float dT = (event.timestamp - timestamp) * NS2S;
    180      *              // Axis of the rotation sample, not normalized yet.
    181      *              float axisX = event.values[0];
    182      *              float axisY = event.values[1];
    183      *              float axisZ = event.values[2];
    184      *
    185      *              // Calculate the angular speed of the sample
    186      *              float omegaMagnitude = sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);
    187      *
    188      *              // Normalize the rotation vector if it's big enough to get the axis
    189      *              if (omegaMagnitude > EPSILON) {
    190      *                  axisX /= omegaMagnitude;
    191      *                  axisY /= omegaMagnitude;
    192      *                  axisZ /= omegaMagnitude;
    193      *              }
    194      *
    195      *              // Integrate around this axis with the angular speed by the timestep
    196      *              // in order to get a delta rotation from this sample over the timestep
    197      *              // We will convert this axis-angle representation of the delta rotation
    198      *              // into a quaternion before turning it into the rotation matrix.
    199      *              float thetaOverTwo = omegaMagnitude * dT / 2.0f;
    200      *              float sinThetaOverTwo = sin(thetaOverTwo);
    201      *              float cosThetaOverTwo = cos(thetaOverTwo);
    202      *              deltaRotationVector[0] = sinThetaOverTwo * axisX;
    203      *              deltaRotationVector[1] = sinThetaOverTwo * axisY;
    204      *              deltaRotationVector[2] = sinThetaOverTwo * axisZ;
    205      *              deltaRotationVector[3] = cosThetaOverTwo;
    206      *          }
    207      *          timestamp = event.timestamp;
    208      *          float[] deltaRotationMatrix = new float[9];
    209      *          SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);
    210      *          // User code should concatenate the delta rotation we computed with the current rotation
    211      *          // in order to get the updated rotation.
    212      *          // rotationCurrent = rotationCurrent * deltaRotationMatrix;
    213      *     }
    214      * </pre>
    215      * <p>
    216      * In practice, the gyroscope noise and offset will introduce some errors
    217      * which need to be compensated for. This is usually done using the
    218      * information from other sensors, but is beyond the scope of this document.
    219      * </p>
    220      * <h4>{@link android.hardware.Sensor#TYPE_LIGHT Sensor.TYPE_LIGHT}:</h4>
    221      * <ul>
    222      * <li>values[0]: Ambient light level in SI lux units </li>
    223      * </ul>
    224      *
    225      * <h4>{@link android.hardware.Sensor#TYPE_PRESSURE Sensor.TYPE_PRESSURE}:</h4>
    226      * <ul>
    227      * <li>values[0]: Atmospheric pressure in hPa (millibar) </li>
    228      * </ul>
    229      *
    230      * <h4>{@link android.hardware.Sensor#TYPE_PROXIMITY Sensor.TYPE_PROXIMITY}:
    231      * </h4>
    232      *
    233      * <ul>
    234      * <li>values[0]: Proximity sensor distance measured in centimeters </li>
    235      * </ul>
    236      *
    237      * <p>
    238      * <b>Note:</b> Some proximity sensors only support a binary <i>near</i> or
    239      * <i>far</i> measurement. In this case, the sensor should report its
    240      * {@link android.hardware.Sensor#getMaximumRange() maximum range} value in
    241      * the <i>far</i> state and a lesser value in the <i>near</i> state.
    242      * </p>
    243      *
    244      *  <h4>{@link android.hardware.Sensor#TYPE_GRAVITY Sensor.TYPE_GRAVITY}:</h4>
    245      *  <p>A three dimensional vector indicating the direction and magnitude of gravity.  Units
    246      *  are m/s^2. The coordinate system is the same as is used by the acceleration sensor.</p>
    247      *  <p><b>Note:</b> When the device is at rest, the output of the gravity sensor should be identical
    248      *  to that of the accelerometer.</p>
    249      *
    250      *  <h4>{@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION Sensor.TYPE_LINEAR_ACCELERATION}:</h4>
    251      *  A three dimensional vector indicating acceleration along each device axis, not including
    252      *  gravity.  All values have units of m/s^2.  The coordinate system is the same as is used by the
    253      *  acceleration sensor.
    254      *  <p>The output of the accelerometer, gravity and  linear-acceleration sensors must obey the
    255      *  following relation:</p>
    256      *   <p><ul>acceleration = gravity + linear-acceleration</ul></p>
    257      *
    258      *  <h4>{@link android.hardware.Sensor#TYPE_ROTATION_VECTOR Sensor.TYPE_ROTATION_VECTOR}:</h4>
    259      *  <p>The rotation vector represents the orientation of the device as a combination of an <i>angle</i>
    260      *  and an <i>axis</i>, in which the device has rotated through an angle &#952 around an axis
    261      *  &lt;x, y, z>.</p>
    262      *  <p>The three elements of the rotation vector are
    263      *  &lt;x*sin(&#952/2), y*sin(&#952/2), z*sin(&#952/2)>, such that the magnitude of the rotation
    264      *  vector is equal to sin(&#952/2), and the direction of the rotation vector is equal to the
    265      *  direction of the axis of rotation.</p>
    266      *  </p>The three elements of the rotation vector are equal to
    267      *  the last three components of a <b>unit</b> quaternion
    268      *  &lt;cos(&#952/2), x*sin(&#952/2), y*sin(&#952/2), z*sin(&#952/2)>.</p>
    269      *  <p>Elements of the rotation vector are unitless.
    270      *  The x,y, and z axis are defined in the same way as the acceleration
    271      *  sensor.</p>
    272      *  The reference coordinate system is defined as a direct orthonormal basis,
    273      *  where:
    274      * </p>
    275      *
    276      * <ul>
    277      * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to
    278      * the ground at the device's current location and roughly points East).</li>
    279      * <li>Y is tangential to the ground at the device's current location and
    280      * points towards magnetic north.</li>
    281      * <li>Z points towards the sky and is perpendicular to the ground.</li>
    282      * </ul>
    283      *
    284      * <p>
    285      * <center><img src="../../../images/axis_globe.png"
    286      * alt="World coordinate-system diagram." border="0" /></center>
    287      * </p>
    288      *
    289      * <ul>
    290      * <li> values[0]: x*sin(&#952/2) </li>
    291      * <li> values[1]: y*sin(&#952/2) </li>
    292      * <li> values[2]: z*sin(&#952/2) </li>
    293      * <li> values[3]: cos(&#952/2) </li>
    294      * <li> values[4]: estimated heading Accuracy (in radians) (-1 if unavailable)</li>
    295      * </ul>
    296      * <p> values[3], originally optional, will always be present from SDK Level 18 onwards.
    297      * values[4] is a new value that has been added in SDK Level 18.
    298      * </p>
    299      *
    300      * <h4>{@link android.hardware.Sensor#TYPE_ORIENTATION
    301      * Sensor.TYPE_ORIENTATION}:</h4> All values are angles in degrees.
    302      *
    303      * <ul>
    304      * <li> values[0]: Azimuth, angle between the magnetic north direction and the
    305      * y-axis, around the z-axis (0 to 359). 0=North, 90=East, 180=South,
    306      * 270=West
    307      * </p>
    308      *
    309      * <p>
    310      * values[1]: Pitch, rotation around x-axis (-180 to 180), with positive
    311      * values when the z-axis moves <b>toward</b> the y-axis.
    312      * </p>
    313      *
    314      * <p>
    315      * values[2]: Roll, rotation around the y-axis (-90 to 90)
    316      * increasing as the device moves clockwise.
    317      * </p>
    318      * </ul>
    319      *
    320      * <p>
    321      * <b>Note:</b> This definition is different from <b>yaw, pitch and roll</b>
    322      * used in aviation where the X axis is along the long side of the plane
    323      * (tail to nose).
    324      * </p>
    325      *
    326      * <p>
    327      * <b>Note:</b> This sensor type exists for legacy reasons, please use
    328      * {@link android.hardware.Sensor#TYPE_ROTATION_VECTOR
    329      * rotation vector sensor type} and
    330      * {@link android.hardware.SensorManager#getRotationMatrix
    331      * getRotationMatrix()} in conjunction with
    332      * {@link android.hardware.SensorManager#remapCoordinateSystem
    333      * remapCoordinateSystem()} and
    334      * {@link android.hardware.SensorManager#getOrientation getOrientation()} to
    335      * compute these values instead.
    336      * </p>
    337      *
    338      * <p>
    339      * <b>Important note:</b> For historical reasons the roll angle is positive
    340      * in the clockwise direction (mathematically speaking, it should be
    341      * positive in the counter-clockwise direction).
    342      * </p>
    343      *
    344      * <h4>{@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY
    345      * Sensor.TYPE_RELATIVE_HUMIDITY}:</h4>
    346      * <ul>
    347      * <li> values[0]: Relative ambient air humidity in percent </li>
    348      * </ul>
    349      * <p>
    350      * When relative ambient air humidity and ambient temperature are
    351      * measured, the dew point and absolute humidity can be calculated.
    352      * </p>
    353      * <u>Dew Point</u>
    354      * <p>
    355      * The dew point is the temperature to which a given parcel of air must be
    356      * cooled, at constant barometric pressure, for water vapor to condense
    357      * into water.
    358      * </p>
    359      * <center><pre>
    360      *                    ln(RH/100%) + m&#183;t/(T<sub>n</sub>+t)
    361      * t<sub>d</sub>(t,RH) = T<sub>n</sub> &#183; ------------------------------
    362      *                 m - [ln(RH/100%) + m&#183;t/(T<sub>n</sub>+t)]
    363      * </pre></center>
    364      * <dl>
    365      * <dt>t<sub>d</sub></dt> <dd>dew point temperature in &deg;C</dd>
    366      * <dt>t</dt>             <dd>actual temperature in &deg;C</dd>
    367      * <dt>RH</dt>            <dd>actual relative humidity in %</dd>
    368      * <dt>m</dt>             <dd>17.62</dd>
    369      * <dt>T<sub>n</sub></dt> <dd>243.12 &deg;C</dd>
    370      * </dl>
    371      * <p>for example:</p>
    372      * <pre class="prettyprint">
    373      * h = Math.log(rh / 100.0) + (17.62 * t) / (243.12 + t);
    374      * td = 243.12 * h / (17.62 - h);
    375      * </pre>
    376      * <u>Absolute Humidity</u>
    377      * <p>
    378      * The absolute humidity is the mass of water vapor in a particular volume
    379      * of dry air. The unit is g/m<sup>3</sup>.
    380      * </p>
    381      * <center><pre>
    382      *                    RH/100%&#183;A&#183;exp(m&#183;t/(T<sub>n</sub>+t))
    383      * d<sub>v</sub>(t,RH) = 216.7 &#183; -------------------------
    384      *                           273.15 + t
    385      * </pre></center>
    386      * <dl>
    387      * <dt>d<sub>v</sub></dt> <dd>absolute humidity in g/m<sup>3</sup></dd>
    388      * <dt>t</dt>             <dd>actual temperature in &deg;C</dd>
    389      * <dt>RH</dt>            <dd>actual relative humidity in %</dd>
    390      * <dt>m</dt>             <dd>17.62</dd>
    391      * <dt>T<sub>n</sub></dt> <dd>243.12 &deg;C</dd>
    392      * <dt>A</dt>             <dd>6.112 hPa</dd>
    393      * </dl>
    394      * <p>for example:</p>
    395      * <pre class="prettyprint">
    396      * dv = 216.7 *
    397      * (rh / 100.0 * 6.112 * Math.exp(17.62 * t / (243.12 + t)) / (273.15 + t));
    398      * </pre>
    399      *
    400      * <h4>{@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE Sensor.TYPE_AMBIENT_TEMPERATURE}:
    401      * </h4>
    402      *
    403      * <ul>
    404      * <li> values[0]: ambient (room) temperature in degree Celsius.</li>
    405      * </ul>
    406      *
    407      *
    408      * <h4>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD_UNCALIBRATED
    409      * Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED}:</h4>
    410      * Similar to {@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD},
    411      * but the hard iron calibration is reported separately instead of being included
    412      * in the measurement. Factory calibration and temperature compensation will still
    413      * be applied to the "uncalibrated" measurement. Assumptions that the magnetic field
    414      * is due to the Earth's poles is avoided.
    415      * <p>
    416      * The values array is shown below:
    417      * <ul>
    418      * <li> values[0] = x_uncalib </li>
    419      * <li> values[1] = y_uncalib </li>
    420      * <li> values[2] = z_uncalib </li>
    421      * <li> values[3] = x_bias </li>
    422      * <li> values[4] = y_bias </li>
    423      * <li> values[5] = z_bias </li>
    424      * </ul>
    425      * </p>
    426      * <p>
    427      * x_uncalib, y_uncalib, z_uncalib are the measured magnetic field in X, Y, Z axes.
    428      * Soft iron and temperature calibrations are applied. But the hard iron
    429      * calibration is not applied. The values are in micro-Tesla (uT).
    430      * </p>
    431      * <p>
    432      * x_bias, y_bias, z_bias give the iron bias estimated in X, Y, Z axes.
    433      * Each field is a component of the estimated hard iron calibration.
    434      * The values are in micro-Tesla (uT).
    435      * </p>
    436      * <p> Hard iron - These distortions arise due to the magnetized iron, steel or permanenet
    437      * magnets on the device.
    438      * Soft iron - These distortions arise due to the interaction with the earth's magentic
    439      * field.
    440      * </p>
    441      * <h4> {@link android.hardware.Sensor#TYPE_GAME_ROTATION_VECTOR}:</h4>
    442      * Identical to {@link android.hardware.Sensor#TYPE_ROTATION_VECTOR} except that it
    443      * doesn't use the geomagnetic field. Therefore the Y axis doesn't
    444      * point north, but instead to some other reference, that reference is
    445      * allowed to drift by the same order of magnitude as the gyroscope
    446      * drift around the Z axis.
    447      * <p>
    448      * In the ideal case, a phone rotated and returning to the same real-world
    449      * orientation will report the same game rotation vector
    450      * (without using the earth's geomagnetic field). However, the orientation
    451      * may drift somewhat over time. See {@link android.hardware.Sensor#TYPE_ROTATION_VECTOR}
    452      * for a detailed description of the values. This sensor will not have
    453      * the estimated heading accuracy value.
    454      * </p>
    455      *
    456      * <h4> {@link android.hardware.Sensor#TYPE_GYROSCOPE_UNCALIBRATED
    457      * Sensor.TYPE_GYROSCOPE_UNCALIBRATED}:</h4>
    458      * All values are in radians/second and measure the rate of rotation
    459      * around the X, Y and Z axis. An estimation of the drift on each axis is
    460      * reported as well.
    461      * <p>
    462      * No gyro-drift compensation is performed. Factory calibration and temperature
    463      * compensation is still applied to the rate of rotation (angular speeds).
    464      * </p>
    465      * <p>
    466      * The coordinate system is the same as is used for the
    467      * {@link android.hardware.Sensor#TYPE_ACCELEROMETER}
    468      * Rotation is positive in the counter-clockwise direction (right-hand rule).
    469      * That is, an observer looking from some positive location on the x, y or z axis
    470      * at a device positioned on the origin would report positive rotation if the device
    471      * appeared to be rotating counter clockwise.
    472      * The range would at least be 17.45 rad/s (ie: ~1000 deg/s).
    473      * <ul>
    474      * <li> values[0] : angular speed (w/o drift compensation) around the X axis in rad/s </li>
    475      * <li> values[1] : angular speed (w/o drift compensation) around the Y axis in rad/s </li>
    476      * <li> values[2] : angular speed (w/o drift compensation) around the Z axis in rad/s </li>
    477      * <li> values[3] : estimated drift around X axis in rad/s </li>
    478      * <li> values[4] : estimated drift around Y axis in rad/s </li>
    479      * <li> values[5] : estimated drift around Z axis in rad/s </li>
    480      * </ul>
    481      * </p>
    482      * <p><b>Pro Tip:</b> Always use the length of the values array while performing operations
    483      * on it. In earlier versions, this used to be always 3 which has changed now. </p>
    484      *
    485      * @see GeomagneticField
    486      */
    487     public final float[] values;
    488 
    489     /**
    490      * The sensor that generated this event. See
    491      * {@link android.hardware.SensorManager SensorManager} for details.
    492      */
    493     public Sensor sensor;
    494 
    495     /**
    496      * The accuracy of this event. See {@link android.hardware.SensorManager
    497      * SensorManager} for details.
    498      */
    499     public int accuracy;
    500 
    501     /**
    502      * The time in nanosecond at which the event happened
    503      */
    504     public long timestamp;
    505 
    506     SensorEvent(int valueSize) {
    507         values = new float[valueSize];
    508     }
    509 }
    510