Example usage for android.hardware SensorManager getRotationMatrix

List of usage examples for android.hardware SensorManager getRotationMatrix

Introduction

In this page you can find the example usage for android.hardware SensorManager getRotationMatrix.

Prototype


public static boolean getRotationMatrix(float[] R, float[] I, float[] gravity, float[] geomagnetic) 

Source Link

Document

Computes the inclination matrix I as well as the rotation matrix R transforming a vector from the device coordinate system to the world's coordinate system which is defined as a direct orthonormal basis, where:

  • X is defined as the vector product Y.Z (It is tangential to the ground at the device's current location and roughly points East).
  • Y is tangential to the ground at the device's current location and points towards the magnetic North Pole.
  • Z points towards the sky and is perpendicular to the ground.

World coordinate-system diagram.Usage

From source file:com.javadog.cgeowear.cgeoWear.java

/**
 * Interprets watch compass if user has requested that feature.
 *///from   www  . j  a  v a 2  s.com
@Override
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        gravity = event.values.clone();
    } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
        geomagnetic = event.values.clone(); //TODO: Some watches don't let me access the compass correctly yet.
    }

    if (gravity != null && geomagnetic != null) {
        float[] R = new float[9];
        float[] I = new float[9];

        boolean success = SensorManager.getRotationMatrix(R, I, gravity, geomagnetic);
        if (success) {
            float[] orientation = new float[3];
            SensorManager.getOrientation(R, orientation);
            float azimuth = (float) Math.toDegrees(orientation[0]);

            if (currentLocation != null) {
                float smoothedLatitude = smoothSensorValues(oldLatitude, (float) currentLocation.getLatitude(),
                        1 / 3f);
                float smoothedLongitude = smoothSensorValues(oldLongitude,
                        (float) currentLocation.getLongitude(), 1 / 3f);
                float smoothedAltitude = smoothSensorValues(oldAltitude, (float) currentLocation.getAltitude(),
                        1 / 3f);

                GeomagneticField geomagneticField = new GeomagneticField(smoothedLatitude, smoothedLongitude,
                        smoothedAltitude, System.currentTimeMillis());
                azimuth += geomagneticField.getDeclination();

                float bearing = currentLocation.bearingTo(geocacheLocation);

                direction = smoothSensorValues(oldDirection, -(azimuth - bearing), 1 / 5f);

                //Set old values to current values (for smoothing)
                oldDirection = direction;
                oldLatitude = smoothedLatitude;
                oldLongitude = smoothedLongitude;
                oldAltitude = smoothedAltitude;

                //Display direction on compass if update interval has passed
                long currentTime = System.currentTimeMillis();
                if ((currentTime - prevTime) > DIRECTION_UPDATE_SPEED) {
                    rotateCompass(direction);
                    prevTime = currentTime;
                }
            }
        }
    }
}

From source file:com.samebits.beacon.locator.ui.view.RadarScanView.java

private synchronized void calcBearing(SensorEvent event) {

    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        System.arraycopy(event.values, 0, mLastAccelerometer, 0, event.values.length);
        mLastAccelerometerSet = true;//  ww w .  j  a  va  2 s  . c  o  m
    } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
        System.arraycopy(event.values, 0, mLastMagnetometer, 0, event.values.length);
        mLastMagnetometerSet = true;
    }
    if (mLastAccelerometerSet && mLastMagnetometerSet) {

        /* Create rotation Matrix */
        float[] rotationMatrix = new float[9];
        if (SensorManager.getRotationMatrix(rotationMatrix, null, mLastAccelerometer, mLastMagnetometer)) {
            SensorManager.getOrientation(rotationMatrix, mOrientation);

            float azimuthInRadians = mOrientation[0];

            angleLowpassFilter.add(azimuthInRadians);

            mLast_bearing = (float) (Math.toDegrees(angleLowpassFilter.average()) + 360) % 360;

            postInvalidate();

            //Log.d(Constants.TAG, "orientation bearing: " + mLast_bearing);

        }
    }
}

From source file:com.cubic9.android.droidglove.Main.java

