0

以下に私のセンサーマネージャークラスが表示されます。仮想コンパスで問題なく動作していますが、クリックすると、Googleのドキュメントによると0 =北、90 =東、180=南を返す方位角値を取得しようとしています。 、および270=西..。

私のアプリは横向きモードのみに設定されています。

面白いのは

私の電話はPORTRAITで保持されています。北は90、東は180、南は-90、西は0です。

横向きモードで保持した場合:北の場合は-40〜-60、東の場合は約30、南の場合は-12、西の場合は-156

同じコードがマトリックスopenGlコンパスを回転させています。これは、磁力計が実際に磁北を考えているものと数値を比較する方法です。私はとても混乱しています。誰か助けてください。

私のセンサークラス:

public void start(Context context,final int displayOrientation) {
            listener = new SensorEventListener() {
            private int displayOri = displayOrientation;

            public void onAccuracyChanged(Sensor arg0, int arg1){}

            public void onSensorChanged(SensorEvent evt) {
                int type=evt.sensor.getType();

                if (type == Sensor.TYPE_MAGNETIC_FIELD) {
                    orientation[0]=(orientation[0]*1+evt.values[0])*0.5f;
                    orientation[1]=(orientation[1]*1+evt.values[1])*0.5f;
                    orientation[2]=(orientation[2]*1+evt.values[2])*0.5f;
                } else if (type == Sensor.TYPE_ACCELEROMETER) {
                    acceleration[0]=(acceleration[0]*2+evt.values[0])*0.33334f;
                    acceleration[1]=(acceleration[1]*2+evt.values[1])*0.33334f;
                    acceleration[2]=(acceleration[2]*2+evt.values[2])*0.33334f;
                }
                if ((type==Sensor.TYPE_MAGNETIC_FIELD) || (type==Sensor.TYPE_ACCELEROMETER)) {
                    float newMat[]=new float[16];

                    //Toast toast = Toast.makeText(ctx.getApplicationContext(), "accel", Toast.LENGTH_SHORT);
                    //toast.show();
                    SensorManager.getRotationMatrix(newMat, null, acceleration, orientation);
                    if(displayOri==0||displayOri==2){
                        SensorManager.remapCoordinateSystem(newMat,SensorManager.AXIS_X*-1, SensorManager.AXIS_MINUS_Y*-1,newMat);
                    }else{
                        SensorManager.remapCoordinateSystem(newMat,SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X,newMat);
                    }

                    matrix=newMat;
                    SensorManager.getOrientation (newMat, orientationValues); 
                }
            }
        };

        sensorMan = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        sensorAcce = sensorMan.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
        sensorMagn = sensorMan.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).get(0);
        //sensorOri = sensorMan.getSensorList(Sensor.TYPE_ORIENTATION).get(0);

        sensorMan.registerListener(listener, sensorAcce, SensorManager.SENSOR_DELAY_UI);
        sensorMan.registerListener(listener, sensorMagn, SensorManager.SENSOR_DELAY_UI);    
        //sensorMan.registerListener(listener, sensorOri, SensorManager.SENSOR_DELAY_UI);   
    }

    public float[] getMatrix() {
        return matrix;
    }
    public float getRoll(){
        return roll;
    }
    public float[] getACC(){
        return acceleration;
    }
    public float[] getORI(){
        return orientationValues;

    }
    public float getIncline(){
        return sensorMan.getInclination(matrix);
    }
    public void finish() {
        sensorMan.unregisterListener(listener);
    }
    public void onPause() {
        sensorMan.unregisterListener(listener);
    }
    public void onResume(){
        sensorMan.registerListener(listener, sensorAcce, SensorManager.SENSOR_DELAY_UI);
        sensorMan.registerListener(listener, sensorMagn, SensorManager.SENSOR_DELAY_UI);
        //sensorMan.registerListener(listener, sensorOri, SensorManager.SENSOR_DELAY_UI);   
    }
}

グーグルドキュメント:

