[android-developers] Re: Getting magnetic field results as degrees

2009-12-14 Thread Jeffrey
I got it working, the phone will only need to be lying flat, so that
made it a lot easier. It seems like google should mention somewhere
that you need to use trig to get degree's from the compass... That
doesn't quite seem like general knowledge. Though I had a problem with
the activity force closing occasionally but I fixed that so that it
wouldn't try and take sensor readings until the activity had been open
for 1 second. It also adds to the suspense of what direction the drift
will be :)

On Dec 13, 12:47 am, Ethan Rublee ethan.rub...@gmail.com wrote:
 Here's my code for capturing orientation data... This is a snippet so
 has not been compiled, but should give you and idea.
 Keep in mind that you should register the sensors with something like
 this when ever you want to start listening to sensors:

 sensorMgr = (SensorManager) contex.getSystemService
 (Service.SENSOR_SERVICE);
 orientationSensor = sensorMgr.getDefaultSensor
 (Sensor.TYPE_ORIENTATION);
 magnetSensor = sensorMgr.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
 accelSensor = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

 //this class implements SensorEventListener
 sensorMgr.registerListener(this,orientationSensor,
 SensorManager.SENSOR_DELAY_FASTEST);
 sensorMgr.registerListener(this,magnetSensor,
 SensorManager.SENSOR_DELAY_FASTEST);
 orientationsupported = sensorMgr.registerListener(this, accelSensor,
 SensorManager.SENSOR_DELAY_FASTEST);

 //*The following is the static data necessary for my
 sensorlistener, these are fields of my class
  // for storing sensor data
 float[] mags = new float[3];
 float[] accels = new float[3];

 int matrix_size = 16;
 // matrices for letting SensorManager do its magic
 float[] RotationMatrix = new float[matrix_size];
 float[] InclinationMatrix = new float[matrix_size];

 // an output matrix, that will hold a rotation matrix that
 // can be used in openGl as a modelview matrix
 float[] outR = new float[matrix_size];

 // the orientation rotation array
 float[] values = new float[3];

 //***
 // here's the meat of the sensor handling, from the
 android.hardware.SensorListener interface
 public void onSensorChanged(SensorEvent event) {
   Sensor sensor = event.sensor;

   int type = sensor.getType();

   switch (type) {
   case Sensor.TYPE_MAGNETIC_FIELD:

     mags[0] = event.values[0];
     mags[1] = event.values[1];
     mags[2] = event.values[2];
     break;
   case Sensor.TYPE_ACCELEROMETER:
     accels[0] = event.values[0];
     accels[1] = event.values[1];
     accels[2] = event.values[2];
     break;
   case Sensor.TYPE_ORIENTATION:
     /**
      *these are the orientation values in degrees - one of them is the
      * magnetic heading
      */
     // values = event.values.clone();

     break;
   }

   //this is key to getting your heading, it fills out the matrices
 which are needed to calculate the
  //heading.  It is important to not that the acceleration data is
 linked to the magnetic data, in that the
  //physical tilt/yaw of the phone affects the mags vector. Atleast
 this is my understanding.
   SensorManager.getRotationMatrix(RotationMatrix, InclinationMatrix,
       accels, mags);

   // this is only necessary for my AR opengl purposes
   SensorManager.remapCoordinateSystem(RotationMatrix,
       SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X, outR);

   // This is the orientation that i need
   // values[0] = compass in radians
   // values[1] and values[2] are the rotations about the x and y axis
   SensorManager.getOrientation(outR, values);

   // I have not used this function but it may give you the magnetic
   // heading
   // directly, in radians of course
   float magHeading = SensorManager.getInclination(InclinationMatrix);

 }

 Check 
 outhttp://developer.android.com/reference/android/hardware/SensorManager...
 for definitive documentation.
 I would put a text field in your activity and output the values live
 as the sensors update.  I have found that the numbers
 do not behave quite as expected, jumping 180 degrees depending on the
 tilt of the phone.  I have not tried getInclination,
 but documentation seems to point that this would be your best bet.
 Good luck.

 On Dec 12, 9:32 pm, Jeffrey jeffisagen...@gmail.com wrote:



  Okay, so I got a little further, I'm now stuck at the point where I
  can pull values, but they are the micro-tesla measurements. How do I
  get degrees from this?

  On Dec 12, 8:13 pm, Jeffrey jeffisagen...@gmail.com wrote:

   I'm working on an application that will randomly point an arrow in a
   direction, and have that arrow maintain it's direction if the device
   is moved. All I want to do it get the magnetic field readings as
   degrees and I can do it from there. The problem I'm having is getting
   the magnetic field readings. I can't find any tutorials on it and the
   API demo on google's dev site uses deprecated code 

