Java Android getOrientation问题-沿轴镜像值
我的方向有点问题。我在横向模式下运行我的应用程序,我有一个轴的问题。代码中有更多解释,一些图片:Java Android getOrientation问题-沿轴镜像值,java,android,orientation,Java,Android,Orientation,我的方向有点问题。我在横向模式下运行我的应用程序,我有一个轴的问题。代码中有更多解释,一些图片: valuesMagnet=newfloat[3]; VALUESACEL=新浮动[3]; valuesOrientation=新浮动[3]; 旋转矩阵=新浮点[9]; rotationMatrixTemp=新浮点[9]; .... @凌驾 传感器更改时的公共无效(传感器事件){ 开关(event.sensor.getType()){ 外壳传感器.U型加速计: 系统阵列复制(event.value
valuesMagnet=newfloat[3];
VALUESACEL=新浮动[3];
valuesOrientation=新浮动[3];
旋转矩阵=新浮点[9];
rotationMatrixTemp=新浮点[9];
....
@凌驾
传感器更改时的公共无效(传感器事件){
开关(event.sensor.getType()){
外壳传感器.U型加速计:
系统阵列复制(event.values,0,valuesAccel,0,3);
打破
外壳传感器。类型\u磁场:
System.arraycopy(event.values,0,valuesMagnet,0,3);
打破
}
if(SensorManager.getRotationMatrix(rotationMatrixTemp,null,valuesAccel,valuesMagnet)){
//SensorManager.remapc协调系统(旋转矩阵xtemp、SensorManager.AXIS_X、SensorManager.AXIS_Z、旋转矩阵);
SensorManager.getOrientation(旋转矩阵、值或方向);
对于(int i=0;i
我希望
orientation[1]
axis在将手机旋转180度时提供-1和1之间的全谱值。此外,目标设备没有陀螺仪。根据您面临的问题,我理解的是,您主要关注两个轴,根据笛卡尔坐标系,这两个轴主要是X轴和Y轴
在Ans中,我将方位1表示为X,方位2表示为Y
因此,您需要X轴在-90到90度之间旋转时的值谱
我已经分析了问题和您的代码,下面是我针对问题的解决方案
package com.example.stackoverflowquestion;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
import android.widget.Toast;
public class MainActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor accel, magnet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
accel = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnet = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
mSensorManager.unregisterListener(this);
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (accel != null) {
mSensorManager.registerListener(this, accel,
SensorManager.SENSOR_DELAY_NORMAL);
} else {
Toast.makeText(this, "Accelerometer not available",
Toast.LENGTH_LONG).show();
}
if (magnet != null) {
mSensorManager.registerListener(this, magnet,
SensorManager.SENSOR_DELAY_NORMAL);
} else {
Toast.makeText(this, "MagnetoMeter not available",
Toast.LENGTH_LONG).show();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
float[] accelMat = new float[3];
float[] magMat = new float[3];
float[] rotmat = new float[9];
float[] orientationMat = new float[3];
@Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
System.arraycopy(event.values, 0, accelMat, 0, 3);
break;
case Sensor.TYPE_MAGNETIC_FIELD:
System.arraycopy(event.values, 0, magMat, 0, 3);
break;
}
if (SensorManager.getRotationMatrix(rotmat, null, accelMat, magMat)) {
SensorManager.getOrientation(rotmat, orientationMat);
for (int i = 0; i < orientationMat.length; i++) {
// convert from redians to degrees
orientationMat[i] = (float) (orientationMat[i] / Math.PI) * 180;
}
Log.d("yaw", ":" + orientationMat[0]);
Log.d("pitch", ":" + orientationMat[1]);
Log.d("roll", ":" + orientationMat[2]);
}
}
}
package com.example.stackoverflowquestion;
导入android.hardware.Sensor;
导入android.hardware.SensorEvent;
导入android.hardware.SensorEventListener;
导入android.hardware.SensorManager;
导入android.os.Bundle;
导入android.app.Activity;
导入android.content.Context;
导入android.util.Log;
导入android.view.Menu;
导入android.widget.Toast;
公共类MainActivity扩展活动实现SensorEventListener{
私人传感器管理器;
专用加速度传感器,磁铁;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
msSensorManager=(SensorManager)getSystemService(Context.SENSOR\u服务);
accel=mSensorManager.getDefaultSensor(传感器类型\加速计);
磁铁=mSensorManager.getDefaultSensor(传感器类型\u磁场);
}
@凌驾
受保护的void onPause(){
//TODO自动生成的方法存根
super.onPause();
mSensorManager.unregisterListener(此);
}
@凌驾
受保护的void onResume(){
//TODO自动生成的方法存根
super.onResume();
如果(加速度!=null){
mSensorManager.registerListener(此,accel,
传感器管理器。传感器延迟(正常);
}否则{
Toast.makeText(此“加速计不可用”,
Toast.LENGTH_LONG).show();
}
如果(磁铁!=null){
mSensorManager.registerListener(此,磁铁,
传感器管理器。传感器延迟(正常);
}否则{
Toast.makeText(此“磁强计不可用”,
Toast.LENGTH_LONG).show();
}
}
@凌驾
公共布尔onCreateOptions菜单(菜单){
//为菜单充气;这会将项目添加到操作栏(如果存在)。
getMenuInflater().充气(R.menu.main,menu);
返回true;
}
@凌驾
已更改准确性上的公共无效信息(传感器arg0、内部arg1){
//TODO自动生成的方法存根
}
float[]accelMat=新浮点[3];
float[]magMat=新的float[3];
浮动[]rotmat=新浮动[9];
float[]方向mat=新的float[3];
@凌驾
传感器更改时的公共无效(传感器事件){
//TODO自动生成的方法存根
开关(event.sensor.getType()){
外壳传感器.U型加速计:
系统阵列复制(event.values,0,accelMat,0,3);
打破
外壳传感器。类型\u磁场:
数组复制(event.values,0,magMat,0,3);
打破
}
if(SensorManager.getRotationMatrix(rotmat、null、accelMat、magMat)){
SensorManager.getOrientation(rotmat、orientationMat);
for(int i=0;i
此代码以度为单位打印日志,如果您希望以重读方式打印日志,则需要更改简单的公式
注意:此代码也适用于没有陀螺仪的设备。我在HTC Evo 4G设备上进行了测试,得到了预期的结果。@Override
@Override
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
System.arraycopy(event.values, 0, valuesAccel, 0, 3);
break;
case Sensor.TYPE_MAGNETIC_FIELD:
System.arraycopy(event.values, 0, valuesMagnet, 0, 3);
break;
case Sensor.TYPE_GRAVITY:
System.arraycopy(event.values, 0, valuesGravity, 0, 3);
break;
default:
break;
}
if (SensorManager.getRotationMatrix(rotationMatrixTemp, null, valuesAccel, valuesMagnet)) {
SensorManager.getOrientation(rotationMatrixTemp, valuesOrientation);
if(valuesGravity[2] < 0) {
if (valuesOrientation[1] > 0) {
valuesOrientation[1] = (float) (Math.PI - valuesOrientation[1]);
}
else {
valuesOrientation[1] = (float) (-Math.PI - valuesOrientation[1]);
}
}
for (int i = 0; i < valuesOrientation.length; i++) {
valuesOrientation[i] /= Math.PI;
valuesOrientation[i] *= 100;
valuesOrientation[i] = (int)valuesOrientation[i];
valuesOrientation[i] /= 100;
}
updateOrientationBuffer(valuesOrientation);
quadcopter.onEvent(new Event(Event.Codes.ORIENTATION_CHANGED, calculateSmoothedOrientation()));
}
else {
Log.d("Quadcopter-SM", "Matrix rotate error");
}
}
传感器更改时的公共无效(传感器事件){
开关(event.sensor.getType()){
外壳传感器.U型加速计:
系统阵列复制(event.values,0,valuesAccel,0,3);
打破
外壳传感器。类型\u磁场:
System.arraycopy(event.values,0,v
@Override
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
System.arraycopy(event.values, 0, valuesAccel, 0, 3);
break;
case Sensor.TYPE_MAGNETIC_FIELD:
System.arraycopy(event.values, 0, valuesMagnet, 0, 3);
break;
case Sensor.TYPE_GRAVITY:
System.arraycopy(event.values, 0, valuesGravity, 0, 3);
break;
default:
break;
}
if (SensorManager.getRotationMatrix(rotationMatrixTemp, null, valuesAccel, valuesMagnet)) {
SensorManager.getOrientation(rotationMatrixTemp, valuesOrientation);
if(valuesGravity[2] < 0) {
if (valuesOrientation[1] > 0) {
valuesOrientation[1] = (float) (Math.PI - valuesOrientation[1]);
}
else {
valuesOrientation[1] = (float) (-Math.PI - valuesOrientation[1]);
}
}
for (int i = 0; i < valuesOrientation.length; i++) {
valuesOrientation[i] /= Math.PI;
valuesOrientation[i] *= 100;
valuesOrientation[i] = (int)valuesOrientation[i];
valuesOrientation[i] /= 100;
}
updateOrientationBuffer(valuesOrientation);
quadcopter.onEvent(new Event(Event.Codes.ORIENTATION_CHANGED, calculateSmoothedOrientation()));
}
else {
Log.d("Quadcopter-SM", "Matrix rotate error");
}
}
// Based on pseudo code from http://www.close-range.com/docs/Computing_Euler_angles_from_a_rotation_matrix.pdf
object EulerAngleHelper {
private const val R11 = 0
private const val R12 = 1
private const val R13 = 2
private const val R21 = 3
private const val R22 = 4
private const val R23 = 5
private const val R31 = 6
private const val R32 = 7
private const val R33 = 8
private const val AZIMUTH = 0
private const val PITCH = 1
private const val ROLL = 2
private const val PHI_Z = AZIMUTH
private const val PSI_X = PITCH
private const val THETA_Y = ROLL
fun getOrientation(r: DoubleArray, values: DoubleArray): DoubleArray {
when {
r[R31] < -0.98 -> {
values[PHI_Z] = 0.0 // Anything; can set to 0
values[THETA_Y] = Math.PI / 2
values[PSI_X] = values[PHI_Z] + atan2(r[R12], r[R13])
}
r[R31] > 0.98 -> {
values[PHI_Z] = 0.0 // Anything; can set to 0
values[THETA_Y] = -Math.PI / 2
values[PSI_X] = values[PHI_Z] + atan2(-r[R12], -r[R13])
}
else -> {
values[THETA_Y] = -asin(r[R31])
val cosTheta = cos(values[THETA_Y])
values[PSI_X] = atan2(r[R32] / cosTheta, r[R33] / cosTheta)
values[PHI_Z] = atan2(r[R21] / cosTheta, r[R11] / cosTheta)
}
}
return values
}
}