以下に私のセンサーマネージャークラスが表示されます。仮想コンパスで問題なく動作していますが、クリックすると、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();
}
}