* SENSOR_ORIENTATION、SENSOR_ORIENTATION_RAW:すべての値は度単位の角度です。values [0]:方位角、Z軸を中心とした回転(0 <=方位角<360)。0 =北、90 =東、180 =南、270 =西の値[1]:ピッチ、X軸を中心とした回転(-180<=ピッチ<=180)、z軸がy-に向かって移動すると正の値軸。values [2]:ロール、Y軸を中心に回転(-90 <= roll <= 90)、z軸がx軸に向かって移動すると正の値になります。このヨー、ピッチ、ロールの定義は、X軸が飛行機の長辺(尾から鼻)に沿っている航空で使用される従来の定義とは異なることに注意してください。現在使用している方法の方が正確であると書かれているため、sensor.orientationを使用していないことに注意してください*

また、同じセンサーデータを使用して正確なコンパスを作成するopenGLクラスと、センサーデータをトーストでスローするnewTAgと呼ばれる長押し機能も含まれています。

トーストは次のようになります。

   Toast.makeText(getContext(), "INLCINE:"+phoneOri.getIncline()+" azimuth:"+Math.toDegrees(tagOri[0])+" pitch:"+Math.toDegrees(tagOri[1])+" roll:"+Math.toDegrees(tagOri[2]),Toast.LENGTH_LONG).show();

