下面列出了android.hardware.SensorManager#getRotationMatrix ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void updateOrientation() {
float[] lastAccelerometer = mSensorData[kSensorType_Accelerometer].values;
float[] lastMagnetometer = mSensorData[kSensorType_Magnetometer].values;
if (lastAccelerometer != null && lastMagnetometer != null) {
SensorManager.getRotationMatrix(mRotation, null, lastAccelerometer, lastMagnetometer);
SensorManager.getOrientation(mRotation, mOrientation);
final boolean kUse4Components = true;
if (kUse4Components) {
SensorManager.getQuaternionFromVector(mQuaternion, mOrientation);
// Quaternions in Android are stored as [w, x, y, z], so we change it to [x, y, z, w]
float w = mQuaternion[0];
mQuaternion[0] = mQuaternion[1];
mQuaternion[1] = mQuaternion[2];
mQuaternion[2] = mQuaternion[3];
mQuaternion[3] = w;
mSensorData[kSensorType_Quaternion].values = mQuaternion;
} else {
mSensorData[kSensorType_Quaternion].values = mOrientation;
}
}
}
private void calculateCompassDirection(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
mAccelerationValues = event.values.clone();
break;
case Sensor.TYPE_MAGNETIC_FIELD:
mGravityValues = event.values.clone();
break;
}
boolean success = SensorManager.getRotationMatrix(mRotationMatrix, null,
mAccelerationValues, mGravityValues);
if (success) {
float[] orientationValues = new float[3];
SensorManager.getOrientation(mRotationMatrix, orientationValues);
float azimuth = (float) Math.toDegrees(-orientationValues[0]);
RotateAnimation rotateAnimation = new RotateAnimation(mLastDirectionInDegrees, azimuth,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(50);
rotateAnimation.setFillAfter(true);
mImageViewCompass.startAnimation(rotateAnimation);
mLastDirectionInDegrees = azimuth;
}
}
@Override
public void onSensorChanged(SensorEvent event) {
// we received a sensor event. it is a good practice to check
// that we received the proper event
float inv = 1f - Config.SOFTEN_NON_GYRO_ROTATION;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
magnitudeValues[0] = filters[0].get(event.values[0]);
magnitudeValues[1] = filters[1].get(event.values[0]);
magnitudeValues[2] = filters[2].get(event.values[0]);
} else if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
accelerometerValues[0] = filters[3].get(event.values[0]);
accelerometerValues[1] = filters[4].get(event.values[1]);
accelerometerValues[2] = filters[5].get(event.values[2]);
}
if (magnitudeValues != null && accelerometerValues != null) {
float[] i = new float[16];
// Fuse accelerometer with compass
SensorManager.getRotationMatrix(currentOrientationRotationMatrix, i, accelerometerValues,
magnitudeValues);
}
}
private void updateOrientation() {
SensorManager.getRotationMatrix(this.mRotationMatrix, null, this.mAccelerationValues, this.mMagneticFieldValues);
// TODO Use dont't use identical matrixes in remapCoordinateSystem, due to performance reasons.
switch (this.mDisplayRotation) {
case Surface.ROTATION_0:
/* Nothing. */
break;
case Surface.ROTATION_90:
SensorManager.remapCoordinateSystem(this.mRotationMatrix, SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X, this.mRotationMatrix);
break;
// case Surface.ROTATION_180:
// SensorManager.remapCoordinateSystem(this.mRotationMatrix, SensorManager.AXIS_?, SensorManager.AXIS_?, this.mRotationMatrix);
// break;
// case Surface.ROTATION_270:
// SensorManager.remapCoordinateSystem(this.mRotationMatrix, SensorManager.AXIS_?, SensorManager.AXIS_?, this.mRotationMatrix);
// break;
}
final float[] values = this.mValues;
SensorManager.getOrientation(this.mRotationMatrix, values);
for (int i = values.length - 1; i >= 0; i--) {
values[i] = values[i] * MathConstants.RAD_TO_DEG;
}
}
private void listing16_12() {
// Listing 16-12: Finding the current orientation using the accelerometer and magnetometer
float[] values = new float[3];
float[] R = new float[9];
SensorManager.getRotationMatrix(R, null,
mAccelerometerValues,
mMagneticFieldValues);
SensorManager.getOrientation(R, values);
// Convert from radians to degrees if preferred.
values[0] = (float) Math.toDegrees(values[0]); // Azimuth
values[1] = (float) Math.toDegrees(values[1]); // Pitch
values[2] = (float) Math.toDegrees(values[2]); // Roll
}
/**
* Callback for processing data from the registered sensors. Accelerometer and magnetometer
* data are used together to get orientation data.
*
* @param sensorEvent The event containing the sensor data values.
*/
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
Log.v(TAG, "onSensorChanged() entered");
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
Log.v(TAG, "Accelerometer -- x: " + sensorEvent.values[0] + " y: "
+ sensorEvent.values[1] + " z: " + sensorEvent.values[2]);
G = sensorEvent.values;
} else if (sensorEvent.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
Log.v(TAG, "Magnetometer -- x: " + sensorEvent.values[0] + " y: "
+ sensorEvent.values[1] + " z: " + sensorEvent.values[2]);
M = sensorEvent.values;
}
if (G != null && M != null) {
if (SensorManager.getRotationMatrix(R, I, G, M)) {
float[] previousO = O.clone();
O = SensorManager.getOrientation(R, O);
yaw = O[0] - previousO[0];
Log.v(TAG, "Orientation: azimuth: " + O[0] + " pitch: " + O[1] + " roll: " + O[2] + " yaw: " + yaw);
}
}
}
private float[] getGyroscopeValues(float timeDifference) {
float[] angularRates = new float[] {0.0F, 0.0F, 0.0F};
float[] rotationMatrix = new float[9];
float[] gravityRot = new float[3];
float[] angleChange = new float[3];
SensorManager.getRotationMatrix(rotationMatrix, null, this.accelerometerValues, this.magneticValues);
gravityRot[0] = GRAVITY[0] * rotationMatrix[0] + GRAVITY[1] * rotationMatrix[3] + GRAVITY[2] * rotationMatrix[6];
gravityRot[1] = GRAVITY[0] * rotationMatrix[1] + GRAVITY[1] * rotationMatrix[4] + GRAVITY[2] * rotationMatrix[7];
gravityRot[2] = GRAVITY[0] * rotationMatrix[2] + GRAVITY[1] * rotationMatrix[5] + GRAVITY[2] * rotationMatrix[8];
SensorManager.getRotationMatrix(rotationMatrix, null, gravityRot, this.magneticValues);
SensorManager.getAngleChange(angleChange, rotationMatrix, this.prevRotationMatrix);
angularRates[0] = -(angleChange[1]) / timeDifference;
angularRates[1] = (angleChange[2]) / timeDifference;
angularRates[2] = (angleChange[0]) / timeDifference;
this.prevRotationMatrix = rotationMatrix;
return angularRates;
}
/**
* Called by {@link MainActivity} when a sensor's reading changes.
* Rotates sky plot according to bearing.
*
* If {@code TYPE_ORIENTATION} data is available, preference is given to that value, which
* appeared to be more accurate in tests. Otherwise orientation is obtained from the rotation
* vector of the device, based on {@link TYPE_ACCELEROMETER} and {@code TYPE_MAGNETIC_FIELD}
* sensor data.
*/
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
gravity = event.values.clone();
break;
case Sensor.TYPE_MAGNETIC_FIELD:
geomagnetic = event.values.clone();
break;
case Sensor.TYPE_ORIENTATION:
if (event.values[0] != 0) {
hasOrientation = true;
gpsStatusView.setYaw(event.values[0]);
}
break;
}
if ((gravity != null) && (geomagnetic != null) && !hasOrientation) {
float[] ypr = new float[3];
float[] r = new float[16];
float[] i = new float[16];
SensorManager.getRotationMatrix(r, i, gravity, geomagnetic);
ypr = SensorManager.getOrientation(r, ypr);
gpsStatusView.setYaw((float) Math.toDegrees(ypr[0]));
}
}
/**
* Computes the Transformation from device to world coordinates
*/
private void computeRotationMatrix() {
synchronized (rotMatrix) {
if (magnetValues.hasValues() && accelValues.hasValues()) {
SensorManager.getRotationMatrix(rotMatrixSensor, null,
accelValues.get(), magnetValues.get());
// transforms from sensor to world
switch (display.getOrientation()) {
case Surface.ROTATION_0:
// No adjustment
SensorManager.remapCoordinateSystem(rotMatrixSensor,
SensorManager.AXIS_X, SensorManager.AXIS_Y,
rotMatrix);
break;
case Surface.ROTATION_90:
SensorManager.remapCoordinateSystem(rotMatrixSensor,
SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X,
rotMatrix);
break;
case Surface.ROTATION_180:
SensorManager.remapCoordinateSystem(rotMatrixSensor,
SensorManager.AXIS_MINUS_X,
SensorManager.AXIS_MINUS_Y, rotMatrix);
break;
case Surface.ROTATION_270:
SensorManager.remapCoordinateSystem(rotMatrixSensor,
SensorManager.AXIS_MINUS_Y, SensorManager.AXIS_X,
rotMatrix);
break;
}
// transforms from device to world
Matrix.rotateM(rotMatrix, 0, 90, 1, 0, 0);
// Account for the upward usage of this app
}
}
}
@Override
public void onSensorChanged(SensorEvent event) {
// Get the device heading
float degree = Math.round( event.values[0] );
currentDegree = -degree;
switch (event.sensor.getType()) {
case Sensor.TYPE_MAGNETIC_FIELD:
mags = event.values.clone();
break;
case Sensor.TYPE_ACCELEROMETER:
accels = event.values.clone();
break;
}
if (mags != null && accels != null) {
gravity = new float[9];
magnetic = new float[9];
SensorManager.getRotationMatrix(gravity, magnetic, accels, mags);
float[] outGravity = new float[9];
SensorManager.remapCoordinateSystem(gravity, SensorManager.AXIS_X,SensorManager.AXIS_Z, outGravity);
SensorManager.getOrientation(outGravity, values);
azimuth = values[0] * 57.2957795f;
pitch = values[1] * 57.2957795f;
roll = values[2] * 57.2957795f;
mags = null;
accels = null;
}
}
/**
* Computes the latest rotation, remaps it according to the current {@link #screenRotation},
* and stores it in {@link #rotationMatrix}.
* <p>
* Should only be called if {@link #haveDataNecessaryToComputeOrientation()} returns true and
* {@link #haveRotVecData} is false, else result may be undefined.
*
* @return true if rotation was retrieved and recalculated, false otherwise.
*/
private boolean computeRotationMatrix() {
if (SensorManager.getRotationMatrix(rotationMatrixTemp, null, latestAccelerations, latestMagFields)) {
switch (screenRotation) {
case Surface.ROTATION_0:
SensorManager.remapCoordinateSystem(rotationMatrixTemp,
SensorManager.AXIS_X, SensorManager.AXIS_Y, rotationMatrix);
break;
case Surface.ROTATION_90:
//noinspection SuspiciousNameCombination
SensorManager.remapCoordinateSystem(rotationMatrixTemp,
SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X, rotationMatrix);
break;
case Surface.ROTATION_180:
SensorManager.remapCoordinateSystem(rotationMatrixTemp,
SensorManager.AXIS_MINUS_X, SensorManager.AXIS_MINUS_Y, rotationMatrix);
break;
case Surface.ROTATION_270:
//noinspection SuspiciousNameCombination
SensorManager.remapCoordinateSystem(rotationMatrixTemp,
SensorManager.AXIS_MINUS_Y, SensorManager.AXIS_X, rotationMatrix);
break;
}
return true;
}
return false;
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED)
mGeomagnetic = event.values;
if ((mGravity == null) || (mGeomagnetic == null))
return;
float[] R = new float[9];
float[] I = new float[9];
if (!SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic))
return;
float[] orientation = new float[3];
SensorManager.getOrientation(R, orientation);
if (orientation == null)
return;
double rollAngle = orientation[1] * 180 / Math.PI;
double pitchAngle = orientation[2] * 180 / Math.PI;
if(notWithinAngleTolerance((int)rollAngle, mLastRoll))
this.mRollTextView.setText(String.format("%.0f", (rollAngle)));
if(notWithinAngleTolerance((int)pitchAngle,mLastPitch))
this.mPitchTextView.setText(String.format("%.0f", (pitchAngle)));
mLastPitch = (int)pitchAngle;
mLastRoll = (int) rollAngle;
calculateAndSetSpeed(rollAngle,pitchAngle);
}
private void setRotationMatrix() {
boolean haveInclination = false;
if (gravityListener != null && magneticFieldListener != null &&
SensorManager.getRotationMatrix(
rotationMatrix,
inclinationMatrix,
gravityValues,
magneticFieldListener.filtered)) {
haveInclination = true;
} else if (rotationVectorListener != null) {
SensorManager.getRotationMatrixFromVector(
rotationMatrix,
rotationVectorListener.values);
} else {
return;
}
if (deviceRotation != 0) {
int x = SensorManager.AXIS_Y;
int y = SensorManager.AXIS_MINUS_X;
switch (deviceRotation) {
default:
break;
case 270:
x = SensorManager.AXIS_MINUS_Y;
y = SensorManager.AXIS_X;
break;
}
SensorManager.remapCoordinateSystem(
rotationMatrix,
x,
y,
rotationMatrix);
}
if (rotationMatrixLoc > -1) {
GLES20.glUniformMatrix3fv(rotationMatrixLoc, 1, true,
rotationMatrix, 0);
}
if (orientationLoc > -1) {
SensorManager.getOrientation(rotationMatrix, orientation);
GLES20.glUniform3fv(orientationLoc, 1, orientation, 0);
}
if (inclinationMatrixLoc > -1 && haveInclination) {
GLES20.glUniformMatrix3fv(inclinationMatrixLoc, 1, true,
inclinationMatrix, 0);
}
if (inclinationLoc > -1 && haveInclination) {
GLES20.glUniform1f(inclinationLoc,
SensorManager.getInclination(inclinationMatrix));
}
}
/**
* override function return every change
*
* @param event Sensor changes
*/
@Override
public void onSensorChanged(SensorEvent event) {
double startTime = System.currentTimeMillis();
if (event.sensor == mAccelerometer) {
mLastAccelerometer = event.values;
mLastAccelerometerSet = true;
} else if (event.sensor == mMagnetometer) {
mLastMagnetometer = event.values;
mLastMagnetometerSet = true;
}
if (mLastAccelerometerSet && mLastMagnetometerSet) {
boolean success = SensorManager.getRotationMatrix(mR, null, mLastAccelerometer, mLastMagnetometer);
SensorManager.getOrientation(mR, mOrientation);
float azimuthInRadians = mOrientation[0];
double azimuthInDegress = -(float) (Math.toDegrees(azimuthInRadians) + 360) % 360;
if (Math.abs(azimuthInDegress - previousAzimuthInDegrees) > 300) {
previousAzimuthInDegrees = azimuthInDegress;
}
azimuthInDegress = lowPass(azimuthInDegress, previousAzimuthInDegrees, startTime);
if (mapReady) updateCamera((float) azimuthInDegress);
RotateAnimation ra = new RotateAnimation(
(float) previousAzimuthInDegrees,
(float) azimuthInDegress,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF,
0.5f);
ra.setDuration(500);
ra.setFillAfter(true);
compass.startAnimation(ra);
innerPosition.startAnimation(ra);
previousAzimuthInDegrees = azimuthInDegress;
if (pointerPosition == true) {
pointerFirstPositionX = compassLevel.getX();
pointerFirstPositionY = compassLevel.getY();
smallCircleRadius = smallCircleLevel.getX();
pointerPosition = false;
}
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(mR, orientation);
double yaw = orientation[0] * 57.2957795f;
double pitch = orientation[1] * 57.2957795f;
double roll = orientation[2] * 57.2957795f;
if (pitch > 90) pitch -= 180;
if (pitch < -90) pitch += 180;
if (roll > 90) roll -= 180;
if (roll < -90) roll += 180;
double time = System.currentTimeMillis();
if (!start) {
lastTime = time;
lastRoll = roll;
lastPitch = pitch;
}
start = true;
double dt = (time - lastTime) / 1000.0;
roll = lowPassPointerLevel(roll, lastRoll, dt);
pitch = lowPassPointerLevel(pitch, lastPitch, dt);
lastTime = time;
lastRoll = roll;
lastPitch = pitch;
newX = (float) (pointerFirstPositionX + pointerFirstPositionX * roll / 90.0);
newY = (float) (pointerFirstPositionY + pointerFirstPositionY * pitch / 90.0);
compassLevel.setX(newX);
compassLevel.setY(newY);
if (smallCircleRadius / 3 < Math.sqrt((roll * roll) + (pitch * pitch))) {
compassLevel.setImageResource(R.drawable.ic_error_pointer);
} else {
compassLevel.setImageResource(R.drawable.ic_level_pointer);
}
}
}
}
public void calculateAccMagOrientation() {
if(SensorManager.getRotationMatrix(rotationMatrix, null, accel, magnet)) {
SensorManager.getOrientation(rotationMatrix, accMagOrientation);
}
}
@Override
public void onSensorChanged(SensorEvent event) {
final float alpha = 0.97f;
synchronized (this) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
mGravity[0] = alpha * mGravity[0] + (1 - alpha)
* event.values[0];
mGravity[1] = alpha * mGravity[1] + (1 - alpha)
* event.values[1];
mGravity[2] = alpha * mGravity[2] + (1 - alpha)
* event.values[2];
// mGravity = event.values;
// Log.e(TAG, Float.toString(mGravity[0]));
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
// mGeomagnetic = event.values;
mGeomagnetic[0] = alpha * mGeomagnetic[0] + (1 - alpha)
* event.values[0];
mGeomagnetic[1] = alpha * mGeomagnetic[1] + (1 - alpha)
* event.values[1];
mGeomagnetic[2] = alpha * mGeomagnetic[2] + (1 - alpha)
* event.values[2];
// Log.e(TAG, Float.toString(event.values[0]));
}
boolean success = SensorManager.getRotationMatrix(mR, mI, mGravity,
mGeomagnetic);
if (success) {
float[] orientation = new float[3];
SensorManager.getOrientation(mR, orientation);
// Log.d(TAG, "azimuth (rad): " + azimuth);
mAzimuth = (float) Math.toDegrees(orientation[0]); // orientation
mAzimuth = (mAzimuth + mAzimuthFix + 360) % 360;
// Log.d(TAG, "azimuth (deg): " + azimuth);
if (mListener != null) {
mListener.onNewAzimuth(mAzimuth);
}
}
}
}
/**
* Responds to changes in the accelerometer or magnetic field sensors to
* recompute orientation. This only updates azimuth, pitch, and roll and
* raises the OrientationChanged event if both sensors have reported in
* at least once.
*
* @param sensorEvent an event from the accelerometer or magnetic field sensor
*/
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
if (enabled) {
int eventType = sensorEvent.sensor.getType();
// Save the new sensor information about acceleration or the magnetic field.
switch (eventType) {
case Sensor.TYPE_ACCELEROMETER:
// Update acceleration array.
System.arraycopy(sensorEvent.values, 0, accels, 0, DIMENSIONS);
accelsFilled = true;
// Only update the accuracy property for the accelerometer.
accuracy = sensorEvent.accuracy;
break;
case Sensor.TYPE_MAGNETIC_FIELD:
// Update magnetic field array.
System.arraycopy(sensorEvent.values, 0, mags, 0, DIMENSIONS);
magsFilled = true;
break;
default:
Log.e(LOG_TAG, "Unexpected sensor type: " + eventType);
return;
}
// If we have both acceleration and magnetic information, recompute values.
if (accelsFilled && magsFilled) {
SensorManager.getRotationMatrix(rotationMatrix, // output
inclinationMatrix, // output
accels,
mags);
SensorManager.getOrientation(rotationMatrix, values);
// Make sure values are in expected range.
azimuth = OrientationSensorUtil.normalizeAzimuth(
(float) Math.toDegrees(values[AZIMUTH]));
pitch = OrientationSensorUtil.normalizePitch(
(float) Math.toDegrees(values[PITCH]));
// Sign change for roll is for compatibility with earlier versions
// of App Inventor that got orientation sensor information differently.
roll = OrientationSensorUtil.normalizeRoll(
(float) -Math.toDegrees(values[ROLL]));
// Adjust pitch and roll for phone rotation (e.g., landscape)
int rotation = getScreenRotation();
switch(rotation) {
case Surface.ROTATION_0: // normal rotation
break;
case Surface.ROTATION_90: // phone is turned 90 degrees counter-clockwise
float temp = -pitch;
pitch = -roll;
roll = temp;
break;
case Surface.ROTATION_180: // phone is rotated 180 degrees
roll = -roll;
break;
case Surface.ROTATION_270: // phone is turned 90 degrees clockwise
temp = pitch;
pitch = roll;
roll = temp;
break;
default:
Log.e(LOG_TAG, "Illegal value for getScreenRotation(): " +
rotation);
break;
}
// Raise event.
OrientationChanged(azimuth, pitch, roll);
}
}
}
private void fuseValues() {
SensorManager.getRotationMatrix(mRotationM, null, mAccelVals, mMagVals);
mRotationUpdateDelegate.onRotationUpdate(mRotationM);
}
public void calculateAccMagOrientation() {
if (SensorManager.getRotationMatrix(rotationMatrix, null, accel, magnet)) {
SensorManager.getOrientation(rotationMatrix, accMagOrientation);
}
}
@Override
public void onSensorChanged(SensorEvent event) {
// Acquire accelerometer event data
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
mGravity = new float[3];
System.arraycopy(event.values, 0, mGravity, 0, 3);
}
// Acquire magnetometer event data
else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
mGeomagnetic = new float[3];
System.arraycopy(event.values, 0, mGeomagnetic, 0, 3);
}
// If we have readings from both sensors then
// use the readings to compute the device's orientation
// and then update the display.
if (mGravity != null && mGeomagnetic != null) {
float rotationMatrix[] = new float[9];
// Users the accelerometer and magnetometer readings
// to compute the device's rotation with respect to
// a real world coordinate system
boolean success = SensorManager.getRotationMatrix(rotationMatrix,
null, mGravity, mGeomagnetic);
if (success) {
float orientationMatrix[] = new float[3];
// Returns the device's orientation given
// the rotationMatrix
SensorManager.getOrientation(rotationMatrix, orientationMatrix);
// Get the rotation, measured in radians, around the Z-axis
// Note: This assumes the device is held flat and parallel
// to the ground
float rotationInRadians = orientationMatrix[0];
// Convert from radians to degrees
mRotationInDegress = Math.toDegrees(rotationInRadians);
// Request redraw
mCompassArrow.invalidate();
// Reset sensor event data arrays
mGravity = mGeomagnetic = null;
}
}
}