Re: [android-developers] Re: Getting magnetic field results as degrees

2009-12-14 Thread Mark Murphy
Jeffrey wrote:
 It seems like google should mention somewhere
 that you need to use trig to get degree's from the compass...

That's because you don't.

http://github.com/commonsguy/cw-advandroid/tree/master/Sensor/Compass/

Or, to quote from the docs:

Sensor.TYPE_ORIENTATION:

All values are angles in degrees.

values[0]: Azimuth, angle between the magnetic north direction and the Y
axis, around the Z axis (0 to 359). 0=North, 90=East, 180=South, 270=West

http://developer.android.com/reference/android/hardware/SensorEvent.html

What you are trying to do is not use the compass
(Sensor.TYPE_ORIENTATION), but rather the raw magnetic field
(Sensor.TYPE_MAGNETIC_FIELD). *That* might need trigonometry to achieve
what you need, but I suspect the vast majority of things that need the
compass can just use the degrees supplied by the compass.

-- 
Mark Murphy (a Commons Guy)
http://commonsware.com | http://twitter.com/commonsguy

Android Consulting/App Development: http://commonsware.com/consulting

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


[android-developers] Re: Getting magnetic field results as degrees

2009-12-13 Thread Peli
You need basic trigonometry:
http://en.wikipedia.org/wiki/Trigonometry

if x and y denote the magnetic field strength in microtesla, then you
get the angle through the arc tangent function:
phi = Math.atan(y/x);
or phi = Math.atan2(y,x);
phi is then the angle in radians. Note that you may want to convert
phi from radians to degree (using phideg = Math.toDegree(phi);)

Note that this only works if your phone lies flat on the desk. In
arbitrary orientation, you need more sophisticated conversion that
includes x, y, and z and the accelerometer values.

Peli
www.openintents.org
http://www.openintents.org/en/node/6

On 13 Dez., 03:32, Jeffrey jeffisagen...@gmail.com wrote:
 Okay, so I got a little further, I'm now stuck at the point where I
 can pull values, but they are the micro-tesla measurements. How do I
 get degrees from this?

 On Dec 12, 8:13 pm, Jeffrey jeffisagen...@gmail.com wrote:



  I'm working on an application that will randomly point an arrow in a
  direction, and have that arrow maintain it's direction if the device
  is moved. All I want to do it get the magnetic field readings as
  degrees and I can do it from there. The problem I'm having is getting
  the magnetic field readings. I can't find any tutorials on it and the
  API demo on google's dev site uses deprecated code (figures, google's
  sample code is never n00b friendly).

  At this point I've got this together but I don't know what I'm
  missing, all the examples I can find are using SensorListener which
  has onSensorChanged(int sensor, float[] values) but
  SensorEventListener does not support float[] values

  What am I missing here?

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


[android-developers] Re: Getting magnetic field results as degrees

2009-12-13 Thread Ethan Rublee
Here's my code for capturing orientation data... This is a snippet so
has not been compiled, but should give you and idea.
Keep in mind that you should register the sensors with something like
this when ever you want to start listening to sensors:

sensorMgr = (SensorManager) contex.getSystemService
(Service.SENSOR_SERVICE);
orientationSensor = sensorMgr.getDefaultSensor
(Sensor.TYPE_ORIENTATION);
magnetSensor = sensorMgr.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
accelSensor = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

//this class implements SensorEventListener
sensorMgr.registerListener(this,orientationSensor,
SensorManager.SENSOR_DELAY_FASTEST);
sensorMgr.registerListener(this,magnetSensor,
SensorManager.SENSOR_DELAY_FASTEST);
orientationsupported = sensorMgr.registerListener(this, accelSensor,
SensorManager.SENSOR_DELAY_FASTEST);

//*The following is the static data necessary for my
sensorlistener, these are fields of my class
 // for storing sensor data