public GLLayer(Context context, int orientation) {
        super(context);

        this.context = context;
        //this.square = new Square();
        this.cRing = new Circle();
        this.cNeedle = new CompassNeedle();

        this.mNorth = new MarkerNorth();
        this.mEast = new MarkerEast();
        this.mSouth = new MarkerSouth();
        this.mWest = new MarkerWest();

        this.mSWest = new MarkerSouthWest();
        this.mSEast = new MarkerSouthEast();
        this.mNWest = new MarkerNorthWest();
        this.mNEast = new MarkerNorthEast();
        this.mtag = new tagImage();
        phoneOri=new PhoneOrientation(context); // sensor manager and interpreter

        // settings for translucent glView
        this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
        this.getHolder().setFormat(PixelFormat.TRANSLUCENT);

        // set render to inline 
        this.setRenderer(this);
        phoneOri.start(context, orientation);

    }

    @Override
    public void onDrawFrame(GL10 gl) {
        gl.glEnable(GL10.GL_TEXTURE_2D);


        // clear Screen and Depth Buffer
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        // Reset the Modelview Matrix
        gl.glLoadIdentity();

        //GLU.gluLookAt(gl, eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
        GLU.gluLookAt(gl,0, 0, 0, 0, 0, 0, 0, 0, 0);
        //GLU.gluLookAt(gl, 90.0f, 1.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0, 1.0f, 0);

        float floatMat[]=phoneOri.getMatrix();

        gl.glMatrixMode(GL10.GL_MODELVIEW);


        //
        //gl.glTranslatef(0,0,-200.0f);
        //cRing.draw(gl);
        //DrawCompass Needle and Markers


        gl.glLoadMatrixf(floatMat, 0);

        for(int i=0;i<tags.size();i++){
            gl.glPushMatrix();

            //GLU.gluLookAt(gl,0, 0, 0, 0, 0, 0, 0, 0, 0);
            //float angle = phoneOri.sensorMan,getAngleChange();
            gl.glRotatef(90,2, 0,0);
            mtag.draw(gl);
            gl.glLoadMatrixf(floatMat,0);
        }

        gl.glPushMatrix();
        gl.glTranslatef(0,0,-10.0f);
        cNeedle.draw(gl);
        gl.glLoadMatrixf(floatMat,0);
        //Draw compass ring
        //gl.glPushMatrix();
        gl.glTranslatef(0,0,10.0f);
        cRing.draw(gl);


        //Draw South
        gl.glTranslatef(0.0f,-150.0f,-10.0f);
        mSouth.draw(gl); 

        //Draw West
        gl.glTranslatef(-150.0f,150.0f,0.0f);
        mWest.draw(gl);

        //DrawNorth
        gl.glTranslatef(150.0f,150.0f,0.0f);
        mNorth.draw(gl); 

        //DrawEast
        gl.glTranslatef(150.0f,-150.0f,0.0f);
        mEast.draw(gl);

        //SW
        gl.glTranslatef(-225.0f, -75.0f, 0.0f);
        mSWest.draw(gl);

        // NW
        gl.glTranslatef(0.0f,150.f,0);
        mNWest.draw(gl);

        gl.glTranslatef(150.0f, 0f, 0f);
        mNEast.draw(gl);

        gl.glTranslatef(0.0f,-150.0f,0.0f);
        mSEast.draw(gl);


        // Drawing
        //gl.glNormal3f(0,0,1);
        //gl.glTranslatef(0.0f,-150.0f,0.0f);     // move 5 units INTO the screen
        //square.draw(gl);                       // Draw the square

         gl.glPushMatrix();

    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        if(height == 0) {                    //Prevent A Divide By Zero By
        height = 1;                         //Making Height Equal One
        }
        float ratio = (float) width / height;
        gl.glViewport(0, 0, width, height);     //Reset The Current Viewport
        gl.glMatrixMode(GL10.GL_PROJECTION);    //Select The Projection Matrix
        gl.glLoadIdentity();                    //Reset The Projection Matrix
                                                //Calculate The Aspect Ratio Of The Window

        //gl.glFrustumf(-ratio, ratio, -1, 1, 1, 100);
        GLU.gluPerspective(gl, 35.0f, (float)width / (float)height, 5.0f, 200.0f);
        gl.glMatrixMode(GL10.GL_MODELVIEW);     //Select The Modelview Matrix
        gl.glLoadIdentity();                    //Reset The Modelview Matrix

        GLU.gluLookAt(gl, 0, 1.0f, 5.0f, 0, 0, 0, 0, 1.0f, 0);


    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
        // Load the texture for the square
        //square.loadGLTexture(gl, this.context);
        cRing.loadGLTexture(gl, this.context);
        cNeedle.loadGLTexture(gl, this.context);
        mNorth.loadGLTexture(gl, this.context);
        mEast.loadGLTexture(gl, this.context);
        mSouth.loadGLTexture(gl, this.context);
        mWest.loadGLTexture(gl, this.context);
        mSWest.loadGLTexture(gl, this.context);
        mNWest.loadGLTexture(gl, this.context);
        mSEast.loadGLTexture(gl, this.context);
        mNEast.loadGLTexture(gl, this.context);

        gl.glEnable(GL10.GL_TEXTURE_2D);            //Enable Texture Mapping ( NEW )
        gl.glShadeModel(GL10.GL_SMOOTH);            //Enable Smooth Shading
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);    //Black Background
        gl.glClearDepthf(1.0f);                     //Depth Buffer Setup
        gl.glEnable(GL10.GL_DEPTH_TEST);            //Enables Depth Testing
        gl.glDepthFunc(GL10.GL_LEQUAL);             //The Type Of Depth Testing To Do

        //Really Nice Perspective Calculations
        //gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_SMOOTH);

    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        // TODO Auto-generated method stub

    }
    public void newTag(){
        float tagOri[] = new float[3];
        tagOri = phoneOri.getORI();
        tags.add(phoneOri.getMatrix());
        Toast.makeText(getContext(), "INLCINE:"+phoneOri.getIncline()+" azimuth:"+Math.toDegrees(tagOri[0])+" pitch:"+Math.toDegrees(tagOri[1])+" roll:"+Math.toDegrees(tagOri[2]),Toast.LENGTH_LONG).show();

    }

}
4

1 に答える 1

0

問題は解決しました。方向センサーからのヨーまたは方位角を使用することにしました。私は以前にこれを行っていて同じ問題が発生していましたが、私の問題は、doubleではなくfloatとしてキャストしていたことであることがわかりました。後でコードを更新します。誰かが私にそれが役立つ理由を説明できれば。floatとdoubleの唯一の違いは合計ビットだと思いました。そして、余分な32ビットは必要ないと考えてfloatとしてキャストしていました。

于 2012-07-13T01:05:06.123 に答える