@Override
public void onSensorChanged(SensorEvent event) {
    Float[] avgAngles = new Float[3];
    float[] rotationMatrix = new float[9];
    float[] attitude = new float[3];

    switch (event.sensor.getType()) {
    case Sensor.TYPE_MAGNETIC_FIELD:
        geomagnetic = event.values.clone();
        break;//w w  w.j  a  va2  s .  c o  m
    case Sensor.TYPE_ACCELEROMETER:
        gravity = event.values.clone();
        break;
    }

    if (geomagnetic != null && gravity != null) {
        SensorManager.getRotationMatrix(rotationMatrix, null, gravity, geomagnetic);
        SensorManager.getOrientation(rotationMatrix, attitude);

        if (!mInitirizedSensor) {
            if (mCountBeforeInit > 20) {
                mInitirizedSensor = true;
                initYaw = (float) Math.toDegrees(attitude[0]);
            } else {
                mCountBeforeInit++;
            }
        }

        for (int i = 0; i < 3; i++) {
            for (int j = AVERAGE_AMOUNT - 1; j > 0; j--) {
                mOrigAngles[i][j] = mOrigAngles[i][j - 1];
            }
        }

        mOrigAngles[0][0] = (float) Math.toDegrees(attitude[0]) - initYaw;
        mOrigAngles[1][0] = (float) Math.toDegrees(attitude[1]);
        mOrigAngles[2][0] = (float) Math.toDegrees(attitude[2]);

        for (int i = 0; i < 3; i++) {
            avgAngles[i] = 0f;
            for (int j = 0; j < AVERAGE_AMOUNT; j++) {
                avgAngles[i] += mOrigAngles[i][j];
            }
            avgAngles[i] /= AVERAGE_AMOUNT;
        }

        /*
         * textViewX.setText(avgAngles[0].toString());
         * textViewY.setText(avgAngles[1].toString());
         * textViewZ.setText(avgAngles[2].toString());
         * textViewGrip.setText(Float.toString(mYDiff));
         */

        // create message for send
        List<Object> valueList = new ArrayList<Object>();
        valueList.add(avgAngles[1]);
        valueList.add(avgAngles[0]);
        valueList.add(-avgAngles[2]);
        valueList.add(Integer.valueOf((int) mYDiff));
        OSCMessage message = new OSCMessage(OSC_ADDRESS_TO_PC, valueList);

        // send
        try {
            mSender.send(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

From source file:com.javadog.cgeowear.WearService.java

/**
 * Handles compass rotation.//  w w w . j a  v a 2s .  c o  m
 */
@Override
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        gravity = event.values.clone();
    } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
        geomagnetic = event.values.clone();
    }

    if (gravity != null && geomagnetic != null) {
        float[] R = new float[9];
        float[] I = new float[9];

        boolean success = SensorManager.getRotationMatrix(R, I, gravity, geomagnetic);
        if (success) {
            float[] orientation = new float[3];
            SensorManager.getOrientation(R, orientation);
            float azimuth = (float) Math.toDegrees(orientation[0]);
            float pitch = (float) Math.toDegrees(orientation[1]);

            if (currentLocation != null) {
                float smoothedLatitude = smoothSensorValues(oldLatitude, (float) currentLocation.getLatitude(),
                        1 / 3f);
                float smoothedLongitude = smoothSensorValues(oldLongitude,
                        (float) currentLocation.getLongitude(), 1 / 3f);
                float smoothedAltitude = smoothSensorValues(oldAltitude, (float) currentLocation.getAltitude(),
                        1 / 3f);

                GeomagneticField geomagneticField = new GeomagneticField(smoothedLatitude, smoothedLongitude,
                        smoothedAltitude, System.currentTimeMillis());
                azimuth += geomagneticField.getDeclination();

                float bearing = currentLocation.bearingTo(geocacheLocation);

                float direction = smoothSensorValues(oldDirection, -(azimuth - bearing), 1 / 5f);

                //If the user puts the phone in his/her pocket upside-down, invert the compass
                if (pitch > 0) {
                    direction += 180f;
                }

                //Set old values to current values (for smoothing)
                oldDirection = direction;
                oldLatitude = smoothedLatitude;
                oldLongitude = smoothedLongitude;
                oldAltitude = smoothedAltitude;

                //Send direction update to Android Wear if update interval has passed
                long currentTime = System.currentTimeMillis();
                if ((currentTime - prevTime) > DIRECTION_UPDATE_SPEED) {
                    wearInterface.sendDirectionUpdate(direction);
                    prevTime = currentTime;
                }
            }
        }
    }
}

From source file:com.thalmic.android.sample.helloworld.HelloWorldActivity.java

public void calculateAngles(float[] result, float[] rVector, float[] accVector, float[] magVector) {
    //caculate temp rotation matrix from rotation vector first
    SensorManager.getRotationMatrix(rMatrix, null, accVector, magVector);
    SensorManager.getQuaternionFromVector(quaternion, rVector);

    roll = Math.atan2(2.0f * (quaternion[0] * quaternion[1] + quaternion[2] * quaternion[3]),
            1.0f - 2.0f * (quaternion[1] * quaternion[1] + quaternion[2] * quaternion[2]));
    pitch = Math.asin(2.0f * (quaternion[0] * quaternion[2] - quaternion[3] * quaternion[1]));
    yaw = Math.atan2(2.0f * (quaternion[0] * quaternion[3] + quaternion[1] * quaternion[2]),
            1.0f - 2.0f * (quaternion[2] * quaternion[2] + quaternion[3] * quaternion[3]));

    rollW = ((roll + Math.PI) / (Math.PI * 2.0) * SCALE);
    pitchW = ((pitch + Math.PI / 2.0) / Math.PI * SCALE);
    yawW = ((yaw + Math.PI) / (Math.PI * 2.0) * SCALE);

    //calculate Euler angles now
    SensorManager.getOrientation(rMatrix, result);

    //Now we can convert it to degrees
    convertToDegrees(result);/* w  w w. j  ava  2 s  . co m*/
}

From source file:com.thousandthoughts.tutorials.SensorFusionActivity.java

public void calculateAccMagOrientation() {
    if (SensorManager.getRotationMatrix(rotationMatrix, null, accel, magnet)) {
        SensorManager.getOrientation(rotationMatrix, accMagOrientation);
    }/*  w w  w  . ja  va2  s  . c  o  m*/
}

From source file:com.example.zoetablet.BasicFragmentActivity.java

public float[] calculateOrientation() {
    float[] values = new float[3];
    float[] R = new float[9];
    float[] outR = new float[9];

    SensorManager.getRotationMatrix(R, null, aValues, mValues);
    SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X, SensorManager.AXIS_Y, outR);

    SensorManager.getOrientation(outR, values);

    // Convert from Radians to Degrees.
    values[0] = (float) Math.toDegrees(values[0]);
    values[1] = (float) Math.toDegrees(values[1]);
    values[2] = (float) Math.toDegrees(values[2]);

    // System.out.println("Compass " + values[0] + " " + values[1] + " " + values[2]);
    if (values[0] != 0.0 && values[1] != 0.0) {
        compassV0 = values[0];// w  w w. j a v a 2s  .co m
        compassV1 = values[1];
        compassV2 = values[2];
    }

    if (values[0] == 0.0 && values[1] == 0.0) {
        //If data is spitting out zeros, keep last good value
        values[0] = compassV0;
        values[1] = compassV1;
        values[2] = compassV2;
    }
    return values;
}

