## Rotational Matrices via getRotationMatrix

Put your problem here if it does not fit any of the other categories.

### Rotational Matrices via getRotationMatrix

I am developing a tilt app. I was using Euler angles (roll, pitch, yaw) for the pitch and roll. When the phone is on end 90 degrees, the x and z plain are the same and the phone goes crazy, a fundamental flaw with Euler angles.

I need to get the pitch and roll degrees using Rotational Matrices via getRotationMatrix. I have been searching for my entire weekend to find any good information about how to use these to get my pitch and roll angles.

I have looked at the Google Dev docs, which really doesn't show me enough to understand how to use them.

If anyone can provide any good material or references, or even better working code that shows how it works, it would be great.
ruebarb
Freshman

Posts: 2
Joined: Mon Feb 27, 2012 1:39 am

### Re: Rotational Matrices via getRotationMatrix

I've finally found what I have been looking for. Here it is for all

<?xml version="1.0" encoding="utf-8"?>
<!-- This file is res/layout/main.xml -->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button android:id="@+id/update" android:text="Update Values"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doUpdate" />
<Button android:id="@+id/show" android:text="Show Me!"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doShow" android:layout_toRightOf="@id/update" />
<TextView android:id="@+id/preferred" android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/update" />
<TextView android:id="@+id/orientation" android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/preferred" />
</RelativeLayout>

package YOURPACKAGE;

import android.app.Activity;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;

public class YOURCLASS extends Activity implements SensorEventListener {
private static final String TAG = "VirtualJax";
private SensorManager mgr;
private Sensor accel;
private Sensor compass;
private Sensor orient;
private TextView preferred;
private TextView orientation;
private float[] accelValues = new float[3];
private float[] compassValues = new float[3];
private float[] inR = new float[9];
private float[] inclineMatrix = new float[9];
private float[] orientationValues = new float[3];
private float[] prefValues = new float[3];
private float mAzimuth;
private double mInclination;
private int counter;
private int mRotation;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
preferred = (TextView)findViewById(R.id.preferred);
orientation = (TextView)findViewById(R.id.orientation);
mgr = (SensorManager) this.getSystemService(SENSOR_SERVICE);
accel = mgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
compass = mgr.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
orient = mgr.getDefaultSensor(Sensor.TYPE_ORIENTATION);
WindowManager window = (WindowManager)
this.getSystemService(WINDOW_SERVICE);
int apiLevel = Integer.parseInt(Build.VERSION.SDK);
if(apiLevel <8) {
mRotation = window.getDefaultDisplay().getOrientation();
}
else {
mRotation = window.getDefaultDisplay().getRotation();
}
}
@Override
protected void onResume() {
mgr.registerListener(this, accel,
SensorManager.SENSOR_DELAY_GAME);
mgr.registerListener(this, compass,
SensorManager.SENSOR_DELAY_GAME);
mgr.registerListener(this, orient,
SensorManager.SENSOR_DELAY_GAME);
super.onResume();
}
@Override
protected void onPause() {
mgr.unregisterListener(this, accel);
mgr.unregisterListener(this, compass);
mgr.unregisterListener(this, orient);
super.onPause();
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// ignore
}
public void onSensorChanged(SensorEvent event) {
// Need to get both accelerometer and compass
// before we can determine our orientationValues
switch(event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
for(int i=0; i<3; i++) {
accelValues[i] = event.values[i];
}
if(compassValues[0] != 0)
break;
case Sensor.TYPE_MAGNETIC_FIELD:
for(int i=0; i<3; i++) {
compassValues[i] = event.values[i];
}
if(accelValues[2] != 0)
break;
case Sensor.TYPE_ORIENTATION:
for(int i=0; i<3; i++) {
orientationValues[i] = event.values[i];
}
break;
}

return;
if(SensorManager.getRotationMatrix(
inR, inclineMatrix, accelValues, compassValues)) {
// got a good rotation matrix
SensorManager.getOrientation(inR, prefValues);
mInclination = SensorManager.getInclination(inclineMatrix);
// Display every 10th value
if(counter++ % 10 == 0) {
doUpdate(null);
counter = 1;
}

}
}
public void doUpdate(View view) {
return;
mAzimuth = (float) Math.toDegrees(prefValues[0]);
if(mAzimuth < 0) {
mAzimuth += 360.0f;
}
String msg = String.format(
"Preferred:\nazimuth (Z): %7.3f \npitch (X): %7.3f\nroll (Y): %7.3f",
mAzimuth, Math.toDegrees(prefValues[1]),
Math.toDegrees(prefValues[2]));
preferred.setText(msg);
msg = String.format(
"Orientation Sensor:\nazimuth (Z): %7.3f\npitch (X): %7.3f\nroll (Y): %7.3f",
orientationValues[0],
orientationValues[1],
orientationValues[2]);
orientation.setText(msg);
preferred.invalidate();
orientation.invalidate();
}
public void doShow(View view) {
// yaw = degrees clockwise from North
// For yaw we can use either mAzimuth or orientationValues[0].
//
// pitch = degrees up or down. -90 is looking straight up,
// +90 is looking straight down
// except that pitch doesn't work properly
Intent intent=new Intent(Intent.ACTION_VIEW, Uri.parse(
Math.round(orientationValues[0]) + ",,0,1.0"
));
startActivity(intent);
return;
}
}
ruebarb
Freshman

Posts: 2
Joined: Mon Feb 27, 2012 1:39 am