float[] mags = new float[3];
float[] accels = new float[3];

int matrix_size = 16;
// matrices for letting SensorManager do its magic
float[] RotationMatrix = new float[matrix_size];
float[] InclinationMatrix = new float[matrix_size];

// an output matrix, that will hold a rotation matrix that
// can be used in openGl as a modelview matrix
float[] outR = new float[matrix_size];

// the orientation rotation array
float[] values = new float[3];

//***
// here's the meat of the sensor handling, from the
android.hardware.SensorListener interface
public void onSensorChanged(SensorEvent event) {
  Sensor sensor = event.sensor;

  int type = sensor.getType();

  switch (type) {
  case Sensor.TYPE_MAGNETIC_FIELD:

mags[0] = event.values[0];
mags[1] = event.values[1];
mags[2] = event.values[2];
break;
  case Sensor.TYPE_ACCELEROMETER:
accels[0] = event.values[0];
accels[1] = event.values[1];
accels[2] = event.values[2];
break;
  case Sensor.TYPE_ORIENTATION:
/**
 *these are the orientation values in degrees - one of them is the
 * magnetic heading
 */
// values = event.values.clone();

break;
  }

  //this is key to getting your heading, it fills out the matrices
which are needed to calculate the
 //heading.  It is important to not that the acceleration data is
linked to the magnetic data, in that the
 //physical tilt/yaw of the phone affects the mags vector. Atleast
this is my understanding.
  SensorManager.getRotationMatrix(RotationMatrix, InclinationMatrix,
  accels, mags);

  // this is only necessary for my AR opengl purposes
  SensorManager.remapCoordinateSystem(RotationMatrix,
  SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X, outR);

  // This is the orientation that i need
  // values[0] = compass in radians
  // values[1] and values[2] are the rotations about the x and y axis
  SensorManager.getOrientation(outR, values);

  // I have not used this function but it may give you the magnetic
  // heading
  // directly, in radians of course
  float magHeading = SensorManager.getInclination(InclinationMatrix);

}

Check out 
http://developer.android.com/reference/android/hardware/SensorManager.html
for definitive documentation.
I would put a text field in your activity and output the values live
as the sensors update.  I have found that the numbers
do not behave quite as expected, jumping 180 degrees depending on the
tilt of the phone.  I have not tried getInclination,
but documentation seems to point that this would be your best bet.
Good luck.

On Dec 12, 9:32 pm, Jeffrey jeffisagen...@gmail.com wrote:
 Okay, so I got a little further, I'm now stuck at the point where I
 can pull values, but they are the micro-tesla measurements. How do I
 get degrees from this?

 On Dec 12, 8:13 pm, Jeffrey jeffisagen...@gmail.com wrote:

  I'm working on an application that will randomly point an arrow in a
  direction, and have that arrow maintain it's direction if the device
  is moved. All I want to do it get the magnetic field readings as
  degrees and I can do it from there. The problem I'm having is getting
  the magnetic field readings. I can't find any tutorials on it and the
  API demo on google's dev site uses deprecated code (figures, google's
  sample code is never n00b friendly).

  At this point I've got this together but I don't know what I'm
  missing, all the examples I can find are using SensorListener which
  has onSensorChanged(int sensor, float[] values) but
  SensorEventListener does not support float[] values

  What am I missing here?



-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at

[android-developers] Re: Getting magnetic field results as degrees

2009-12-12 Thread Jeffrey
Okay, so I got a little further, I'm now stuck at the point where I
can pull values, but they are the micro-tesla measurements. How do I
get degrees from this?

On Dec 12, 8:13 pm, Jeffrey jeffisagen...@gmail.com wrote:
 I'm working on an application that will randomly point an arrow in a
 direction, and have that arrow maintain it's direction if the device
 is moved. All I want to do it get the magnetic field readings as
 degrees and I can do it from there. The problem I'm having is getting
 the magnetic field readings. I can't find any tutorials on it and the
 API demo on google's dev site uses deprecated code (figures, google's
 sample code is never n00b friendly).

 At this point I've got this together but I don't know what I'm
 missing, all the examples I can find are using SensorListener which
 has onSensorChanged(int sensor, float[] values) but
 SensorEventListener does not support float[] values

 What am I missing here?

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en