From source file:uk.org.rivernile.edinburghbustracker.android.fragments.general.BusStopDetailsFragment.java

/**
 * Update the direction needle so that it is pointing towards the bus stop,
 * based on the device location and the direction it is facing.
 *//* w  ww.ja  v  a2  s  . c  o m*/
private void updateDirectionNeedle() {
    // We need values for location, the accelerometer and magnetometer to
    // continue.
    if (lastLocation == null || accelerometerValues == null || magnetometerValues == null) {
        // Make sure the needle isn't showing.
        txtDistance.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
        recycleNeedleBitmapIfNotNull(null);

        return;
    }

    // Calculating the rotation matrix may fail, for example, if the device
    // is in freefall. In that case we cannot continue as the values will
    // be unreliable.
    if (!SensorManager.getRotationMatrix(rotationMatrix, null, accelerometerValues, magnetometerValues)) {
        return;
    }

    // The screen rotation was obtained earlier.
    switch (screenRotation) {
    // There's lots of information about this elsewhere, but briefly;
    // The values from the sensors are in the device's coordinate system
    // which may be correct if the device is in its natural orientation,
    // but it needs to be remapped if the device is rotated.
    case Surface.ROTATION_0:
        SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z,
                rotationMatrix);
        break;
    case Surface.ROTATION_90:
        SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_Z, SensorManager.AXIS_MINUS_X,
                rotationMatrix);
        break;
    case Surface.ROTATION_180:
        SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_MINUS_X,
                SensorManager.AXIS_MINUS_Z, rotationMatrix);
        break;
    case Surface.ROTATION_270:
        SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_MINUS_Z, SensorManager.AXIS_X,
                rotationMatrix);
        break;
    }

    // Get the X, Y and Z orientations, which are in radians. Covert this
    // in to degrees East of North.
    SensorManager.getOrientation(rotationMatrix, headings);
    double heading = Math.toDegrees(headings[0]);

    // If there's a GeomagneticField value, then adjust the heading to take
    // this in to account.
    if (geoField != null) {
        heading -= geoField.getDeclination();
    }

    // The orientation is in the range of -180 to +180. Convert this in to
    // a range of 0 to 360.
    final float bearingTo = distance[1] < 0 ? distance[1] + 360 : distance[1];

    // This is the heading to the bus stop.
    heading = bearingTo - heading;

    // The above calculation may come out as a negative number again. Put
    // this back in to the range of 0 to 360.
    if (heading < 0) {
        heading += 360;
    }

    // This 'if' statement is required to prevent a crash during device
    // rotation. It ensured that the Fragment is still part of the Activity.
    if (isAdded()) {
        // Get the arrow bitmap from the resources.
        final Bitmap needleIn = BitmapFactory.decodeResource(getResources(), R.drawable.heading_arrow);
        // Get an identity matrix and rotate it by the required amount.
        final Matrix m = new Matrix();
        m.setRotate((float) heading % 360, (float) needleIn.getWidth() / 2, (float) needleIn.getHeight() / 2);
        // Apply the rotation matrix to the Bitmap, to create a new Bitmap.
        final Bitmap needleOut = Bitmap.createBitmap(needleIn, 0, 0, needleIn.getWidth(), needleIn.getHeight(),
                m, true);

        // Recycle the needle read in if it's not the same as the rotated
        // needle.
        if (needleIn != needleOut) {
            needleIn.recycle();
        }

        // This Bitmap needs to be converted to a Drawable type.
        final BitmapDrawable drawable = new BitmapDrawable(getResources(), needleOut);
        // Set the new needle to be on the right hand side of the TextView.
        txtDistance.setCompoundDrawablesWithIntrinsicBounds(null, null, drawable, null);
        recycleNeedleBitmapIfNotNull(needleOut);
    } else {
        // If the Fragment is not added to the Activity, then make sure
        // there's no needle.
        txtDistance.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
        recycleNeedleBitmapIfNotNull(null);
    }
}

