[android-developers] Re: Getting magnetic field results as degrees
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
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
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
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
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