Hi,

I wanna thank you very much for your explanation. The official
documentation was very difficult to understand. And the example in the
api sample (the compass) does use a depreciated methods  (with
sensorlistener).

I don't understand what does remapCoordinateSystem and his parameters,
could you help?

Thank you.

On 16 juin, 06:28, "repDetect()" <n6mba50...@gmail.com> wrote:
> Hi,
> While trying to retrieve orientation data I found some pretty straight
> forward code making use of SensorEventListener for
> Sensor.TYPE_ORIENTATION and it works fine, but the
> Sensor.TYPE_ORIENTATION constant has been deprecated recently - I
> believe it was on 8 (API level) - which I understand to mean that
> while I can still use it, I shouldn't.
> The documentation [1] only says "use SensorManager.getOrientation()
> instead." [2] but as a newbie, I had difficulties following that
> "detailed" instruction.
>
> So the question is:
> How to properly get device orientation data?
>
> In an attempt to make this discussion constructive, here is what I
> managed to figure out, hopefully it will attract corrections relevant
> to my limitations and not just general pointers to material I already
> read (and misunderstood) and perhaps also benefit other newbies
> struggling with this task.
> So please fix any misconceptions or errors you find below.
>
> The most important thing to realize is that
> SensorManager.getOrientation() doesn't get the orientation from the
> sensors (as with SensorEvent for Sensor.TYPE_ORIENTATION), it merely
> "Computes the device's orientation based on the rotation matrix" which
> you must provide as the first parameter.
> In a similar fashion SensorManager.getRotationMatrix() doesn't read
> sensors data to produce the rotation matrix, it depends on you to
> provide the data through the third and forth arguments (gravity,
> geomagnetic), also note that the values of these arguments must be
> within expected limits or the method will fail. This holds in
> particular for the case where these are initialized to zeros, as this
> will imply free fall for gravity and something even more disturbing
> for geomagnetic.
> Don't take my word on it look it up for yourself in the source [3],
> for the Java end at list.
>
> Once that was digested it appears the only way to get sensor data is
> through registering a sensor event listener (I thought it would be
> really nice if I could query the sensors's readings at will and that
> what I naively assumed was done by the get methods in SensorManager,
> could anyone comment why this is not made available?), then that data
> may be used to calculate the orientation as outlined below:
>
> 1) Retrieve sensor data from accelerometer and magnetic field sensor
> as required by getRotationMatrix():
> This actually involves a number of steps in the Activity class:
> 1.1) Obtain a sensor manager.
> NOTE: Context.getSystemService needs a Context, typically called
> within an Activity's context.
>                 mSensMan = (SensorManager) getSystemService(SENSOR_SERVICE);
>
> 1.2) Register a sensor event listener for each of the above sensor
> types.
>                 mSensMan.registerListener(this,
> mSensMan.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
>                                 SensorManager.SENSOR_DELAY_UI);
>                 mSensMan.registerListener(this,
> mSensMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
>                                 SensorManager.SENSOR_DELAY_UI);
>
> 1.3) In the listener's onSensorChanged method copy the data from the
> SensorEvent.values.
> NOTE: The data must be copied off the event.values as the system is
> reusing that array in all SensorEvents, simply assigning won't work.
> public void onSensorChanged(SensorEvent event) {
>         switch (event.sensor.getType()) {
>                 case Sensor.TYPE_ACCELEROMETER:
>                         System.arraycopy(event.values, 0, mGravs, 0, 3);
>                         break;
>                 case Sensor.TYPE_MAGNETIC_FIELD:
>                         System.arraycopy(event.values, 0, mGeoMags, 0, 3);
>                         break;
>                 default:
>                         return;
>         }
>
> }
>
> 2)  Pass the copied sensor data as arrays to
> SensorManager.getRotationMatrix() to receive the rotation matrix.
> SensorManager.getRotationMatrix(mRotationM, null, mGravs, mGeoMags)
>
> Optionally transform the returned rotation matrix through
> SensorManager.remapCoordinateSystem() or multiplying by a
> transformation matrix.
>
> 3) Pass the rotation matrix to SensorManager.getOrientation() to
> receive the orientation as yaw, pitch and roll expressed in radians.
> SensorManager.getOrientation(mRotationM, mOrientation);
>
> Voila.
>
> Below the relevant code is wrapped with a complete Activity to allow
> for testing and to get the whole picture, once again - corrections and
> remarks are requested - the TODO: tags would also indicate areas where
> knowledge is lacking.
>
> Please handle with care, this newbie is still a little wet and
> slippery!
>
> [1]http://developer.android.com/reference/android/hardware/Sensor.html#T...
> [2]http://developer.android.com/reference/android/hardware/SensorManager...[],%20float[]%29
> [3]http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;...
>
> <<------------------------------------------------------------------------------------------------------------------------
>
>
>
> package my.odd.demo.orientation;
>
> import android.app.Activity;
> import android.hardware.Sensor;
> import android.hardware.SensorEvent;
> import android.hardware.SensorEventListener;
> import android.hardware.SensorManager;
> import android.os.Bundle;
> import android.view.ViewGroup.LayoutParams;
> import android.widget.TextView;
>
> public class OrientationDemo extends Activity implements
> SensorEventListener {
>         TextView mOrientationData;
>         private SensorManager mSensMan;
>         private float mAzimuth;
>         private float[] mGravs = new float[3];
>         private float[] mGeoMags = new float[3];
>         private float[] mOrientation = new float[3];
>         private float[] mRotationM = new float[9];               // Use [16]
> to co-operate with android.opengl.Matrix
>         private float[] mRemapedRotationM = new float[9];
>         private boolean mFailed;
>
>     /** Called when the activity is first created. */
>     @Override
>     public void onCreate(Bundle savedInstanceState) {
>         super.onCreate(savedInstanceState);
>
> //      I'd like to actually see something so let's have a view:
>         mOrientationData = new TextView(this);
>         setContentView(mOrientationData, new
> LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
>
> //      Initiate the Sensor Manager and register this as Listener for
> the required sensor types:
> //      TODO: Find how to get a SensorManager outside an Activity, to
> implement as a utility class.
>                 mSensMan = (SensorManager) getSystemService(SENSOR_SERVICE);
>                 mSensMan.registerListener(this,
>                                 
> mSensMan.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), //
> Anonymous Sensors- no further use for them.
>                                 SensorManager.SENSOR_DELAY_UI);
>                 mSensMan.registerListener(this,
> mSensMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
>                                 SensorManager.SENSOR_DELAY_UI);
>     }
>
>         @Override
>         public void onAccuracyChanged(Sensor sensor, int accuracy) {
>                 // Do nothing
>         }
>
>         @Override
>         public void onSensorChanged(SensorEvent event) {
>                 switch (event.sensor.getType()) {
>                 case Sensor.TYPE_ACCELEROMETER:
>                         /*
>                          * NOTE: The data must be copied off the event.values
>                          * as the system is reusing that array in all 
> SensorEvents.
>                          * Simply assigning:
>                          * mGravs = event.values won't work.
>                          *
>                          * I use a member array in an attempt to reduce 
> garbage production.
>                          */
>                         System.arraycopy(event.values, 0, mGravs, 0, 3);
>                         break;
>                 case Sensor.TYPE_MAGNETIC_FIELD:
>                         // Here let's try another way:
>                         for (int i=0;i<3;i++) mGeoMags[i] = event.values[i];
>                                 break;
>                         default:
>                                 return;
>                 }
>
>                 if (SensorManager.getRotationMatrix(mRotationM, null, mGravs,
> mGeoMags)){
> //                      Rotate to the camera's line of view (Y axis along the 
> camera's
> axis)
> //                      TODO: Find how to use android.opengl.Matrix to rotate 
> to an
> arbitrary coordinate system.
>                         SensorManager.remapCoordinateSystem(mRotationM,
> SensorManager.AXIS_X,
>                                         SensorManager.AXIS_Z, 
> mRemapedRotationM);
>                         SensorManager.getOrientation(mRemapedRotationM, 
> mOrientation);
>                         onSuccess();
>                 }
>                 else onFailure();
>         }
>
>         void onSuccess(){
>                 if (mFailed) mFailed = false;
> //              Convert the azimuth to degrees in 0.5 degree resolution.
>                 mAzimuth = (float) 
> Math.round((Math.toDegrees(mOrientation[0])) *2)/
> 2;
> //              Adjust the range: 0 < range <= 360 (from: -180 < range <= 
> 180).
>                 mAzimuth = (mAzimuth+360)%360; // alternative: mAzimuth =
> mAzimuth>=0 ? mAzimuth : mAzimuth+360;
>                 mOrientationData.setText("Azimuth= " + mAzimuth);
>         }
>
>         void onFailure() {
>                 if (!mFailed) {
>                         mFailed = true;
>                         mOrientationData.setText("Failed to retrive rotation 
> Matrix");
>                 }
>         }
>
> }

-- 
You received this message because you are subscribed to the Google
Groups "Android Beginners" group.

NEW! Try asking and tagging your question on Stack Overflow at
http://stackoverflow.com/questions/tagged/android

To unsubscribe from this group, send email to
android-beginners+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-beginners?hl=en

Reply via email to