From source file:com.davidmascharka.lips.MainActivity.java

@Override
public void onSensorChanged(SensorEvent event) {
    /*//  w  w w  .j  a  v  a2s .c o m
     * Because Android doesn't let us query a sensor reading whenever we want so
     * we have to keep track of the readings at all times. Here we just update
     * the class members with the values associated with each reading we're
     * interested in.
     */
    switch (event.sensor.getType()) {
    case Sensor.TYPE_ACCELEROMETER:
        accelerometerX = event.values[0];
        accelerometerY = event.values[1];
        accelerometerZ = event.values[2];
        break;
    case Sensor.TYPE_MAGNETIC_FIELD:
        magneticX = event.values[0];
        magneticY = event.values[1];
        magneticZ = event.values[2];
        break;
    case Sensor.TYPE_LIGHT:
        light = event.values[0];
        break;
    case Sensor.TYPE_ROTATION_VECTOR:
        rotationX = event.values[0];
        rotationY = event.values[1];
        rotationZ = event.values[2];
        break;
    default:
        break;
    }

    SensorManager.getRotationMatrix(rotation, inclination,
            new float[] { accelerometerX, accelerometerY, accelerometerZ },
            new float[] { magneticX, magneticY, magneticZ });
    orientation = SensorManager.getOrientation(rotation, orientation);
}

From source file:org.osm.keypadmapper2.KeypadMapper2Activity.java

@Override
public void onSensorChanged(SensorEvent event) {
    synchronized (this) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
            mGravity = event.values;/*from   w  w w.j  a va2s  .  c om*/
        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
            mGeomagnetic = event.values;
        if (mGravity != null && mGeomagnetic != null) {
            float R[] = new float[9];
            float I[] = new float[9];
            boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
            if (success) {
                float orientation[] = new float[3];
                SensorManager.getOrientation(R, orientation);
                azimuth = orientation[0]; // orientation contains: azimuth, pitch and roll
            }
        }
    }
}