2012-07-12 12 views
0

下面你會看到我的傳感器管理員類..我有一個虛擬羅盤工作很好,但點擊我想獲得方位角值,根據谷歌文檔應該返回0 =北,90 =東,180 =南,270 =西...方位角錯誤的值

我的應用程序設置爲僅橫向模式..

有趣的是,如果

我的手機在肖像舉行我得到: 90爲北, 180爲東, -90爲南, 0爲西

,如果我拿在lanscape模式: -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現在,因爲它說現在使用的方法IM是更準確*

我還包括創建使用相同的傳感器數據與所謂的長按功能準確的指南針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(); 

    } 

} 

回答

0

問題解決了。我重新使用方位傳感器的偏航或方位角。我之前這樣做,並得到同樣的問題,但發現我的問題是,我把它作爲float,而不是一個雙..將稍後更新代碼。如果有人能向我解釋爲什麼這會有所幫助。我認爲浮動和雙打之間的唯一區別就是總分......並且正在以浮點形式投射,因爲我不需要額外的32位